public List <Intersection> Intersect(LineEdge target, LineEdge tool) { var res = new List <Intersection>(); // intersect corresponding lines. 1 or zero intersections var target_data = target.Data; var tool_data = tool.Data; Vector2R target_p0 = new Vector2R(target_data.p0); Vector2R target_p1 = new Vector2R(target_data.p1); Vector2R tool_p0 = new Vector2R(tool_data.p0); Vector2R tool_p1 = new Vector2R(tool_data.p1); Vector2R dir1 = target_p1 - target_p0; Vector2R dir2 = tool_p1 - tool_p0; if (dir1.SqrMagnitude == Rational.FromLong(0) || dir2.SqrMagnitude == Rational.FromLong(0)) // one vector is degenerate { return(res); } if (Vector2R.Cross(dir1, dir2) == new Rational(0)) // parallel or collinear { return(res); } Rational target_t = Vector2R.Cross(tool_p0 - target_p0, dir2 / Vector2R.Cross(dir1, dir2)); Rational tool_t = Vector2R.Cross(target_p0 - tool_p0, dir1 / Vector2R.Cross(dir2, dir1)); if (target_t >= Rational.FromLong(0) && target_t <= Rational.FromLong(1) && tool_t >= Rational.FromLong(0) && tool_t <= Rational.FromLong(1)) { if (!target.Sense) { target_t = Rational.FromLong(1) - target_t; } if (!tool.Sense) { tool_t = Rational.FromLong(1) - tool_t; } Intersection i = new Intersection { face_edge_param = target_t, cut_param = tool_t, tool_edge_enters = Vector2R.TestLeftHemiplane(dir2, dir1) == (target.Sense == tool.Sense) }; res.Add(i); } return(res); }