81 lines
1.5 KiB
Go
81 lines
1.5 KiB
Go
package mx
|
|
|
|
type Liner interface {
|
|
PointContainer
|
|
GetLineExpr() LineExpr
|
|
}
|
|
type Liners []Liner
|
|
|
|
// The type represents the cross of 2 Liners.
|
|
type LinersCrossing struct {
|
|
Pair [2]LineExpr
|
|
Point Vector
|
|
}
|
|
|
|
// Checks all possible combinations
|
|
// of Liners to cross and returns
|
|
// the crossings if are present.
|
|
func GetLinersCrossings(
|
|
what, with Liners,
|
|
) []LinersCrossing {
|
|
ret := make([]LinersCrossing, 0, len(with))
|
|
for i := range what {
|
|
for j := range with {
|
|
cross, doCross := DoLinersCross(
|
|
what[i],
|
|
with[j],
|
|
)
|
|
if doCross {
|
|
ret = append(ret, cross)
|
|
}
|
|
}
|
|
}
|
|
|
|
return ret
|
|
}
|
|
|
|
// Check if two LinerPointContainers do cross and return the
|
|
// crossing point.
|
|
func DoLinersCross(
|
|
lp1, lp2 Liner,
|
|
) (LinersCrossing, bool) {
|
|
l1 := lp1.GetLineExpr()
|
|
l2 := lp2.GetLineExpr()
|
|
|
|
crossPt, doCross := l1.Crosses(l2)
|
|
if !lp1.ContainsPoint(crossPt) ||
|
|
!lp2.ContainsPoint(crossPt) {
|
|
return LinersCrossing{}, false
|
|
}
|
|
|
|
return LinersCrossing{
|
|
Pair: [2]LineExpr{l1, l2},
|
|
Point: crossPt,
|
|
}, doCross
|
|
}
|
|
|
|
// Check whether the liner is parallel to the other liner.
|
|
func AreLinersParallel(
|
|
first, second Liner,
|
|
) bool {
|
|
l1 := first.GetLineExpr()
|
|
l2 := second.GetLineExpr()
|
|
|
|
return l1.Vertical && l2.Vertical ||
|
|
l1.K == l2.K
|
|
}
|
|
|
|
// Returns angle between liners in radians.
|
|
// The value fits the -Pi < Value < Pi condition.
|
|
func GetAngleBetweenLiners(
|
|
first, second Liner,
|
|
) Float {
|
|
l1 := first.GetLineExpr()
|
|
l2 := second.GetLineExpr()
|
|
|
|
if l1.K == l2.K {
|
|
return 0
|
|
}
|
|
|
|
return Atan(l1.K/l2.K)
|
|
}
|