/// <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> /// /// </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; }
public override void Draw(GraphicsWrapper g, PointF? mousePosition, RectangleF clippingRectangle, RectangleF drawingSpace) { if (Visible == false) { return; } if (_controlPoints.Count < 1) { return; } PointF point1 = _controlPoints[0]; PointF point2; if (mousePosition.HasValue) { point2 = mousePosition.Value; } else { point2 = point1; } if (_controlPoints.Count == 2) { point2 = _controlPoints[1]; } // Clipping opitmization. RectangleF rectangle = new RectangleF( Math.Min(point1.X, point2.X), Math.Min(point1.Y, point2.Y), Math.Abs(point2.X - point1.X), Math.Abs(point2.Y - point1.Y)); if (rectangle.IntersectsWith(clippingRectangle) == false) { return; } SimpleLine line = new SimpleLine(point1, point2); PointF vec = new PointF(line.XDelta, line.YDelta); vec = g.DrawingSpaceToActualSpace(vec, false); vec = new PointF(vec.Y, vec.X); // Rotate PointF vec1 = SimpleLine.RotatePoint(vec, -(float)Math.PI/2 + 0.3f); PointF vec2 = SimpleLine.RotatePoint(vec, -(float)Math.PI/2 -0.3f); // Scale vec1 = new PointF(vec1.X * 0.35f, vec1.Y * 0.35f); vec2 = new PointF(vec2.X * 0.35f, vec2.Y * 0.35f); vec1 = g.ActualSpaceToDrawingSpace(vec1, false); vec2 = g.ActualSpaceToDrawingSpace(vec2, false); g.DrawLine(_pen, point1, point2); g.FillPolygon(_brush, new PointF[] { point2, new PointF(point2.X + vec1.X, point2.Y + vec1.Y), new PointF(point2.X + vec2.X, point2.Y + vec2.Y) }); if (Selected) { DrawControlPoints(g); } }
/// <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 baseMethod 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; }