//-------------------------------------------------------------------------------------------------- void _ValueHudElement_AngleEntered(ValueHudElement hudElement, double newValue) { if (newValue == 0) { return; } var startPoint = _Points[0]; if (startPoint.Distance(_CenterPoint) <= 0) { return; } var xAxis = new Ax2d(_CenterPoint, new Dir2d(new Vec2d(_CenterPoint, startPoint))); var radius = _CenterPoint.Distance(startPoint); var circ = new gp_Circ2d(xAxis, radius, _ArcDirection); var startParameter = ElCLib.Parameter(circ, startPoint); var endParameter = startParameter + newValue.ToRad(); var endPoint = ElCLib.Value(endParameter, circ); _ArcDirection = newValue < 0; if (!_CalcArcRimPoints(endPoint)) { return; } _MergePointIndices[1] = -1; _MergePointIndices[2] = -1; _PointsCompleted++; _SketchEditorTool.FinishSegmentCreation(_Points, _MergePointIndices, new SketchSegment[] { _Segment }, null); }
//-------------------------------------------------------------------------------------------------- bool _CalcArcRimPoints(Pnt2d endPoint) { // Project end point on circle var startPoint = _Points[0]; if ((startPoint.Distance(endPoint) <= 0) || (endPoint.Distance(_CenterPoint) <= 0) || (startPoint.Distance(_CenterPoint) <= 0)) { return(false); } var xAxis = new Ax2d(_CenterPoint, new Dir2d(new Vec2d(_CenterPoint, startPoint))); var radius = _CenterPoint.Distance(startPoint); var circ = new gp_Circ2d(xAxis, radius, _ArcDirection); var projEndPoint = new Geom2dAPI_ProjectPointOnCurve(endPoint, new Geom2d_Circle(circ)).NearestPoint(); // Check if we should toggle the direction var endParameter = ElCLib.Parameter(circ, projEndPoint); // If the last parameter was very small (~PI/2), and the current is very high (~PI*1.5), toggle direction if (((_LastEndParameter < 1) && (endParameter > 5)) || ((endParameter < 1) && (_LastEndParameter > 5))) { _ArcDirection = !_ArcDirection; circ = new gp_Circ2d(xAxis, radius, _ArcDirection); endParameter = ElCLib.Parameter(circ, projEndPoint); } _LastEndParameter = endParameter; // Calc rim point var rimPoint = ElCLib.Value(endParameter / 2, circ); _Points[1] = projEndPoint; _Points[2] = rimPoint; return(true); }
//-------------------------------------------------------------------------------------------------- bool _CalcArcRimPoints(Pnt2d endPoint, int mergeCandidateIndex = -1) { // Project end point on circle if ((_StartPoint.Distance(endPoint) <= 0) || (endPoint.Distance(_CenterPoint) <= 0) || (_StartPoint.Distance(_CenterPoint) <= 0)) { return(false); } var ellipse = Core.Geom.Geom2dUtils.MakeEllipse(_CenterPoint, _StartPoint, endPoint, _ArcDirection); if (ellipse == null) { return(false); } // If the last parameter was small (a*0.25), and the current is high (a*0.5), toggle direction var startParameter = ElCLib.Parameter(ellipse, _StartPoint); var endParameter = ElCLib.Parameter(ellipse, endPoint); var maxParameter = Math.Max(startParameter, endParameter); if (((startParameter > endParameter) && _LastParameterWasEnd) || ((startParameter < endParameter) && !_LastParameterWasEnd)) { _LastEndParameter = maxParameter; _LastParameterWasEnd = !_LastParameterWasEnd; } else { if (maxParameter > 0.0001) { var qa = ellipse.MajorRadius() / 4; if (((_LastEndParameter < qa) && (maxParameter > qa * 2)) || ((maxParameter < qa) && (_LastEndParameter > qa * 2))) { _ArcDirection = !_ArcDirection; ellipse = Core.Geom.Geom2dUtils.MakeEllipse(_CenterPoint, _StartPoint, endPoint, _ArcDirection); // Debug.WriteLine("Toggle direction"); } // Debug.WriteLine("New: {0} Last: {1}", maxParameter, _LastEndParameter); _LastEndParameter = maxParameter; } } // Catch points if (_ArcDirection) { _Points[1] = _StartPoint; _MergePointIndices[1] = _StartPointMergeIndex; _Points[2] = endPoint; _MergePointIndices[2] = mergeCandidateIndex; } else { _Points[1] = endPoint; _MergePointIndices[1] = mergeCandidateIndex; _Points[2] = _StartPoint; _MergePointIndices[2] = _StartPointMergeIndex; } return(true); }
//-------------------------------------------------------------------------------------------------- void _ImportArcSegment(SvgPathSegArc svgSegment, ref int startPoint) { var radiusX = svgSegment.RadiusX; var radiusY = svgSegment.RadiusY; var rotation = -svgSegment.Angle.ToRad(); var startPnt2d = svgSegment.Start; var endPnt2d = svgSegment.End; var centerPnt2d = Geom2dUtils.FindEllipseCenterFromEndpoints( startPnt2d, endPnt2d, radiusX, radiusY, rotation, (int)svgSegment.Size != (int)svgSegment.Sweep); // Do we have a circle arc? if (Math.Abs(radiusX - radiusY) < 0.0001) { var axis = Ax2d.OX.Rotated(Pnt2d.Origin, rotation).Translated(centerPnt2d.ToVec()); var circ = new gp_Circ2d(axis, radiusX, svgSegment.Sweep != SvgArcSweep.Positive); //Debug.WriteLine("StartParam: {0} - EndParam: {1}", ElCLib.Parameter(circ, startPnt2d), ElCLib.Parameter(circ, endPnt2d)); var startParam = ElCLib.Parameter(circ, startPnt2d); var endParam = ElCLib.Parameter(circ, endPnt2d); if (endParam < startParam) { endParam += 2 * Math.PI; } var rimPnt2d = ElCLib.Value(startParam + (endParam - startParam) / 2, circ); var endPoint = _AddPoint(endPnt2d); _Segments.Add(new SketchSegmentArc(startPoint, endPoint, _AddPoint(rimPnt2d))); startPoint = endPoint; } else { // No, we have a elliptical arc // Construct ellipse, convert to bezier var axis = Ax2d.OX.Rotated(Pnt2d.Origin, rotation).Translated(centerPnt2d.ToVec()); var ellipse = new gp_Elips2d(axis, radiusX, radiusY, svgSegment.Sweep != SvgArcSweep.Positive); var startParam = ElCLib.Parameter(ellipse, startPnt2d); var endParam = ElCLib.Parameter(ellipse, endPnt2d); if (double.IsNaN(startParam) || double.IsNaN(endParam)) { Messages.Warning("Invalid elliptical arc found in SVG file."); return; } var bezierPointArray = Geom2dUtils.EllipticalArcToBezier(ellipse, startParam, endParam); foreach (var bezierPoints in bezierPointArray) { var endPoint = _AddPoint(bezierPoints.p2); _Segments.Add(new SketchSegmentBezier(startPoint, _AddPoint(bezierPoints.c1), _AddPoint(bezierPoints.c2), endPoint)); startPoint = endPoint; } } }
//-------------------------------------------------------------------------------------------------- public gp_Elips2d GetEllipse(Dictionary <int, Pnt2d> points, double[] parameters = null) { var p1 = points[Points[0]]; var p2 = points[Points[1]]; var center = points[Points[2]]; var ellipse = Geom.Geom2dUtils.MakeEllipse(center, p1, p2); if (ellipse != null && parameters != null) { Debug.Assert(parameters.Length == 2); parameters[0] = ElCLib.Parameter(ellipse, p1); parameters[1] = ElCLib.Parameter(ellipse, p2); } return(ellipse); }
//-------------------------------------------------------------------------------------------------- public gp_Circ2d GetCircle(Dictionary <int, Pnt2d> points, double[] parameter = null) { var start = points[Points[0]]; var end = points[Points[1]]; var rim = points[Points[2]]; if ((start.Distance(end) <= 0) || (end.Distance(rim) <= 0) || (start.Distance(rim) <= 0)) { return(null); } var circ = new gce_MakeCirc2d(start, rim, end).Value(); if (circ != null && parameter != null) { Debug.Assert(parameter.Length == 2); parameter[0] = ElCLib.Parameter(circ, start); parameter[1] = ElCLib.Parameter(circ, end); } return(circ); }
//-------------------------------------------------------------------------------------------------- public override Geom2d_Curve MakeCurve(Dictionary <int, Pnt2d> points) { try { var p1 = points[Points[0]]; var p2 = points[Points[1]]; if (p1.Distance(p2) <= 0) { return(null); } var line = GetLine(points); if (line == null) { return(null); } return(new Geom2d_TrimmedCurve(new Geom2d_Line(line), ElCLib.Parameter(line, p1), ElCLib.Parameter(line, p2))); } catch (Exception) { return(null); } }
//-------------------------------------------------------------------------------------------------- void _ValueHudElement_RadiusEntered(ValueHudElement hudElement, double newValue) { if (newValue == 0) { return; } if (_Points[0].Distance(_Points[1]) == 0) { return; } var center = Geom2dUtils.FindEllipseCenterFromEndpoints(_Points[0], _Points[1], newValue, newValue, 0, newValue > 0); var xAxis = new Ax2d(center, new Dir2d(new Vec2d(center, _Points[0]))); var radius = center.Distance(_Points[0]); var circ = new gp_Circ2d(xAxis, radius, newValue < 0); var endParameter = ElCLib.Parameter(circ, _Points[1]); _Points[2] = ElCLib.Value(endParameter / 2, circ); _MergePointIndices[2] = -1; _PointAction.Stop(); _SketchEditorTool.FinishSegmentCreation(_Points, _MergePointIndices, new SketchSegment[] { _Segment }, null); }