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) }