public bool IsCirclePointOnArc(Point2d pnt, double tol = 0) { if (Linear) { return(MathUtil.IsBetween(new Line2d(start, end).PositionOf(pnt), -tol, 1.0 + tol)); } if (CW) { return(pnt.Location(start, end, tol) != Location.Right); } else { return(pnt.Location(start, end, tol) != Location.Left); } }
public static Circle2d[] LineLinePoint(Line2d lin1, Line2d lin2, Point2d pnt) { // Compute the 2 circles (or 1 in special cases) that tangents two lines and a point. // Solving for parameter t on the bisector vector between lines that have the same // distance to point as the radius for that t (given using radfac computed below) // Solution by Robert.P. 2013-02-14 List <Circle2d> res = null; Vector2d v1 = lin1.Direction; Vector2d v2 = lin2.Direction; Vector2d midvec; Point2d linint; double[] ts; linint = Intersect2d.LineLineAsPoint(lin1, lin2); //basepoint for midline vector if (linint == null) //special case for parallel lines { //use vector and base point on midpoint of radical line of circles midvec = v1; Line2d radlin = new Line2d(lin1.ClosestPoint(pnt), lin2.ClosestPoint(pnt)); linint = radlin.MidPoint; double r = radlin.Length * 0.5, i = pnt.X, j = pnt.Y, x0 = linint.X, y0 = linint.Y, dx = midvec.X, dy = midvec.Y; double tp2 = 1; //squared length of midlin => assume normalized double tp1 = 2 * (dy * y0 + dx * x0 - dy * j - dx * i); double tp0 = y0 * y0 - 2 * j * y0 - r * r + j * j + i * i + x0 * x0 - 2 * i * x0; ts = RealPolynomial.SolveQuadric(tp2, tp1, tp0, 0.0); if (ts == null) { return(null); } foreach (double t in ts) { Point2d center = linint + midvec * t; AddResult(ref res, center.X, center.Y, r); } } else //normal case with non-parallel lines { if (pnt.Location(lin1.Start, lin1.End) == pnt.Location(lin2.Start, lin2.End)) { v2 = -v2; //select correct bisector out of two (actually 4 but it does not matter if we solve for negative t) } midvec = v1.Bisect(v2); double radfac = Math.Sin(v1.AngleTo(v2) / 2.0); //multiplied with midvector t this gives radius of circle at that t //solve problem in space where pnt=origo Point2d org = new Point2d(linint.X - pnt.X, linint.Y - pnt.Y); double t2 = -radfac * radfac + 1; //// 1 for squared length of midlin => assume normalized double t1 = 2 * (midvec.Y * org.Y + midvec.X * org.X); double t0 = org.X * org.X + org.Y * org.Y; ts = RealPolynomial.SolveQuadric(t2, t1, t0, 0.0); if (ts == null) { return(null); } foreach (double t in ts) { Point2d center = linint + midvec * t; AddResult(ref res, center.X, center.Y, Math.Abs(t * radfac)); } } return(MakeResult(res)); }