import "dart:math"; class Line { ///y = kx + c static double normalLine(x, {k = 0, c = 0}) { return k * x + c; } ///Calculate the param K in y = kx +c static double paramK(Point p1, Point p2) { if (p1.x == p2.x) return 0; return (p2.y - p1.y) / (p2.x - p1.x); } ///Calculate the param C in y = kx +c static double paramC(Point p1, Point p2) { return p1.y - paramK(p1, p2) * p1.x; } } /// start point p1, end point p2,p2 is center of the circle,r is its radius. class LineInterCircle { /// start point p1, end point p2,p2 is center of the circle,r is its radius. /// param a: y = kx +c intersect with circle,which has the center with point2 and radius R . /// when derive to x2+ ax +b = 0 equation. the param a is here. static double paramA(Point p1, Point p2) { return (2 * Line.paramK(p1, p2) * Line.paramC(p1, p2) - 2 * Line.paramK(p1, p2) * p2.y - 2 * p2.x) / (Line.paramK(p1, p2) * Line.paramK(p1, p2) + 1); } /// start point p1, end point p2,p2 is center of the circle,r is its radius. /// param b: y = kx +c intersect with circle,which has the center with point2 and radius R . /// when derive to x2+ ax +b = 0 equation. the param b is here. static double paramB(Point p1, Point p2, double r) { return (p2.x * p2.x - r * r + (Line.paramC(p1, p2) - p2.y) * (Line.paramC(p1, p2) - p2.y)) / (Line.paramK(p1, p2) * Line.paramK(p1, p2) + 1); } ///the circle has the intersection or not static bool isIntersection(Point p1, Point p2, double r) { var delta = sqrt(paramA(p1, p2) * paramA(p1, p2) - 4 * paramB(p1, p2, r)); return delta >= 0.0; } ///the x coordinate whether or not is between two point we give. static bool _betweenPoint(x, Point p1, Point p2) { if (p1.x > p2.x) { return x > p2.x && x < p1.x; } else { return x > p1.x && x < p2.x; } } static Point _equalX(Point p1, Point p2, double r) { if (p1.y > p2.y) { return Point(p2.x, p2.y + r); } else if (p1.y < p2.y) { return Point(p2.x, p2.y - r); } else { return p2; } } static Point _equalY(Point p1, Point p2, double r) { if (p1.x > p2.x) { return Point(p2.x + r, p2.y); } else if (p1.x < p2.x) { return Point(p2.x - r, p2.y); } else { return p2; } } ///intersection point static Point intersectionPoint(Point p1, Point p2, double r) { if (p1.x == p2.x) return _equalX(p1, p2, r); if (p1.y == p2.y) return _equalY(p1, p2, r); var delta = sqrt(paramA(p1, p2) * paramA(p1, p2) - 4 * paramB(p1, p2, r)); if (delta < 0.0) { //when no intersection, i will return the center of the circ le. return p2; } var a_2 = -paramA(p1, p2) / 2.0; var x1 = a_2 + delta / 2; if (_betweenPoint(x1, p1, p2)) { var y1 = Line.paramK(p1, p2) * x1 + Line.paramC(p1, p2); return Point(x1, y1); } var x2 = a_2 - delta / 2; var y2 = Line.paramK(p1, p2) * x2 + Line.paramC(p1, p2); return Point(x2, y2); } }