114 lines
2.0 KiB
Go
114 lines
2.0 KiB
Go
package ggfx
|
|
|
|
import "image"
|
|
|
|
func (this Image[T]) Line (
|
|
stroke []T,
|
|
weight int,
|
|
min image.Point,
|
|
max image.Point,
|
|
) {
|
|
// TODO: move this process to plottingContext.Plot, it might be more
|
|
// efficient there
|
|
this.assertWidth(stroke)
|
|
for offset, part := range stroke {
|
|
this.lineInternal(part, weight, min, max, offset)
|
|
}
|
|
}
|
|
|
|
func (this Image[T]) lineInternal (
|
|
stroke T,
|
|
weight int,
|
|
min image.Point,
|
|
max image.Point,
|
|
offset int,
|
|
) {
|
|
context := linePlottingContext[T] {
|
|
plottingContext: plottingContext[T] {
|
|
data: this.Pix,
|
|
stride: this.Stride,
|
|
color: stroke,
|
|
weight: weight,
|
|
bounds: this.Bounds,
|
|
width: this.Width,
|
|
offset: offset,
|
|
},
|
|
min: min,
|
|
max: max,
|
|
}
|
|
|
|
if abs(max.Y - min.Y) < abs(max.X - min.X) {
|
|
if max.X < min.X { context.swap() }
|
|
context.lineLow()
|
|
|
|
} else {
|
|
if max.Y < min.Y { context.swap() }
|
|
context.lineHigh()
|
|
}
|
|
}
|
|
|
|
type linePlottingContext[T any] struct {
|
|
plottingContext[T]
|
|
min image.Point
|
|
max image.Point
|
|
}
|
|
|
|
func (context *linePlottingContext[T]) swap () {
|
|
temp := context.max
|
|
context.max = context.min
|
|
context.min = temp
|
|
}
|
|
|
|
func (context linePlottingContext[T]) lineLow () {
|
|
deltaX := context.max.X - context.min.X
|
|
deltaY := context.max.Y - context.min.Y
|
|
yi := 1
|
|
|
|
if deltaY < 0 {
|
|
yi = -1
|
|
deltaY *= -1
|
|
}
|
|
|
|
D := (2 * deltaY) - deltaX
|
|
point := context.min
|
|
|
|
for ; point.X < context.max.X; point.X ++ {
|
|
context.plot(point)
|
|
if D > 0 {
|
|
D += 2 * (deltaY - deltaX)
|
|
point.Y += yi
|
|
} else {
|
|
D += 2 * deltaY
|
|
}
|
|
}
|
|
}
|
|
|
|
func (context linePlottingContext[T]) lineHigh () {
|
|
deltaX := context.max.X - context.min.X
|
|
deltaY := context.max.Y - context.min.Y
|
|
xi := 1
|
|
|
|
if deltaX < 0 {
|
|
xi = -1
|
|
deltaX *= -1
|
|
}
|
|
|
|
D := (2 * deltaX) - deltaY
|
|
point := context.min
|
|
|
|
for ; point.Y < context.max.Y; point.Y ++ {
|
|
context.plot(point)
|
|
if D > 0 {
|
|
point.X += xi
|
|
D += 2 * (deltaX - deltaY)
|
|
} else {
|
|
D += 2 * deltaX
|
|
}
|
|
}
|
|
}
|
|
|
|
func abs (n int) int {
|
|
if n < 0 { n *= -1}
|
|
return n
|
|
}
|