package point import ( "math" "git.wtrh.nl/patterns/gopatterns/pkg/position" "git.wtrh.nl/patterns/gopatterns/pkg/vector" "github.com/tdewolff/canvas" ) // BetweenPoint defines a point on the line between two other points. type BetweenPoint struct { id ID p Point q Point offset float64 name string draw bool hide bool } // NewBetweenPoint returns a new BetweenPoint relative to two other points p and q. // The given offset defines where the new point is. // With offset = 0 the new point is a p, offset = 0.5 results in a point exactly in the middle. // Offset can be <0 (extending from p side) or >1 (extending from the q side). func NewBetweenPoint(p, q Point, offset float64, id ID) *BetweenPoint { return &BetweenPoint{ id: id, p: p, q: q, offset: offset, name: string(id), } } // Position calculates and returns the absolute [position.Position]. func (b *BetweenPoint) Position() position.Position { return position.Position{ Vector: b.p.Vector().Add(b.inBetween()), Rotation: b.p.Vector().AngleBetween(b.q.Vector()) - math.Pi/2, } } func (b *BetweenPoint) inBetween() vector.Vector { return b.q.Vector().Subtract(b.p.Vector()).Multiply(b.offset) } // Vector calculates and returns the absolute [vector.Vector]. func (b *BetweenPoint) Vector() vector.Vector { return b.Position().Vector } // Matrix calculates and returns the [canvas.Matrix] of a point. func (b *BetweenPoint) Matrix() canvas.Matrix { return b.p.Matrix().Translate(b.inBetween().Values()). Rotate((b.p.Vector().AngleBetween(b.q.Vector()) - math.Pi/2) * 180 / math.Pi) } // ID returns the point ID. func (b *BetweenPoint) ID() ID { return b.id } // Name returns the name of a point. func (b *BetweenPoint) Name() string { return b.name } // Draw returns if the point should be drawn. func (b *BetweenPoint) Draw() bool { return b.draw } // SetDraw indicates that the point should be drawn. func (b *BetweenPoint) SetDraw() { b.draw = true } // UnsetDraw indicates that the point should not be drawn. func (b *BetweenPoint) UnsetDraw() { b.draw = true } // Hide returns if the point must remain hidden. func (b *BetweenPoint) Hide() bool { return b.hide } // SetHide indicates that the must be hidden. func (b *BetweenPoint) SetHide() { b.hide = true }