private void CurveEnd(PointFP control1, PointFP control2, PointFP curveEnd) { drawingCurve = false; if (needDrawStartCap) { startCapP1 = new PointFP(curveBegin); startCapP2 = new PointFP(control1); //AddLineCap(control1, curveBegin, startLineCap); needDrawStartCap = false; } LineFP head = new LineFP(); LineFP tail = new LineFP(); CalcHeadTail(curveBegin, control1, head, new LineFP()); outline.AddMoveTo(head.P1); outline.AddPath(curvePath1); CalcHeadTail(control2, curveEnd, new LineFP(), tail); outline.AddLineTo(tail.P1); outline.AddLineTo(tail.P2); outline.ExtendIfNeeded(curvePath1.cmdsSize, curvePath1.pntsSize); int j = curvePath2.pntsSize - 1; for (int i = curvePath2.cmdsSize - 1; i >= 0; i--) { outline.AddLineTo(curvePath2.pnts[j--]); } outline.AddLineTo(head.P2); outline.AddClose(); curvePath1 = null; curvePath2 = null; lastCurveTail = null; lastPoint = new PointFP(control2); drawingCurve = false; }
private void CalcHeadTail(PointFP p1, PointFP p2, LineFP head, LineFP tail) { LineFP curr = new LineFP(p1, p2); head.Reset(curr.GetHeadOutline(ff_rad)); int dx = p2.X - p1.X; int dy = p2.Y - p1.Y; tail.Reset(head.P1.X + dx, head.P1.Y + dy, head.P2.X + dx, head.P2.Y + dy); }
private void AddLineJoin(PointFP lastPoint, PointFP currPoint, PointFP nextPoint) { if (lastPoint == null || currPoint == null || nextPoint == null || nextPoint.Equals(currPoint) || lastPoint.Equals(currPoint)) { return; } PointFP p1 = null, p2 = null; LineFP head, tail, lastHead, lastTail; CalcHeadTail(currPoint, nextPoint, head = new LineFP(), tail = new LineFP()); CalcHeadTail(lastPoint, currPoint, lastHead = new LineFP(), lastTail = new LineFP()); bool cross1, cross2, needLineJoin = false; PointFP pi1 = new PointFP(); PointFP pi2 = new PointFP(); cross1 = LineFP.Intersects(new LineFP(head.P1, tail.P1), new LineFP(lastHead.P1, lastTail.P1), pi1); cross2 = LineFP.Intersects(new LineFP(head.P2, tail.P2), new LineFP(lastHead.P2, lastTail.P2), pi2); if (cross1 && !cross2 && pi1.X != SingleFP.NaN) { p1 = lastTail.P2; p2 = head.P2; needLineJoin = true; } else if (!cross1 && cross2 && pi2.X != SingleFP.NaN) { p1 = lastTail.P1; p2 = head.P1; needLineJoin = true; } if (needLineJoin) { outline.AddMoveTo(cross1 ? pi1 : pi2); outline.AddLineTo(cross1 ? p2 : p1); if (lineJoin == PenFP.LINEJOIN_MITER) { outline.AddLineTo(cross1 ? pi2 : pi1); } outline.AddLineTo(cross1 ? p1 : p2); outline.AddClose(); if (lineJoin == PenFP.LINEJOIN_ROUND) { AddLineCap(cross2 ? pi2 : pi1, currPoint, PenFP.LINECAP_ROUND); } } }
public override void LineTo(PointFP point) { if (point.Equals(currPoint)) { return; } LineFP head, tail; CalcHeadTail(currPoint, point, head = new LineFP(), tail = new LineFP()); if (drawingCurve) { if (lastCurveTail != null) { curvePath1.AddLineTo(lastCurveTail.P1); curvePath2.AddLineTo(lastCurveTail.P2); } lastCurveTail = new LineFP(tail); } else { if (needDrawStartCap) { //AddLineCap(point, currPoint, startLineCap); startCapP1 = new PointFP(currPoint); startCapP2 = new PointFP(point); needDrawStartCap = false; } AddLineJoin(lastPoint, currPoint, point); outline.AddMoveTo(head.P1); outline.AddLineTo(tail.P1); outline.AddLineTo(tail.P2); outline.AddLineTo(head.P2); outline.AddLineTo(head.P1); outline.AddClose(); lastPoint = new PointFP(currPoint); } base.LineTo(point); }
public void Reset(LineFP l) { Reset(l.P1, l.P2); }
public LineFP(LineFP l) { Reset(l.P1, l.P2); }
public static bool Intersects(LineFP l1, LineFP l2, PointFP intersection) { int x = SingleFP.NaN; int y = SingleFP.NaN; if (intersection != null) { intersection.Reset(x, y); } int ax0 = l1.P1.X; int ax1 = l1.P2.X; int ay0 = l1.P1.Y; int ay1 = l1.P2.Y; int bx0 = l2.P1.X; int bx1 = l2.P2.X; int by0 = l2.P1.Y; int by1 = l2.P2.Y; int adx = (ax1 - ax0); int ady = (ay1 - ay0); int bdx = (bx1 - bx0); int bdy = (by1 - by0); if (IsZero(adx) && IsZero(bdx)) { return(IsEqual(ax0, bx0)); } else if (IsZero(ady) && IsZero(bdy)) { return(IsEqual(ay0, by0)); } else if (IsZero(adx)) { // A vertical x = ax0; y = IsZero(bdy)?by0:MathFP.Mul(MathFP.Div(bdy, bdx), x - bx0) + by0; } else if (IsZero(bdx)) { // B vertical x = bx0; y = IsZero(ady)?ay0:MathFP.Mul(MathFP.Div(ady, adx), x - ax0) + ay0; } else if (IsZero(ady)) { y = ay0; x = MathFP.Mul(MathFP.Div(bdx, bdy), y - by0) + bx0; } else if (IsZero(bdy)) { y = by0; x = MathFP.Mul(MathFP.Div(adx, ady), y - ay0) + ax0; } else { int xma = MathFP.Div(ady, adx); // slope segment A int xba = ay0 - (MathFP.Mul(ax0, xma)); // y intercept of segment A int xmb = MathFP.Div(bdy, bdx); // slope segment B int xbb = by0 - (MathFP.Mul(bx0, xmb)); // y intercept of segment B // parallel lines? if (xma == xmb) { // Need trig functions return(xba == xbb); } else { // Calculate points of intersection // At the intersection of line segment A and B, XA=XB=XINT and YA=YB=YINT x = MathFP.Div((xbb - xba), (xma - xmb)); y = (MathFP.Mul(xma, x)) + xba; } } // After the point or points of intersection are calculated, each // solution must be checked to ensure that the point of intersection lies // on line segment A and B. int minxa = MathFP.Min(ax0, ax1); int maxxa = MathFP.Max(ax0, ax1); int minya = MathFP.Min(ay0, ay1); int maxya = MathFP.Max(ay0, ay1); int minxb = MathFP.Min(bx0, bx1); int maxxb = MathFP.Max(bx0, bx1); int minyb = MathFP.Min(by0, by1); int maxyb = MathFP.Max(by0, by1); if (intersection != null) { intersection.Reset(x, y); } return((x >= minxa) && (x <= maxxa) && (y >= minya) && (y <= maxya) && (x >= minxb) && (x <= maxxb) && (y >= minyb) && (y <= maxyb)); }