public Point FindStraightLineIntersection(StraightLine p, StraightLine q) { Point intersectionPoint = new Point(); if (p.k == q.k || (double.IsInfinity(q.k) && double.IsInfinity(p.k))) { throw new Exception("Method: FindStraightLineIntersection . Message: Straight lines are paralell"); } if (double.IsInfinity(p.k)) { intersectionPoint.x = ConvertToZero(p.x); intersectionPoint.y = ConvertToZero(q.k * p.x + q.n); return(intersectionPoint); } if (double.IsInfinity(q.k)) { intersectionPoint.x = ConvertToZero(q.x); intersectionPoint.y = ConvertToZero(p.k * q.x + p.n); return(intersectionPoint); } intersectionPoint.x = ConvertToZero((q.n - p.n) / (p.k - q.k)); intersectionPoint.y = ConvertToZero(q.k * intersectionPoint.x + q.n); return(intersectionPoint); }
// Domain - sets of point that belong to R // distanceD - distance between points on domain public List <float> GenerateStraightLine(StraightLine p, double[] domain, List <float> color, double distanceD = 0.001) { List <float> straightLine = new List <float>(); double a = domain[0]; double b = domain[1]; double y; while (a <= b) { if (double.IsInfinity(p.k)) { y = p.k * a + p.n; straightLine.Add((float)p.x); straightLine.Add((float)a); straightLine.Add(0); straightLine.AddRange(color); a = a + distanceD; } else { y = p.k * a + p.n; straightLine.Add((float)a); straightLine.Add((float)y); straightLine.Add(0); straightLine.AddRange(color); a = a + distanceD; } } return(straightLine); }
public List <float> GenerateHiperbolicSegment(Point pointA, Point pointB, List <float> color) { // Center of inversion circle Point o = new Point(); // Radius of inversion circle double radius; if (IsColinear(pointA, pointB, new Point(0, 0)) == true) { // This is when you want to generate hiperbolic straight line through center List <Point> intersection = FindIntersectionBetweenStraightLineAndCircle(new Circle(new Point(0, 0), 1), new StraightLine(pointA, pointB)); // If points belongs to line paralel with y axis // (pointA.x - pointB.x) < 0.00001 if (pointB.x == pointA.x) { double[] domain = { Math.Min(pointA.y, pointB.y), Math.Max(pointA.y, pointB.y) }; return(GenerateStraightLine(new StraightLine(pointA, pointB), domain, color, 0.001)); } else { double[] domain = { Math.Min(pointA.x, pointB.x), Math.Max(pointA.x, pointB.x) }; return(GenerateStraightLine(new StraightLine(pointA, pointB), domain, color, 0.001)); } } else { Point pointA_inversе = CircleInversion(pointA); Point midPointM = FindMidPoint(pointA, pointB); Point midPointN = FindMidPoint(pointA_inversе, pointA); StraightLine s = new StraightLine(pointA, pointB); StraightLine d = new StraightLine(midPointM, -1 / s.k); StraightLine p = new StraightLine(pointA, pointA_inversе); StraightLine q = new StraightLine(midPointN, -1 / p.k); o = FindStraightLineIntersection(d, q); radius = FindDistance(pointA, o); List <Point> points = FindIntersectionBetweenTwoCircles(new Circle(new Point(0, 0), 1), new Circle(o, radius)); double minAngle = Math.Min(FindAngle(pointA, o, radius), FindAngle(pointB, o, radius)); double maxAngle = Math.Max(FindAngle(pointA, o, radius), FindAngle(pointB, o, radius)); // angle between 2 points must be 180 deegres or less because arch lenght must be less then half of circumstance of inversion circle if (maxAngle * minAngle < 0 && maxAngle - minAngle >= 180) { var auxiliarAngle = maxAngle; maxAngle = 360 + minAngle; minAngle = auxiliarAngle; return(GenerateCircle(o, radius, color, minAngle, maxAngle)); } return(GenerateCircle(o, radius, color, minAngle, maxAngle)); } }
// Inversion circle is Poencare circle (Fundamental circle defined as x^2 + y^2 = 1) public Point CircleInversion(Point point) { StraightLine p = new StraightLine(new Point(0, 0), point); StraightLine v = new StraightLine(point, -1 / p.k); List <Point> intersections = FindIntersectionBetweenStraightLineAndCircle(new Circle(new Point(0, 0), 1), v); StraightLine q = new StraightLine(intersections[0], new Point(0, 0)); StraightLine s = new StraightLine(intersections[0], -1 / q.k); return(FindStraightLineIntersection(p, s)); }
public List <Point> FindIntersectionBetweenStraightLineAndCircle(Circle k, StraightLine p, double sensitivity = 0.01) { // Regarding tesalation it should not happen that D <= 0 List <Point> intersectionPoints = new List <Point>(); // Case when p is parallel with y axis if (double.IsInfinity(p.k)) { double x1 = ConvertToZero(p.x); double y1 = ConvertToZero(Math.Sqrt((1 - Math.Pow(p.x, 2)))); double x2 = ConvertToZero(p.x); double y2 = ConvertToZero(-Math.Sqrt((1 - Math.Pow(p.x, 2)))); intersectionPoints.Add(new Point(x1, y1)); intersectionPoints.Add(new Point(x2, y2)); return(intersectionPoints); } Point kCenter = k.center; // ax^2 + bx + c = 0 double a = 1 + Math.Pow(p.k, 2); double b = 2 * (p.k * (p.n - kCenter.y) - kCenter.x); double c = Math.Pow(kCenter.x, 2) + Math.Pow(kCenter.y, 2) + Math.Pow(p.n, 2) - Math.Pow(k.radius, 2) - (2 * p.n * kCenter.y); double D = Math.Sqrt(Math.Pow(b, 2) - 4 * a * c); if (D == 0) { double x = ConvertToZero(-b / (2 * a)); double y = ConvertToZero(p.k * x + p.n); intersectionPoints.Add(new Point(x, y)); } else if (D > 0) { double x1 = ConvertToZero((-b + D) / (2 * a)); double y1 = ConvertToZero(p.k * x1 + p.n); double x2 = ConvertToZero((-b - D) / (2 * a)); double y2 = ConvertToZero(p.k * x2 + p.n); intersectionPoints.Add(new Point(x1, y1)); intersectionPoints.Add(new Point(x2, y2)); } // For D < 0 there are 2 solutions that belongs to C (set of complex numbers) return(intersectionPoints); }