private void AddSmoothedCorner(Site a, Site b, Site c, Curve curve) { double k = 0.5; CubicBezierSegment seg; do { seg = Curve.CreateBezierSeg(k, k, a, b, c); //if (Routing.db) // LayoutAlgorithmSettings .Show(seg, CreatePolyTest()); b.PreviousBezierSegmentFitCoefficient = k; k /= 2; } while (BezierSegIntersectsBoundary(seg)); k *= 2; //that was the last k if (k < 0.5) //one time try a smoother seg { k = 0.5 * (k + k * 2); CubicBezierSegment nseg = Curve.CreateBezierSeg(k, k, a, b, c); if (!BezierSegIntersectsBoundary(nseg)) { b.PreviousBezierSegmentFitCoefficient = b.NextBezierSegmentFitCoefficient = k; seg = nseg; } } if (curve.Segments.Count > 0 && !ApproximateComparer.Close(curve.End, seg.Start)) { curve.AddSegment(new LineSegment(curve.End, seg.Start)); } curve.AddSegment(seg); }
public CubicBezierEquation(Point startPoint, CubicBezierSegment segment) { _startPoint = startPoint; _controlPoint1 = segment.ControlPoint1; _controlPoint2 = segment.ControlPoint2; _endPoint = segment.EndPoint; }
public PathStatistics(PathData data) { _data = data; int i = 1; _totalLength = 0; ISegment newSegment; while (i < _data.Points.Length) { switch (_data.Types[i]) { case 1: newSegment = new LineSegment(_data.Points[i - 1], _data.Points[i]); i++; break; case 3: newSegment = new CubicBezierSegment(_data.Points[i - 1], _data.Points[i], _data.Points[i + 1], _data.Points[i + 2]); i += 3; break; default: throw new NotSupportedException(); } newSegment.StartOffset = _totalLength; _segments.Add(newSegment); _totalLength += newSegment.Length; } }
private void UpdateCurve() { Ray sourceRay = new Ray(_uiLaserInteractor.transform.position, _uiLaserInteractor.transform.forward); Ray hitRay = new Ray(_uiLaserInteractor.EventData.PointerCurrentWorldPosition(), Vector3.forward); hitRay.direction = (sourceRay.origin - hitRay.origin).normalized; float startEndDistance = Vector3.Distance( sourceRay.origin, hitRay.origin); float handleDistance = startEndDistance / 4f; CubicBezierSegment bezierSegment = new CubicBezierSegment( sourceRay.origin, sourceRay.GetPoint(handleDistance), hitRay.GetPoint(handleDistance), hitRay.origin); float step = 1f / BezierSegmentCount; float t = 0; for (int i = 0; i < BezierSegmentCount; ++i) { _lineRenderer.SetPosition(i, bezierSegment.Point(t)); t += step; } }
public PathStatistics(PathData data) { _data = data; int i = 1; _totalLength = 0; ISegment newSegment; while (i < _data.Points.Length) { switch (_data.Types[i]) { case 1: newSegment = new LineSegment(_data.Points[i - 1], _data.Points[i]); i++; break; case 3: newSegment = new CubicBezierSegment(_data.Points[i - 1], _data.Points[i], _data.Points[i + 1], _data.Points[i + 2]); i+= 3; break; default: throw new NotSupportedException(); } newSegment.StartOffset = _totalLength; _segments.Add(newSegment); _totalLength += newSegment.Length; } }
private static void AddSegmentToPath(ICurve seg, ref System.Drawing.Drawing2D.GraphicsPath p) { const float radiansToDegrees = (float)(180.0 / Math.PI); LineSegment line = seg as LineSegment; if (line != null) { p.AddLine(PointF(line.Start), PointF(line.End)); } else { CubicBezierSegment cb = seg as CubicBezierSegment; if (cb != null) { p.AddBezier(PointF(cb.B(0)), PointF(cb.B(1)), PointF(cb.B(2)), PointF(cb.B(3))); } else { Ellipse ellipse = seg as Ellipse; if (ellipse != null) { p.AddArc((float)(ellipse.Center.X - ellipse.AxisA.Length), (float)(ellipse.Center.Y - ellipse.AxisB.Length), (float)(2 * ellipse.AxisA.Length), (float)(2 * ellipse.AxisB.Length), (float)(ellipse.ParStart * radiansToDegrees), (float)((ellipse.ParEnd - ellipse.ParStart) * radiansToDegrees)); } } } }
private string DotGeomString(Core.Layout.Edge geometryEdge) { var edgeGeom = geometryEdge.EdgeGeometry; if (edgeGeom == null) { return(""); } CubicBezierSegment b = edgeGeom.Curve as CubicBezierSegment; if (b == null) { throw new NotImplementedException(); } string ret = ""; if (edgeGeom.SourceArrowhead != null) { ret += string.Format("s,{0},{1} ", edgeGeom.SourceArrowhead.TipPosition.X, edgeGeom.SourceArrowhead.TipPosition.Y); } if (edgeGeom.TargetArrowhead != null) { ret += string.Format("e,{0},{1} ", edgeGeom.TargetArrowhead.TipPosition.X, edgeGeom.TargetArrowhead.TipPosition.Y); } for (int i = 0; i < 4; i++) { ret += string.Format("{0},{1} ", b.B(i).X, b.B(i).Y); } return("pos=" + Utils.Quote(ret)); }
private static void DrawControlPoints(Graphics g, CubicBezierSegment bs) { using (Pen pen = new Pen(System.Drawing.Color.Green, (float)(1 / 1000.0))) { // pen.DashStyle = DashStyle.DashDot; g.DrawLine(pen, PointF(bs.B(0)), PointF(bs.B(1))); g.DrawLine(pen, PointF(bs.B(1)), PointF(bs.B(2))); g.DrawLine(pen, PointF(bs.B(2)), PointF(bs.B(3))); } }
static PathGeometry CreateControlPointPolygon(Tuple <double, double> t, CubicBezierSegment cubic) { throw new NotImplementedException(); /* * var gp = new GraphicsPath(); * gp.AddLines(new[] { PP(cubic.B(0)), PP(cubic.B(1)), PP(cubic.B(2)), PP(cubic.B(3)) }); * return gp; */ }
/// <summary> /// Creates a spline between two nodes big enough to draw arrowheads /// </summary> /// <param name="edge"></param> public static void CreateBigEnoughSpline(Edge edge) { ValidateArg.IsNotNull(edge, "edge"); Point a = edge.Source.Center; Point b = edge.Target.Center; Point bMinA = b - a; double l = bMinA.Length; Point perp; if (l < 0.001) { perp = new Point(1, 0); b = a + perp.Rotate(Math.PI / 2); } else { perp = bMinA.Rotate(Math.PI / 2); } double maxArrowLength = 1; if (edge.EdgeGeometry.SourceArrowhead != null) { maxArrowLength += edge.EdgeGeometry.SourceArrowhead.Length; } if (edge.EdgeGeometry.TargetArrowhead != null) { maxArrowLength += edge.EdgeGeometry.TargetArrowhead.Length; } perp = perp.Normalize() * 1.5 * maxArrowLength; int i = 1; do { CubicBezierSegment seg = Curve.CreateBezierSeg(a, b, perp, i); if (TrimSplineAndCalculateArrowheads( edge.EdgeGeometry, edge.Source.BoundaryCurve, edge.Target.BoundaryCurve, seg, false, false)) { break; } i *= 2; const int stop = 10000; if (i >= stop) { CreateEdgeCurveWithNoTrimming(edge, a, b); return; } } while (true); }
/// <inheritdoc/> public override void CubicBezierTo(PointShape point1, PointShape point2, PointShape point3, bool isStroked = true, bool isSmoothJoin = true) { var segment = CubicBezierSegment.Create( point1, point2, point3, isStroked, isSmoothJoin); _currentFigure.Segments = _currentFigure.Segments.Add(segment); }
bool FitLonger(OrientedHubSegment longerOrientedSeg, Point del0, Point del1, Point midPointOfShorter, double minDelLength, double maxDel, Point center, double radius) { CubicBezierSegment seg = (CubicBezierSegment)longerOrientedSeg.Segment; Point start = seg.Start; Point end = seg.End; // LayoutAlgorithmSettings.ShowDebugCurves(new DebugCurve("green", shorterDebugOnly), new DebugCurve("red", seg)); int steps = 0; const int maxSteps = 10; Point lowP1 = (1 - SqueezeBound) * seg.Start + SqueezeBound * seg.B(1); Point lowP2 = (1 - SqueezeBound) * seg.End + SqueezeBound * seg.B(2); Point highP1 = 2 * seg.B(1) - seg.Start; //originally the tangents were 0.25 of the length of seg[1]-seg[0] - so were are safe to lengthen two times Point highP2 = 2 * seg.B(2) - seg.End; PullControlPointToTheCircle(seg.Start, ref highP1, center, radius); int r = NicelyAligned(seg, del0, del1, midPointOfShorter, minDelLength, maxDel); do { if (r == -1) { //pull the control points lower Point p1 = (seg.B(1) + lowP1) / 2; Point p2 = (seg.B(2) + lowP2) / 2; highP1 = seg.B(1); highP2 = seg.B(2); seg = new CubicBezierSegment(start, p1, p2, end); } else { Debug.Assert(r == 1); //pull the control points higher Point p1 = (seg.B(1) + highP1) / 2; Point p2 = (seg.B(2) + highP2) / 2; lowP1 = seg.B(1); lowP2 = seg.B(2); seg = new CubicBezierSegment(start, p1, p2, end); } if ((r = NicelyAligned(seg, del0, del1, midPointOfShorter, minDelLength, maxDel)) == 0) { longerOrientedSeg.Other.Segment = longerOrientedSeg.Segment = seg; return(true); } if (steps++ > maxSteps) { return(false); //cannot fix it } } while (true); }
internal static GraphicsPath CreateGraphicsPath(ICurve iCurve) { GraphicsPath graphicsPath = new GraphicsPath(); if (iCurve == null) { return(null); } Curve c = iCurve as Curve; if (c != null) { foreach (ICurve seg in c.Segments) { CubicBezierSegment cubic = seg as CubicBezierSegment; if (cubic != null) { graphicsPath.AddBezier(PointF(cubic.B(0)), PointF(cubic.B(1)), PointF(cubic.B(2)), PointF(cubic.B(3))); } else { LineSegment ls = seg as LineSegment; if (ls != null) { graphicsPath.AddLine(PointF(ls.Start), PointF(ls.End)); } else { Ellipse el = seg as Ellipse; if (el != null) { graphicsPath.AddArc((float)(el.Center.X - el.AxisA.X), (float)(el.Center.Y - el.AxisB.Y), (float)(el.AxisA.X * 2), Abs((float)el.AxisB.Y * 2), EllipseStartAngle(el), EllipseSweepAngle(el)); } } } } } else { var ls = iCurve as LineSegment; if (ls != null) { graphicsPath.AddLine(PointF(ls.Start), PointF(ls.End)); } } return(graphicsPath); }
private void ButtonsHeld(XRInteractionEventReceiver receiver) { if (_attachable.CanAttachTo.Count > 0 && _attachable.CanAttachTo.Count > 0 && _attachable.CanAttachTo[0].enabled) { if (!_lineRenderers[0].enabled) { LineVisibility(true); } Transform targetTransform = _attachable.CanAttachTo[0].VisualizerTarget.transform; Ray sourceRay = new Ray(_sweepMesh.transform.position, _sweepMesh.transform.forward); Ray targetRay = new Ray(targetTransform.position, targetTransform.forward); float distance = Vector3.Distance(transform.position, targetTransform.position); float handleDistance = distance / 3f; CubicBezierSegment segment = new CubicBezierSegment( sourceRay.origin, sourceRay.GetPoint(handleDistance), targetRay.GetPoint(-handleDistance), targetRay.origin); Vector3 initialSweepPosition = _sweepMesh.transform.localPosition; Quaternion initialLocalSweepRotation = _sweepMesh.transform.localRotation; Quaternion initialSweepRotation = _sweepMesh.transform.rotation; for (int i = 0; i < _lineRenderers.Length; ++i) { int positionIndex = 0; for (int step = 0; step < _stepLength; ++step) { float stepNormalized = (float)step / (float)_stepLength; _sweepMesh.transform.position = segment.Point(stepNormalized); _sweepMesh.transform.rotation = Quaternion.Slerp(initialSweepRotation, targetTransform.rotation, stepNormalized); _lineVertices[i][positionIndex] = _sweepMesh.transform.TransformPoint(_sweepVertices[i]); positionIndex++; _lineRenderers[i].SetPositions(_lineVertices[i]); Vector2 newOffset = _lineRenderers[i].material.mainTextureOffset; newOffset.x -= Time.deltaTime * _lineScrollMultiplier; _lineRenderers[i].material.mainTextureOffset = newOffset; } } _sweepMesh.transform.localPosition = initialSweepPosition; _sweepMesh.transform.localRotation = initialLocalSweepRotation; } }
static PathGeometry CreatePathOnCurvaturePoint(Tuple <double, double> t, CubicBezierSegment cubic) { throw new NotImplementedException(); /* * var gp = new GraphicsPath(); * Point center = cubic[t.First]; * int radius = 10; * gp.AddEllipse((float)(center.X - radius), (float)(center.Y - radius), * (2 * radius), (2 * radius)); * * return gp; //*/ }
public void ToString_Should_Return_Path_Markup() { var target = new CubicBezierSegment() { Point1 = new PointShape(), Point2 = new PointShape(), Point3 = new PointShape() }; var actual = target.ToString(); Assert.Equal("C0,0 0,0 0,0", actual); }
private bool BezierSegIntersectsBoundary(CubicBezierSegment seg) { double side = Point.SignedDoubledTriangleArea(seg.B(0), seg.B(1), seg.B(2)); if (side > 0) { return(BezierSegIntersectsTree(seg, thinLeftHierarchy) || BezierSegIntersectsTree(seg, leftHierarchy)); } else { return(BezierSegIntersectsTree(seg, thinRightHierarchy) || BezierSegIntersectsTree(seg, rightHierarchy)); } }
private static void AddSegToPath(ICurve seg, ref GraphicsPath p) { LineSegment line = seg as LineSegment; if (line != null) { p.AddLine(PointF(line.Start), PointF(line.End)); } else { CubicBezierSegment cb = seg as CubicBezierSegment; p.AddBezier(PointF(cb.B(0)), PointF(cb.B(1)), PointF(cb.B(2)), PointF(cb.B(3))); } }
public static Point SplitByNextIntersection(Point startPoint, CubicBezierSegment segment, out SegmentBase segment1, out SegmentBase segment2) { return(SplitByNextIntersection(startPoint, segment, out segment1, out segment2, new CubicBezierEquation(startPoint, segment), (t, p) => { var a = Mid(startPoint, segment.ControlPoint1, t); var b = Mid(segment.ControlPoint1, segment.ControlPoint2, t); return new CubicBezierSegment(a, Mid(a, b, t), p); }, t => { var b = Mid(segment.ControlPoint1, segment.ControlPoint2, t); var c = Mid(segment.ControlPoint2, segment.EndPoint, t); return new CubicBezierSegment(Mid(b, c, t), c, segment.EndPoint); })); }
public void GetPoints_Should_Return_All_Segment_Points() { var segment = new CubicBezierSegment() { Point1 = new PointShape(), Point2 = new PointShape(), Point3 = new PointShape() }; var target = segment.GetPoints(); Assert.Equal(3, target.Count()); Assert.Contains(segment.Point1, target); Assert.Contains(segment.Point2, target); Assert.Contains(segment.Point3, target); }
/// <summary> /// Creates a curve by using the underlying polyline /// </summary> /// <returns></returns> public Curve CreateCurve() { Curve curve = new Curve(); Site a = HeadSite; //the corner start Site b; //the corner origin Site c; //the corner other end while (Curve.FindCorner(a, out b, out c)) { CubicBezierSegment bezierSeg = CreateBezierSegOnSite(b); if (curve.Segments.Count == 0) { if (!ApproximateComparer.Close(a.Point, bezierSeg.Start)) { Curve.AddLineSegment(curve, a.Point, bezierSeg.Start); } } else if (!ApproximateComparer.Close(curve.End, bezierSeg.Start)) { Curve.ContinueWithLineSegment(curve, bezierSeg.Start); } curve.AddSegment(bezierSeg); a = b; } System.Diagnostics.Debug.Assert(a.Next.Next == null); if (curve.Segments.Count == 0) { if (!ApproximateComparer.Close(a.Point, a.Next.Point)) { Curve.AddLineSegment(curve, a.Point, a.Next.Point); } else { double w = 5; curve.Segments.Add(new CubicBezierSegment(a.Point, a.Point + new Point(w, w), a.Point + new Point(-w, w), b.Point)); } } else if (!ApproximateComparer.Close(curve.End, a.Next.Point)) { Curve.ContinueWithLineSegment(curve, a.Next.Point); } return(curve); }
private void DrawCurve(ICurve curve) { if (curve == null) { return; } Curve c = curve as Curve; if (c != null) { foreach (ICurve segment in c.Segments) { LineSegment ls = segment as LineSegment; if (ls != null) { DrawLineSegment(ls); continue; } CubicBezierSegment cubic = segment as CubicBezierSegment; if (cubic != null) { DrawBezier(cubic); continue; } DrawGenericCurve(curve); } } else { var ls = curve as LineSegment; if (ls != null) { DrawLineSegment(ls); } else { DrawGenericCurve(curve); } } }
public static void Draw(this ICurve curve) { if (curve == null) { return; } Curve c = curve as Curve; if (c != null) { foreach (ICurve segment in c.Segments) { LineSegment ls = segment as LineSegment; if (ls != null) { ls.Draw(); continue; } CubicBezierSegment cubic = segment as CubicBezierSegment; if (cubic != null) { cubic.Draw(); continue; } curve.DrawGeneric(); } } else { var ls = curve as LineSegment; if (ls != null) { ls.Draw(); } else { curve.DrawGeneric(); } } }
static bool BezierSegIntersectsBoundary(CubicBezierSegment seg, ICurve curve) { foreach (IntersectionInfo x in Curve.GetAllIntersections(seg, curve, false)) { Curve c = curve as Curve; if (c != null) { if (Curve.RealCutWithClosedCurve(x, c, false)) { return(true); } } else { //curve is a line from a thin hierarchy that's forbidden to touch return(true); } } return(false); }
/// <summary> /// /// </summary> /// <param name="longerSeg"></param> /// <param name="del0"></param> /// <param name="del1"></param> /// <param name="midPointOfShorter"></param> /// <param name="minDelLength"></param> /// <param name="maxDelLen"></param> /// <returns> 1 - need to stretch, -1 - need to squeze, 0 - OK </returns> int NicelyAligned(CubicBezierSegment longerSeg, Point del0, Point del1, Point midPointOfShorter, double minDelLength, double maxDelLen) { const double eps = 0.001; Point midDel = longerSeg[0.5] - midPointOfShorter; double midDelLen = midDel.Length; if (del0 * midDel < 0 || del1 * midDel < 0) { return(1); } if (midDelLen < minDelLength - eps) { return(1); } if (midDelLen > maxDelLen + eps) { return(-1); } return(0); }
public void StrokeACubicBezierCurve() { var geometry = new PathGeometry(); PathFigure figure = new PathFigure(); //for pixel perfect, we need to add 0.5 and 0.51 figure.StartPoint = new Point(10 + 0.5, 100 + 0.5); var segment = new CubicBezierSegment( new Point(30 + 0.5, 40 + 0.5), new Point(80 + 0.5, 40 + 0.5), new Point(100 + 0.51, 100 + 0.51), true); figure.Segments.Add(segment); figure.IsClosed = false; figure.IsFilled = false; geometry.Figures.Add(figure); Pen pen = new Pen(Color.Black, 1); CheckGeometry(geometry, null, pen, 110, 110); }
internal static void CreateGraphicsPath(DEdge dedge) { DrawingEdge edge = dedge.DrawingEdge; dedge.GraphicsPath = new GraphicsPath(); Curve c = edge.Attr.EdgeCurve as Curve; if (c != null) { foreach (ICurve seg in c.Segments) { CubicBezierSegment cubic = seg as CubicBezierSegment; if (cubic != null) { dedge.GraphicsPath.AddBezier(PointF(cubic.B(0)), PointF(cubic.B(1)), PointF(cubic.B(2)), PointF(cubic.B(3))); } else { LineSegment ls = seg as LineSegment; dedge.GraphicsPath.AddLine(PointF(ls.Start), PointF(ls.End)); } } } else { LineSegment ls = edge.Attr.EdgeCurve as LineSegment; if (ls != null) { dedge.GraphicsPath.AddLine(PointF(ls.Start), PointF(ls.End)); } else { CubicBezierSegment seg = (CubicBezierSegment)edge.Attr.EdgeCurve; dedge.GraphicsPath.AddBezier(PointF(seg.B(0)), PointF(seg.B(1)), PointF(seg.B(2)), PointF(seg.B(3))); } } }
private void DrawEdge(Edge e, Pen pen, Graphics graphics) { ICurve curve = e.Curve; Curve c = curve as Curve; if (c != null) { foreach (ICurve s in c.Segments) { LineSegment l = s as LineSegment; if (l != null) { graphics.DrawLine(pen, MsaglPointToDrawingPoint(l.Start), MsaglPointToDrawingPoint(l.End)); } CubicBezierSegment cs = s as CubicBezierSegment; if (cs != null) { graphics.DrawBezier(pen, MsaglPointToDrawingPoint(cs.B(0)), MsaglPointToDrawingPoint(cs.B(1)), MsaglPointToDrawingPoint(cs.B(2)), MsaglPointToDrawingPoint(cs.B(3))); } } if (e.ArrowheadAtSource) { DrawArrow(e, pen, graphics, e.Curve.Start, e.EdgeGeometry.SourceArrowhead.TipPosition); } if (e.ArrowheadAtTarget) { DrawArrow(e, pen, graphics, e.Curve.End, e.EdgeGeometry.TargetArrowhead.TipPosition); } } else { var l = curve as LineSegment; if (l != null) { graphics.DrawLine(pen, MsaglPointToDrawingPoint(l.Start), MsaglPointToDrawingPoint(l.End)); } } }
private bool BezierSegIntersectsTree(CubicBezierSegment seg, ParallelogramNode tree) { if (tree == null) { return(false); } if (Parallelogram.Intersect(seg.ParallelogramNodeOverICurve.Parallelogram, tree.Parallelogram)) { ParallelogramBinaryTreeNode n = tree as ParallelogramBinaryTreeNode; if (n != null) { return(BezierSegIntersectsTree(seg, n.LeftSon) || BezierSegIntersectsTree(seg, n.RightSon)); } else { return(BezierSegIntersectsBoundary(seg, ((ParallelogramNodeOverICurve)tree).Seg)); } } else { return(false); } }
string CubicBezierSegmentToString(CubicBezierSegment cubic) { return "C" + PointsToString(cubic.B(1), cubic.B(2), cubic.B(3)); }
static ICurve CreateBaseSegOnSourceTargetAndOrth(ref Point a, ref Point b, ref Point abOrtog) { ICurve seg = new CubicBezierSegment(a, a * 3.0 / 4 + b / 4 + abOrtog, b * 3.0 / 4.0 + a / 4.0 + abOrtog, b); return(seg); }