/// <summary> /// /// </summary> /// <param name="otherLine"></param> /// <returns>Returns null to indicate lines are invalid or parralel.</returns> public PointF?Intersection(SimpleLine otherLine) { float det = this.A * otherLine.B - otherLine.A * this.B; if (det == 0) { return(null); } return(new PointF((otherLine.B * this.C - this.B * otherLine.C) / det, (this.A * otherLine.C - otherLine.A * this.C) / det)); }
/// <summary> /// Helper. /// </summary> protected bool TrySelectLine(Matrix transformationMatrix, bool allowLineSegmentOnly, PointF linePoint1, PointF linePoint2, PointF location, float absoluteSelectionMargin) { float lineSegmentLocation; PointF intersectionPoint; SimpleLine line = new SimpleLine(linePoint1, linePoint2); float? distance = line.DistanceToPoint(location, out lineSegmentLocation, out intersectionPoint); if (MathHelper.GetAbsoluteDistance(transformationMatrix, location, intersectionPoint) <= absoluteSelectionMargin) {// Selection. return(allowLineSegmentOnly == false || (lineSegmentLocation >= 0 && lineSegmentLocation <= 1)); } return(false); }
/// <summary> /// Helper. /// </summary> protected bool TrySelectLine(Matrix transformationMatrix, bool allowLineSegmentOnly, PointF linePoint1, PointF linePoint2, PointF location, float absoluteSelectionMargin) { float lineSegmentLocation; PointF intersectionPoint; SimpleLine line = new SimpleLine(linePoint1, linePoint2); float? distance = line.DistanceToPoint(location, out lineSegmentLocation, out intersectionPoint); if (MathHelper.GetAbsoluteDistance(transformationMatrix, location, intersectionPoint) <= absoluteSelectionMargin) {// Selection. return allowLineSegmentOnly == false || (lineSegmentLocation >=0 && lineSegmentLocation <= 1); } return false; }
/// <summary> /// Helper - extends the given line segment to the ends of the drawing space. /// </summary> protected void StretchSegmentToDrawingSpace(ref PointF point1, ref PointF point2, RectangleF drawingSpace) { //if (_controlPoints.Count < 2) //{ // return; //} SimpleLine thisLine = new SimpleLine(point1, point2); PointF?[] intersectionPoints = new PointF?[4]; // The order is important, so preserve it. intersectionPoints[0] = thisLine.Intersection(new SimpleLine(new PointF(drawingSpace.X, drawingSpace.Y), new PointF(drawingSpace.X, drawingSpace.Y + drawingSpace.Width))); intersectionPoints[1] = thisLine.Intersection(new SimpleLine(new PointF(drawingSpace.X + drawingSpace.Width, drawingSpace.Y), new PointF(drawingSpace.X + drawingSpace.Width, drawingSpace.Y + drawingSpace.Width))); intersectionPoints[2] = thisLine.Intersection(new SimpleLine(new PointF(drawingSpace.X, drawingSpace.Y), new PointF(drawingSpace.X + drawingSpace.Height, drawingSpace.Y))); intersectionPoints[3] = thisLine.Intersection(new SimpleLine(new PointF(drawingSpace.X, drawingSpace.Y + drawingSpace.Height), new PointF(drawingSpace.X + drawingSpace.Height, drawingSpace.Y + drawingSpace.Height))); if (intersectionPoints[0].HasValue == false) {// Parallel to the 0,0 / 0, 10 line. point1 = new PointF(point1.X, drawingSpace.Y); point2 = new PointF(point1.X, drawingSpace.Y + drawingSpace.Height); return; } else if (intersectionPoints[1].HasValue == false) {// Parallel to the 0,0 / 10, 0 line. point1 = new PointF(drawingSpace.X, point1.Y); point2 = new PointF(drawingSpace.X + drawingSpace.Width, point1.Y); return; } // Establish the best 2 points (shortest line = best performance). int pointIndex1 = -1, pointIndex2 = -1; for (int i = 0; i < intersectionPoints.Length; i++) { if (intersectionPoints[i].HasValue == false) { continue; } // Is the point within drawing space (Contains method does not deliver needed results). float xCalculationErrorMargin = (drawingSpace.X + drawingSpace.Width) / 100; float yCalculationErrorMargin = (drawingSpace.Y + drawingSpace.Height) / 100; if (intersectionPoints[i].Value.X < drawingSpace.X - xCalculationErrorMargin || intersectionPoints[i].Value.X > drawingSpace.X + drawingSpace.Width + xCalculationErrorMargin || intersectionPoints[i].Value.Y < drawingSpace.Y - yCalculationErrorMargin || intersectionPoints[i].Value.Y > drawingSpace.Y + drawingSpace.Height + yCalculationErrorMargin) {// Point outside. continue; } // Point approved. if (pointIndex1 < 0) { pointIndex1 = i; } else { pointIndex2 = i; break; } } if (pointIndex1 < 0 || pointIndex2 < 0) { // SystemMonitor.Error("This scenario should not happen."); pointIndex1 = 0; pointIndex2 = 1; } point1 = intersectionPoints[pointIndex1].Value; point2 = intersectionPoints[pointIndex2].Value; }
/// <summary> /// /// </summary> /// <param name="otherLine"></param> /// <returns>Returns null to indicate lines are invalid or parralel.</returns> public PointF? Intersection(SimpleLine otherLine) { float det = this.A * otherLine.B - otherLine.A * this.B; if(det == 0) { return null; } return new PointF( (otherLine.B * this.C - this.B * otherLine.C) / det, (this.A * otherLine.C - otherLine.A * this.C) / det); }
/// <summary> /// Helper - extends the given line segment to the ends of the drawing space. /// </summary> protected void StretchSegmentToDrawingSpace(ref PointF point1, ref PointF point2, RectangleF drawingSpace) { //if (_controlPoints.Count < 2) //{ // return; //} SimpleLine thisLine = new SimpleLine(point1, point2); PointF?[] intersectionPoints = new PointF?[4]; // The order is important, so preserve it. intersectionPoints[0] = thisLine.Intersection(new SimpleLine(new PointF(drawingSpace.X, drawingSpace.Y), new PointF(drawingSpace.X, drawingSpace.Y + drawingSpace.Width))); intersectionPoints[1] = thisLine.Intersection(new SimpleLine(new PointF(drawingSpace.X + drawingSpace.Width, drawingSpace.Y), new PointF(drawingSpace.X + drawingSpace.Width, drawingSpace.Y + drawingSpace.Width))); intersectionPoints[2] = thisLine.Intersection(new SimpleLine(new PointF(drawingSpace.X, drawingSpace.Y), new PointF(drawingSpace.X + drawingSpace.Height, drawingSpace.Y))); intersectionPoints[3] = thisLine.Intersection(new SimpleLine(new PointF(drawingSpace.X, drawingSpace.Y + drawingSpace.Height), new PointF(drawingSpace.X + drawingSpace.Height, drawingSpace.Y + drawingSpace.Height))); if (intersectionPoints[0].HasValue == false) {// Parallel to the 0,0 / 0, 10 line. point1 = new PointF(point1.X, drawingSpace.Y); point2 = new PointF(point1.X, drawingSpace.Y + drawingSpace.Height); return; } else if (intersectionPoints[1].HasValue == false) {// Parallel to the 0,0 / 10, 0 line. point1 = new PointF(drawingSpace.X, point1.Y); point2 = new PointF(drawingSpace.X + drawingSpace.Width, point1.Y); return; } // Establish the best 2 points (shortest line = best performance). int pointIndex1 = -1, pointIndex2 = -1; for (int i = 0; i < intersectionPoints.Length; i++) { if (intersectionPoints[i].HasValue == false) { continue; } // Is the point within drawing space (Contains method does not deliver needed results). float xCalculationErrorMargin = (drawingSpace.X + drawingSpace.Width) / 100; float yCalculationErrorMargin = (drawingSpace.Y + drawingSpace.Height) / 100; if (intersectionPoints[i].Value.X <drawingSpace.X - xCalculationErrorMargin || intersectionPoints[i].Value.X> drawingSpace.X + drawingSpace.Width + xCalculationErrorMargin || intersectionPoints[i].Value.Y <drawingSpace.Y - yCalculationErrorMargin || intersectionPoints[i].Value.Y> drawingSpace.Y + drawingSpace.Height + yCalculationErrorMargin) {// Point outside. continue; } // Point approved. if (pointIndex1 < 0) { pointIndex1 = i; } else { pointIndex2 = i; break; } } if (pointIndex1 < 0 || pointIndex2 < 0) { // SystemMonitor.Error("This scenario should not happen."); pointIndex1 = 0; pointIndex2 = 1; } point1 = intersectionPoints[pointIndex1].Value; point2 = intersectionPoints[pointIndex2].Value; }