/// <summary>Returns true if this point lies between the lines or on either line.</summary> /// <exception cref='ArgumentException'>Lines A and B must be parallel.</exception> /// <exception cref='ArgumentException'>Lines A and B cannot be coincidental. (They must be different lines.)</exception> public bool Between(WLine lineA, WLine lineB) { if (!lineA.Parallel(lineB)) { throw new ArgumentException("Lines A and B must be parallel."); } if (lineA.Coincidental(lineB)) { throw new ArgumentException("Lines A and B cannot be coincidental. (They must be different lines.)"); } //vertical lines - just check the X value if (lineA.IsVertical) { return(this.X >= Math.Min(lineA.A.X, lineB.A.X) && this.X <= Math.Max(lineA.A.X, lineB.A.X)); } //horizontal lines - just check the Y value if (lineA.IsHorizontal) { return(this.Y >= Math.Min(lineA.A.Y, lineB.A.Y) && this.Y <= Math.Max(lineA.A.Y, lineB.A.Y)); } //otherwise //find vertical line through "this" point //if it intersects one line higher than "this" (or equal to it) and the other line lower than "this" (or equal to it), then "this" is between the lines WLine verticalLine = WLine.Vertical(this); return(false); }
/// <returns>Null (no intercepts), or array of length 1 or 2.</returns> public WPoint[] GetIntersectionPoints(WLine line) { //line does not intersect if perpendicular line from circle-center to line is longer than circle-radius WPoint perpendicularToCenter = line.GetPerpendicularIntersect(Center); if (perpendicularToCenter.Distance(Center) > Radius) { return(null); } //equation of circle with radius r and center (h, k) //is (x - h)^2 + (y - k)^2 = r^2 //line: y = mx + b //circle: (x - h)^2 + (y - k)^2 = r^2 //substitute y: (x - h)^2 + (mx + b - k)^2 = r^2 //expand: x^2 - 2hx + h^2 + m^2x^2 + 2(b - k)mx + (b - k)^2 - r^2 = 0 //group: (1 + m^2)x^2 + (-2h + 2(b - k)m)x + (h^2 + (b - k)^2 - r^2) = 0 //quadratic equation: if 0 = Ax^2 + Bx + C, then x = (-B +- sqrt(B^2 - 4AC)) / 2A double A = 1 + Math.Pow(line.Slope, 2); double B = (-2 * Center.X) + (2 * (line.YIntercept - Center.Y) * line.Slope); double C = Math.Pow(Center.X, 2) + Math.Pow(line.YIntercept - Center.Y, 2) - Math.Pow(Radius, 2); double x1 = (-1 * B + Math.Sqrt(Math.Pow(B, 2) - (4 * A * C))) / (2 * A); double x2 = (-1 * B - Math.Sqrt(Math.Pow(B, 2) - (4 * A * C))) / (2 * A); double y1 = line.Slope * x1 + line.YIntercept; double y2 = line.Slope * x2 + line.YIntercept; if (line.IsVertical) { x1 = line.A.X; x2 = line.A.X; //must use circle equation instead of line equation to find y's y1 = Center.Y + Math.Sqrt(Math.Pow(Radius, 2) - Math.Pow(x1 - Center.X, 2)); y2 = Center.Y - Math.Sqrt(Math.Pow(Radius, 2) - Math.Pow(x1 - Center.X, 2)); } if (line.IsHorizontal) { y1 = line.A.Y; y2 = line.A.Y; } WPoint point1 = new WPoint(x1, y1); WPoint point2 = new WPoint(x2, y2); List <WPoint> result = new List <WPoint>() { point1 }; if (point1 != point2) { result.Add(point2); } return(result.ToArray()); }
/// <summary>Returns the intersection between the two lines.</summary> public virtual Intersection GetIntersection(WLine b) { if (this.Parallel(b)) { if (this.Coincidental(b)) { return(new Intersection(this)); } return(Intersection.NONE); } //y = mx + b AND y = m'x + b' //mx + b = m'x + b' //mx - m'x = b' - b //x(m - m') = b' - b //x = (b' - b) / (m - m') double intersectionX = (b.YIntercept - this.YIntercept) / (this.Slope - b.Slope); if (this.IsVertical) { intersectionX = this.A.X; } else if (b.IsVertical) { intersectionX = b.A.X; } //y = mx + b double intersectionY = (this.Slope * intersectionX) + this.YIntercept; if (this.IsVertical) { intersectionY = (b.Slope * intersectionX) + b.YIntercept; } else if (this.IsHorizontal) { intersectionY = this.A.Y; } if (b.IsHorizontal) { intersectionY = b.A.Y; } return(new Intersection(new WPoint(intersectionX, intersectionY))); }
/// <summary></summary> public Intersection GetIntersection(WLine line) { //if line intersects 1 corner, that's one point //if line intersects 2 corners, that's a line segment List <WPoint> overlapsCorners = new List <WPoint>(); foreach (WPoint corner in Corners) { if (corner.Overlaps(line)) { overlapsCorners.Add(corner); } } if (overlapsCorners.Count == 1) { return(new Intersection(overlapsCorners[0])); } if (overlapsCorners.Count == 2) { return(new Intersection(overlapsCorners.ToArray())); } //either line intersects two edges, or none at all List <WPoint> intersections = new List <WPoint>(); foreach (WLineSegment edge in Edges) { Intersection intersection = edge.GetIntersection(line); if (intersection == Intersection.NONE) { continue; } intersections.Add(intersection.Point); } if (intersections.Count == 2) { return(new Intersection(intersections.ToArray())); } return(Intersection.NONE); }
/// <summary>Returns intersection between a line segment and a line.</summary> public override Intersection GetIntersection(WLine b) { if (this.Parallel(b)) { if (b.Overlaps(this.A)) { return(new Intersection(this)); } return(Intersection.NONE); } WLine thisLine = this.ToWLine(); Intersection potentialIntersection = thisLine.GetIntersection(b); if (this.Overlaps(potentialIntersection.Point)) { return(potentialIntersection); } return(Intersection.NONE); }
/// <summary>Returns false. An infinite line cannot be coincidental to a finite line.</summary> public override bool Coincidental(WLine b) { return(false); }
/// <summary></summary> public Intersection(WLine line) { Type = IntersectionType.Line; this.line = line; }
/// <summary>Returns true if lines are coincidental to each other.</summary> /// <remarks>Coincidental means that every point on this line is also on the other, and vice versa. In short, the lines are equal.</remarks> public virtual bool Coincidental(WLine b) { return(Parallel(b) && Geometry.WithinMarginOfError(this.YIntercept, b.YIntercept)); }
/// <summary>Returns true if the lines are parallel to each other.</summary> /// <remarks>Parallel means they have the same slope.</remarks> public bool Parallel(WLine b) { return(Geometry.WithinMarginOfError(this.Slope, b.Slope)); }
/// <summary>Returns true if this point overlaps any part of the <pararef name='line'/>.</summary> public bool Overlaps(WLine line) { return(line.Overlaps(this)); }