/// <summary> /// Default constructor</summary> /// <param name="curve">Curve for which evaluator created</param> public HermiteCurveEvaluator(ICurve curve) { if (curve == null) throw new ArgumentNullException("curve"); m_curve = curve; Reset(); }
/// <summary> /// Flattens the specified curve. See <see cref="ICurve{TParam, TPoint}.Flatten"/>. /// </summary> /// <remarks> /// This method cannot be used for curves that contain gaps! /// </remarks> internal static void Flatten(ICurve<float, Vector3F> curve, ICollection<Vector3F> points, int maxNumberOfIterations, float tolerance) { if (tolerance <= 0) throw new ArgumentOutOfRangeException("tolerance", "The tolerance must be greater than zero."); float totalLength = curve.GetLength(0, 1, maxNumberOfIterations, tolerance); // No line segments if the curve has zero length. if (totalLength == 0) return; // A single line segment if the curve's length is less than the tolerance. if (totalLength < tolerance) { points.Add(curve.GetPoint(0)); points.Add(curve.GetPoint(1)); return; } var list = ResourcePools<Vector3F>.Lists.Obtain(); Flatten(curve, list, 0, 1, curve.GetPoint(0), curve.GetPoint(1), 0, totalLength, 1, maxNumberOfIterations, tolerance); foreach (var point in list) points.Add(point); ResourcePools<Vector3F>.Lists.Recycle(list); }
static IEnumerable<CurveTangent> TangentsAroundCurve(ICurve iCurve) { Curve c = iCurve as Curve; if (c != null) { foreach (ICurve seg in c.Segments) foreach (CurveTangent ct in TangentsAroundCurve(seg)) yield return ct; } else { LineSegment ls = iCurve as LineSegment; if (ls != null) yield return new CurveTangent(ls.Start, ls.Derivative(0)); else { Ellipse ellipse = iCurve as Ellipse; if (ellipse != null) { foreach (CurveTangent ct in TangentsOfEllipse(ellipse)) yield return ct; } else { CubicBezierSegment bez = iCurve as CubicBezierSegment; if (bez != null) foreach (CurveTangent ct in TangentsOfBezier(bez)) yield return ct; } } } }
static bool WithinEpsilon(ICurve bc, double start, double end) { int n = 3; //hack !!!! double d = (end - start)/n; P2 s = bc[start]; P2 e = bc[end]; return DistToSegm(bc[start + d], s, e) < epsilon && DistToSegm(bc[start + d*(n - 1)], s, e) < epsilon; }
/// <summary> /// Offsets curve</summary> /// <param name="curve">Curve</param> /// <param name="x">X offset</param> /// <param name="y">Y offset</param> public static void OffsetCurve(ICurve curve, float x, float y) { foreach (IControlPoint cpt in curve.ControlPoints) { cpt.X += x; cpt.Y += y; } }
internal Rail(ICurve curveSegment, LgEdgeInfo topRankedEdgeInfoOfTheRail, int zoomLevel) #if DEBUG : this() #endif { TopRankedEdgeInfoOfTheRail = topRankedEdgeInfoOfTheRail; this.ZoomLevel = zoomLevel; Geometry = curveSegment; }
public static Polyline PolylineAroundClosedCurve(ICurve curve) { Polyline poly = new Polyline(); foreach (Point point in PointsOnAroundPolyline(curve)) poly.AddPoint(point); if (Point.GetTriangleOrientation(poly.StartPoint.Point, poly.StartPoint.Next.Point, poly.StartPoint.Next.Next.Point) == TriangleOrientation.Counterclockwise) poly = (Polyline)poly.Reverse(); poly.Closed = true; return poly; }
public WeierstrassCurvePoint(FiniteFieldElement x, FiniteFieldElement y, ICurve curve) { if (!(curve is WeierstrassCurve)) throw new ArgumentException("A weierstrass curve point should only be placed on a weierstrass curve, but was placed on " + curve + ".", "curve"); _x = x; _y = y; _curve = curve as WeierstrassCurve; }
/// <summary> /// constructor /// </summary> internal BundleBase(int count, ICurve boundaryCurve, Point position, bool belongsToRealNode, int stationIndex) { BelongsToRealNode = belongsToRealNode; Curve = boundaryCurve; Position = position; this.stationIndex = stationIndex; points = new Point[count]; tangents = new Point[count]; OrientedHubSegments = new OrientedHubSegment[count]; ParameterSpan = Curve.ParEnd - Curve.ParStart; }
public PortEntryOnCurve(ICurve entryCurve, IEnumerable<Tuple<double, double>> parameterSpans) { EntryCurve = entryCurve; #if TEST_MSAGL var polyline = entryCurve as Polyline; curveIsClosed = (polyline != null) ? polyline.Closed : ApproximateComparer.Close(EntryCurve.Start, EntryCurve.End); #endif Spans = parameterSpans; #if TEST_MSAGL TestSpans(entryCurve, parameterSpans, curveIsClosed); #endif }
/// <summary> /// Creates a curve evaluator for a curve</summary> /// <param name="curve">Curve</param> /// <returns>Curve evaluator</returns> /// <remarks>A curve evaluator calculates y-coordinates from x-coordinates using appropriate interpolation for a curve</remarks> public static ICurveEvaluator CreateCurveEvaluator(ICurve curve) { ICurveEvaluator cv = null; if (curve.CurveInterpolation == InterpolationTypes.Linear) cv = new LinearCurveEvaluator(curve); else if (curve.CurveInterpolation == InterpolationTypes.Hermite) cv = new HermiteCurveEvaluator(curve); else throw new NotImplementedException("CurveEvaluator not implement for " + curve.CurveInterpolation); return cv; }
internal static void Serialize(string fileName, ICurve i) { Stream file = File.Open(fileName, FileMode.Create); // Create a formatter object based on command line arguments IFormatter formatter = new BinaryFormatter(); // Serialize the object graph to stream formatter.Serialize(file, i); // All done file.Close(); }
internal IntersectionInfo(double pr0, double pr1, Point x, ICurve s0, ICurve s1) { par0 = pr0; par1 = pr1; this.x = x; seg0 = s0; seg1 = s1; #if DETAILED_DEBUG System.Diagnostics.Debug.Assert(ApproximateComparer.Close(x, s0[pr0], ApproximateComparer.IntersectionEpsilon*10), string.Format("intersection not at curve[param]; x = {0}, s0[pr0] = {1}, diff = {2}", x, s0[pr0], x - s0[pr0])); System.Diagnostics.Debug.Assert(ApproximateComparer.Close(x, s1[pr1], ApproximateComparer.IntersectionEpsilon*10), string.Format("intersection not at curve[param]; x = {0}, s1[pr1] = {1}, diff = {2}", x, s1[pr1], x - s1[pr1])); #endif }
/// <summary> /// Constructor /// </summary> /// <param name="steeringCurve">Steering curve</param> /// <param name="pushCurve">Push amount curve</param> /// <param name="elevationCurve">Elevation curve</param> public KinectPilotProcessor(ICurve steeringCurve, ICurve pushCurve, ICurve elevationCurve) { if (steeringCurve == null) throw new ArgumentNullException("steeringCurve"); if (pushCurve == null) throw new ArgumentNullException("pushCurve"); if (elevationCurve == null) throw new ArgumentNullException("elevationCurve"); this.steeringCurve = steeringCurve; this.pushCurve = pushCurve; this.elevationCurve = elevationCurve; }
internal static List<LineSegment> Interpolate(double a, ref Point ap, double b, ref Point bp, ICurve s, double eps) { var r = new List<LineSegment>(); if (IsCloseToLineSeg(a, ref ap, b, ref bp, s, eps)) r.Add(new LineSegment(ap, bp)); else { double m = 0.5*(a + b); Point mp = s[m]; r.AddRange(Interpolate(a, ref ap, m, ref mp, s, eps)); r.AddRange(Interpolate(m, ref mp, b, ref bp, s, eps)); } return r; }
///// <summary> ///// Gets the closest point on the curve to the point ///// </summary> ///// <param name="curve"></param> ///// <param name="coeff"></param> ///// <param name="hint">will return Double.MaxVal if Newton iterations fail</param> ///// <param name="closestPointParam"></param> internal static double ClosestPoint(ICurve curve, Point a, double hint, double low, double high) { /* * Let F=(c(t)-a)^2. We try to bring to zero the first derivative of F, Ft. Denote it by f(t). * Applying the Newton method we see that dt=-f(t)/der(f(t) * The first derivative of F, f, has the form (c-a)*ct. We discarded a multiplier here. * The second derivative has the form ct*ct+(c-a)*ctt * The new t becomes t-dt */ const int numberOfIterationsMax = 5; const int numberOfOverShootsMax = 5; double t = hint; int numberOfIteration = 0; int numberOfOvershoots = 0; double dt; bool abort = false; do { Point c = curve[t]; Point ct = curve.Derivative(t); Point ctt = curve.SecondDerivative(t); double secondDerivative = ct * ct + (c - a) * ctt; if (Math.Abs(secondDerivative) < ApproximateComparer.Tolerance) return t; dt = (c - a) * ct / secondDerivative; t -= dt; if (t > high + ApproximateComparer.Tolerance) { t = high; numberOfOvershoots++; } else if (t < low - ApproximateComparer.Tolerance) { t = low; numberOfOvershoots++; } numberOfIteration++; } while (Math.Abs(dt) > ApproximateComparer.Tolerance &&! (abort = (numberOfIteration >= numberOfIterationsMax || numberOfOvershoots >= numberOfOverShootsMax))); //may be the initial value was just fine if (abort && (curve[hint] - a).Length < ApproximateComparer.DistanceEpsilon) t = hint; return t; }
static IEnumerable<Point> PointsOnAroundPolyline(ICurve curve) { bool firstSide = true; CurveTangent prevTangent = null; CurveTangent firstCurveTangent = null; foreach (CurveTangent curveTangent in TangentsAroundCurve(curve)) { if (firstSide) { firstSide = false; firstCurveTangent = prevTangent = curveTangent; } else { if (!TangentsAreParallel(prevTangent, curveTangent)) yield return TangentIntersection(prevTangent, curveTangent); prevTangent = curveTangent; } } yield return TangentIntersection(firstCurveTangent, prevTangent); }
static bool WithinEpsilon(ICurve seg, double start, double end, double eps) { if (seg is LineSegment) return true; int n = 3; //hack !!!! but maybe can be proven for Bezier curves and other regular curves double d = (end - start) / n; Point s = seg[start]; Point e = seg[end]; double d0 = DistToSegm(seg[start + d], s, e); double d1 = DistToSegm(seg[start + d * (n-1)], s, e); //double d1d1 = seg.d1(start) * seg.d1(end); return d0 < eps && d1 < eps;// && d1d1 > 0; }
/// <summary> /// constructor /// </summary> /// <param name="curveAPar">first curve</param> /// <param name="curveBPar">second curve</param> /// <param name="lowBound0">the first curve minimal parameter</param> /// <param name="upperBound0">the first curve maximal parameter</param> /// <param name="lowBound1">the second curve minimal parameter</param> /// <param name="upperBound1">the first curve maximal parameter</param> /// <param name="guess0"></param> /// <param name="guess1"></param> public MinDistCurveCurve(ICurve curveAPar, ICurve curveBPar, double lowBound0, double upperBound0, double lowBound1, double upperBound1, double guess0, double guess1) { this.curveA = curveAPar; this.curveB = curveBPar; this.aMin = lowBound0; this.bMin = lowBound1; this.aMax = upperBound0; this.bMax = upperBound1; this.aGuess = guess0; this.bGuess = guess1; this.si = guess0; this.ti = guess1; }
/// <summary> /// Validates the curve</summary> /// <param name="curve">Curve to validate</param> /// <returns>True iff curve is valid</returns> public static bool IsValid(ICurve curve) { if (curve == null) return false; ReadOnlyCollection<IControlPoint> points = curve.ControlPoints; if (points.Count < 2) return true; int count = points.Count; IControlPoint prev = points[0]; for (int i = 1; i < count; i++) { IControlPoint curPoint = points[i]; if ((curPoint.X - prev.X) < s_epsilone) return false; prev = curPoint; } return true; }
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)); } } }
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), Math.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; }
static bool IsCloseToLineSeg(double a, ref Point ap, double b, ref Point bp, ICurve s, double e) { const double x = 1.0/3; double p = a*x + b*(1 - x); Point delta = s[p] - (ap*x + bp*(1 - x)); if (delta*delta > e) return false; p = a*(1 - x) + b*x; delta = s[p] - (ap*(1 - x) + bp*x); if (delta*delta > e) return false; p = a*0.5 + b*0.5; delta = s[p] - (ap*0.5 + bp*0.5); if (delta*delta > e) return false; return true; }
/***************************************************/ /**** Private Methods - Fallback ****/ /***************************************************/ private static Vector TangentAtLength(this ICurve curve, double length, double tolerance = Tolerance.Distance) { Reflection.Compute.RecordError($"TangentAtLength is not implemented for ICurves of type: {curve.GetType().Name}."); return(null); }
/***************************************************/ /**** Public Methods - Interfaces ****/ /***************************************************/ public static Vector ITangentAtLength(this ICurve curve, double length, double tolerance = Tolerance.Distance) { return(TangentAtLength(curve as dynamic, length, tolerance)); }
internal ParallelogramInternalTreeNode(ICurve seg, double leafBoxesOffset) : base(seg, leafBoxesOffset) { }
/***************************************************/ /**** Public Methods - Interfaces ****/ /***************************************************/ public static Vector ITangentAtParameter(this ICurve curve, double parameter, double tolerance = Tolerance.Distance) { return(TangentAtParameter(curve as dynamic, parameter, tolerance)); }
private static bool HasLengthZero(ICurve curve) { return(MathUtils.AreEqual(curve.Length, 0)); }
/// <summary> /// Construct a solid by sweeping a face along a curve. /// </summary> /// <param name="perimeter">The perimeter of the face to sweep.</param> /// <param name="holes">The holes of the face to sweep.</param> /// <param name="curve">The curve along which to sweep.</param> /// <param name="startSetback">The setback distance of the sweep from the start of the curve.</param> /// <param name="endSetback">The setback distance of the sweep from the end of the curve.</param> /// <returns>A solid.</returns> public static Solid SweepFaceAlongCurve(Polygon perimeter, IList <Polygon> holes, ICurve curve, double startSetback = 0, double endSetback = 0) { var solid = new Solid(); var l = curve.Length(); // The start and end setbacks can't be more than // the length of the beam together. if ((startSetback + endSetback) >= l) { startSetback = 0; endSetback = 0; } // Calculate the setback parameter as a percentage // of the curve length. This will not work for curves // without non-uniform parameterization. var ssb = startSetback / l; var esb = endSetback / l; var transforms = curve.Frames(ssb, esb); if (curve is Polygon) { for (var i = 0; i < transforms.Length; i++) { var next = i == transforms.Length - 1 ? transforms[0] : transforms[i + 1]; solid.SweepPolygonBetweenPlanes(perimeter, transforms[i], next); } } else if (curve is Bezier) { var startCap = solid.AddFace(perimeter, transform: transforms[0]); for (var i = 0; i < transforms.Length - 1; i++) { var next = transforms[i + 1]; solid.SweepPolygonBetweenPlanes(perimeter, transforms[i], next); } var endCap = solid.AddFace(perimeter, transform: transforms[transforms.Length - 1], reverse: true); } else { // Add start cap. Face cap = null; Edge[][] openEdges; if (holes != null) { cap = solid.AddFace(perimeter, holes, transform: transforms[0]); openEdges = new Edge[1 + holes.Count][]; } else { cap = solid.AddFace(perimeter, transform: transforms[0]); openEdges = new Edge[1][]; } // last outer edge var openEdge = cap.Outer.GetLinkedEdges(); openEdge = solid.SweepEdges(transforms, openEdge); openEdges[0] = openEdge; if (holes != null) { for (var i = 0; i < cap.Inner.Length; i++) { openEdge = cap.Inner[i].GetLinkedEdges(); // last inner edge for one hole openEdge = solid.SweepEdges(transforms, openEdge); openEdges[i + 1] = openEdge; } } solid.Cap(openEdges, true); } return(solid); }
/***************************************************/ /**** Public Methods - Interfaces ****/ /***************************************************/ public static bool IIsContaining(this ICurve curve, List <Point> points, bool acceptOnEdge = true, double tolerance = Tolerance.Distance) { return(IsContaining(curve as dynamic, points, acceptOnEdge, tolerance)); }
/***************************************************/ public static ICurve IScale(this ICurve geometry, Point origin, Vector scaleVector) { return(Scale(geometry as dynamic, origin, scaleVector)); }
/// <summary> /// Pastes into selected curves from internal clipboard</summary> public void Paste() { if (AutoComputeCurveLimitsEnabled && s_clipboard.Length > 0 && m_selectedCurves.Length > 0) { var sorted = s_clipboard.OrderBy(item => item.X).ToArray(); // convert sorted points to local space. float fclipPtx = sorted[0].X; float fclipPty = sorted[0].Y; sorted.ForEach( item => { item.X -= fclipPtx; item.Y -= fclipPty; }); float range = (sorted.Last().X - sorted.First().X) + CurveUtils.Epsilone; ICurve[] selectedCurves = new ICurve[m_selectedCurves.Length]; m_selectedCurves.CopyTo(selectedCurves, 0); ClearSelection(); m_selection.BeginUpdate(); m_transactionContext.DoTransaction(delegate { foreach (ICurve curve in selectedCurves) { if (curve.ControlPoints.Count == 0) continue; // relax the curve limits to allow offset. curve.MinX = float.MinValue; curve.MaxX = float.MaxValue; curve.MinY = float.MaxValue; curve.MaxY = float.MaxValue; var insertAt = new PointF(curve.ControlPoints[0].X, curve.ControlPoints[0].Y); CurveUtils.OffsetCurve(curve, range, 0); int index = 0; foreach (IControlPoint clipCpt in sorted) { IControlPoint cpt = clipCpt.Clone(); cpt.X += insertAt.X; cpt.Y += insertAt.Y; curve.InsertControlPoint(index++, cpt); m_selection.Add(cpt); cpt.EditorData.SelectedRegion = PointSelectionRegions.Point; } CurveUtils.ComputeTangent(curve); UpdateCurveLimits(); } }, "Paste".Localize()); m_selection.EndUpdate(); UpdateCurveLimits(); Invalidate(); } }
/// <summary> /// Creates a Node instance /// </summary> /// <param name="curve">node boundaryCurve</param> public Node(ICurve curve) { boundaryCurve = curve; }
/// <summary> /// Removes all the control points of the curve from the selection</summary> /// <param name="curve">Curve whose control points are removed</param> public void RemoveCurveFromSelection(ICurve curve) { if (!m_curves.Contains(curve)) throw new ArgumentException("curve not found"); if (m_selection.Count > 0) { m_selection.BeginUpdate(); IControlPoint[] snapShot = m_selection.GetSnapshot(); foreach (IControlPoint cpt in snapShot) { if (cpt.Parent == curve) { m_selection.Remove(cpt); cpt.EditorData.SelectedRegion = PointSelectionRegions.None; } } m_selection.EndUpdate(); } }
/// <summary> /// </summary> /// <param name="label"></param> /// <returns></returns> public bool PlaceEdgeLabelHorizontally(Label label) { ValidateArg.IsNotNull(label, "label"); var e = (Edge)label.GeometryParent; // approximate label with a rectangle // process candidate points for label ordered by priority // check candidate point for conflicts - if none then stop and keep placement label.InnerPoints = null; List <KeyValuePair <double, Point> > curvePoints = edgePoints[e]; var wh = new Point(label.Width, label.Height); int bestConflictIndex = -1; var bestRectangle = new Rectangle(); foreach (int index in ExpandingSearch(StartIndex(label, curvePoints), 0, curvePoints.Count)) { KeyValuePair <double, Point> cp = curvePoints[index]; ICurve curve = e.Curve ?? new LineSegment(e.Source.Center, e.Target.Center); Point der = curve.Derivative(cp.Key); if (der.LengthSquared < ApproximateComparer.DistanceEpsilon) { continue; } foreach (double side in GetPossibleSides(label.Side, der)) { Rectangle queryRect = GetLabelBounds(cp.Value, der, wh, side); int conflictIndex = ConflictIndex(queryRect, label); if (conflictIndex > bestConflictIndex) { bestConflictIndex = conflictIndex; bestRectangle = queryRect; // If the best location was found, we're done if (bestConflictIndex == int.MaxValue) { break; } } } // If the best location was found, we're done if (bestConflictIndex == int.MaxValue) { break; } } if (bestConflictIndex >= 0) { SetLabelBounds(label, bestRectangle); var r = new RectangleObstacle(bestRectangle); AddLabelObstacle(r); #if SHARPKIT //https://code.google.com/p/sharpkit/issues/detail?id=371 if (bestConflictIndex == 0) { label.PlacementResult = LabelPlacementResult.OverlapsOtherLabels; } else if (bestConflictIndex == 1) { label.PlacementResult = LabelPlacementResult.OverlapsNodes; } else if (bestConflictIndex == 2) { label.PlacementResult = LabelPlacementResult.OverlapsEdges; } else { label.PlacementResult = LabelPlacementResult.OverlapsNothing; } #else label.PlacementResult = (LabelPlacementResult)bestConflictIndex; #endif return(true); } return(false); }
private void GetSplines(int index, out ICurve <float, float> xSpline, out ICurve <float, float> ySpline) { // Spline keys CurveKey2F p2 = Items[index]; CurveKey2F p3 = Items[Math.Min(Count - 1, index + 1)]; if (Items[index].Interpolation == SplineInterpolation.StepLeft) { var spline = StepSegment1F.Create(); spline.Point1 = p2.Point.X; spline.Point2 = p3.Point.X; spline.StepType = StepInterpolation.Left; xSpline = spline; spline = StepSegment1F.Create(); spline.Point1 = p2.Point.Y; spline.Point2 = p3.Point.Y; spline.StepType = StepInterpolation.Left; ySpline = spline; } else if (Items[index].Interpolation == SplineInterpolation.StepCentered) { var spline = StepSegment1F.Create(); spline.Point1 = p2.Point.X; spline.Point2 = p3.Point.X; spline.StepType = StepInterpolation.Centered; xSpline = spline; spline = StepSegment1F.Create(); spline.Point1 = p2.Point.Y; spline.Point2 = p3.Point.Y; spline.StepType = StepInterpolation.Centered; ySpline = spline; } else if (Items[index].Interpolation == SplineInterpolation.StepRight) { var spline = StepSegment1F.Create(); spline.Point1 = p2.Point.X; spline.Point2 = p3.Point.X; spline.StepType = StepInterpolation.Right; xSpline = spline; spline = StepSegment1F.Create(); spline.Point1 = p2.Point.Y; spline.Point2 = p3.Point.Y; spline.StepType = StepInterpolation.Right; ySpline = spline; } else if (Items[index].Interpolation == SplineInterpolation.Linear) { var spline = LineSegment1F.Create(); spline.Point1 = p2.Point.X; spline.Point2 = p3.Point.X; xSpline = spline; spline = LineSegment1F.Create(); spline.Point1 = p2.Point.Y; spline.Point2 = p3.Point.Y; ySpline = spline; } else if (Items[index].Interpolation == SplineInterpolation.Bezier) { var spline = BezierSegment1F.Create(); spline.Point1 = p2.Point.X; spline.ControlPoint1 = p2.TangentOut.X; spline.Point2 = p3.Point.X; spline.ControlPoint2 = p3.TangentIn.X; xSpline = spline; spline = BezierSegment1F.Create(); spline.Point1 = p2.Point.Y; spline.ControlPoint1 = p2.TangentOut.Y; spline.Point2 = p3.Point.Y; spline.ControlPoint2 = p3.TangentIn.Y; ySpline = spline; } else if (Items[index].Interpolation == SplineInterpolation.Hermite) { var spline = HermiteSegment1F.Create(); spline.Point1 = p2.Point.X; spline.Tangent1 = p2.TangentOut.X; spline.Point2 = p3.Point.X; spline.Tangent2 = p3.TangentIn.X; xSpline = spline; spline = HermiteSegment1F.Create(); spline.Point1 = p2.Point.Y; spline.Tangent1 = p2.TangentOut.Y; spline.Point2 = p3.Point.Y; spline.Tangent2 = p3.TangentIn.Y; ySpline = spline; } else { Vector2F p1; Vector2F p4; if (index > 0) { p1 = Items[index - 1].Point; } else if (SmoothEnds && PreLoop == CurveLoopType.Constant && Items[index].Interpolation == SplineInterpolation.CatmullRom) { // Mirror point 1 through point 0 for x component. // Set a constant y. // This does not work for BSplines because they would not run through the last point. p1 = new Vector2F(Items[0].Point.X - (Items[1].Point.X - Items[0].Point.X), p2.Point.Y); } else if (SmoothEnds && PreLoop == CurveLoopType.Cycle) { // Wrap around. p1 = Items[Count - 2].Point; // Add offset to x. p1.X = p1.X - (Items[Count - 1].Point.X - Items[0].Point.X); } else if (SmoothEnds && PreLoop == CurveLoopType.CycleOffset) { // Wrap around and add offset. p1 = Items[Count - 2].Point - (Items[Count - 1].Point - Items[0].Point); } else if (SmoothEnds && PreLoop == CurveLoopType.Oscillate) { // Mirror point 1 through point 0 for x component. // Y should be the same as p3. p1 = new Vector2F(Items[0].Point.X - (Items[1].Point.X - Items[0].Point.X), p3.Point.Y); } else { // Mirror point 1 through point 0. p1 = Items[0].Point - (Items[1].Point - Items[0].Point); } Debug.Assert(index > 0 || Count > 1); if (index + 2 < Count) { p4 = Items[index + 2].Point; } else if (SmoothEnds && PostLoop == CurveLoopType.Constant && Items[index].Interpolation == SplineInterpolation.CatmullRom) { // This does not work for BSplines because they would not run through the last point. // Mirror point Count-2 through last point for x component. // Set a constant y. p4 = new Vector2F(Items[Count - 1].Point.X + (Items[Count - 1].Point.X - Items[Count - 2].Point.X), p3.Point.Y); } else if (SmoothEnds && PostLoop == CurveLoopType.Cycle) { // Wrap around. p4 = Items[1].Point; // Add offset to x. p4.X = p4.X + (Items[Count - 1].Point.X - Items[0].Point.X); } else if (SmoothEnds && PostLoop == CurveLoopType.CycleOffset) { // Wrap around and add offset. p4 = Items[1].Point + (Items[Count - 1].Point - Items[0].Point); } else if (SmoothEnds && PostLoop == CurveLoopType.Oscillate) { // Mirror point Count-2 through last point for x component. // y should be the same as p2.Y. p4 = new Vector2F(Items[Count - 1].Point.X + (Items[Count - 1].Point.X - Items[Count - 2].Point.X), p2.Point.Y); } else { // Mirror point Count-2 through last point. p4 = Items[Count - 1].Point + (Items[Count - 1].Point - Items[Count - 2].Point); } if (Items[index].Interpolation == SplineInterpolation.BSpline) { var spline = BSplineSegment1F.Create(); spline.Point1 = p1.X; spline.Point2 = p2.Point.X; spline.Point3 = p3.Point.X; spline.Point4 = p4.X; xSpline = spline; spline = BSplineSegment1F.Create(); spline.Point1 = p1.Y; spline.Point2 = p2.Point.Y; spline.Point3 = p3.Point.Y; spline.Point4 = p4.Y; ySpline = spline; } else { Debug.Assert((Items[index].Interpolation == SplineInterpolation.CatmullRom)); var spline = CatmullRomSegment1F.Create(); spline.Point1 = p1.X; spline.Point2 = p2.Point.X; spline.Point3 = p3.Point.X; spline.Point4 = p4.X; xSpline = spline; spline = CatmullRomSegment1F.Create(); spline.Point1 = p1.Y; spline.Point2 = p2.Point.Y; spline.Point3 = p3.Point.Y; spline.Point4 = p4.Y; ySpline = spline; } } }
public bool cilpOperator(IMap iMap, string inLayerName, string clipLayerName, string outpath) { IFeatureLayer inLayer = (IFeatureLayer)GetLayerByName(inLayerName); IFeatureLayer clipLayer = (IFeatureLayer)GetLayerByName(clipLayerName); //调用GeoProcessing工具 Geoprocessor geoprocessor = new Geoprocessor(); geoprocessor.OverwriteOutput = true; IFeatureClass inLayerFeaCls = inLayer.FeatureClass; IFeatureClass clipLayerFeaCls = clipLayer.FeatureClass; //调用clip工具 ESRI.ArcGIS.AnalysisTools.Clip clip = new ESRI.ArcGIS.AnalysisTools.Clip( inLayerFeaCls, clipLayerFeaCls, outpath + "\\" + inLayerName + "_Clip"); geoprocessor.Execute(clip, null); //输出切割后图层 IWorkspaceFactory workspaceFactory = new ShapefileWorkspaceFactoryClass(); IFeatureWorkspace featureWorkspace = (IFeatureWorkspace)workspaceFactory.OpenFromFile(outpath, 0); IFeatureClass outFClass = featureWorkspace.OpenFeatureClass(inLayerName + "_Clip"); IFeatureLayer outLayer = new FeatureLayerClass(); outLayer.FeatureClass = outFClass; outLayer.Name = inLayerName + "_Clip"; iMap.AddLayer(outLayer); IActiveView activeView = iMap as IActiveView; activeView.Refresh(); if (inLayerName == "DLTB") { int raIndex = outFClass.FindField("SHAPE_Area"); IFeatureCursor featureCursor = outLayer.FeatureClass.Search(null, false); IFeature feature = featureCursor.NextFeature(); while (feature != null) { if (feature.Shape.GeometryType == esriGeometryType.esriGeometryPolygon) { //使用IArea接口计算面积 IArea pArea = feature.Shape as IArea; feature.set_Value(raIndex, pArea.Area); } feature.Store(); feature = featureCursor.NextFeature(); } } else if (inLayerName == "XZDW") { //计算切割后图层中线状地物的长度 IFieldsEdit pFieldsEdit = outFClass.Fields as IFieldsEdit; IField pField = new FieldClass(); IFieldEdit pFieldEdit = pField as IFieldEdit; pFieldEdit.Name_2 = "Real_Leng"; pFieldEdit.Type_2 = esriFieldType.esriFieldTypeDouble; outFClass.AddField(pField); int rlIndex = outFClass.FindField("Real_Leng"); int slIndex = outFClass.FindField("SHAPE_Leng"); int xzdwmjIndex = outFClass.FindField("XZDWMJ"); IFeatureCursor featureCursor = outLayer.FeatureClass.Search(null, false); IFeature feature = featureCursor.NextFeature(); while (feature != null) { if (feature.Shape.GeometryType == esriGeometryType.esriGeometryPolyline) { //使用ICure接口计算长度 ICurve pCurve = feature.Shape as ICurve; feature.set_Value(rlIndex, pCurve.Length); //计算切割后线状地物面积 Double real_mj = Double.Parse(feature.get_Value(rlIndex).ToString()) / Double.Parse(feature.get_Value(slIndex).ToString()) * Double.Parse(feature.get_Value(xzdwmjIndex).ToString()); feature.set_Value(xzdwmjIndex, real_mj.ToString()); } feature.Store(); feature = featureCursor.NextFeature(); } } return(true); }//切割
public static IElement1D NewElement1D(this Panel panel, ICurve curve) { return(Query.NewElement1D(panel, curve)); }
private IGSLine CreateGSLine(IMetricUnitConverter MetricConversion, ICadastralPoints CadastralPoints, ref IPoint FromPointInToPointOut, int FromPointID, double Direction, double Distance, double Radius, int Accuracy, int UserLineType, int Category, bool ComputeToPoint, out int ToPointID) { //In this function, Radius == 0 means a straight line //If the radius is >0 or <0 then the line is a circular curve with Distance as the chord length //for curves Bearing means chord bearing //negative radius means a curve to the left, positive radius curve to the right //for no Accuracy, no Type, or no Category pass in -1 //Bearing is in north azimuth radians IGSLine pLine = new GSLineClass(); pLine.Bearing = Direction; //direction is in radians north azimuth double dConvertedDistance = 0; MetricConversion.ConvertDistance(esriCadastralUnitConversionType.esriCUCToMetric, Distance, ref dConvertedDistance); pLine.Distance = dConvertedDistance; //needs to be in meters; if (Math.Abs(Radius) > 0) { MetricConversion.ConvertDistance(esriCadastralUnitConversionType.esriCUCToMetric, Radius, ref dConvertedDistance); pLine.Radius = dConvertedDistance; //needs to be in meters; } pLine.FromPoint = FromPointID; pLine.ToPoint = -1; if (Accuracy > -1) { pLine.Accuracy = Accuracy; } if (UserLineType > -1) { pLine.LineType = UserLineType; } if (Category > -1) { pLine.Category = (esriCadastralLineCategory)Category; } //Make sure that any extended attributes on the line have their default values set IGSAttributes pGSAttributes = (IGSAttributes)pLine; if (pGSAttributes != null) { ICadastralObjectSetup pCadaObjSetup = (ICadastralObjectSetup)MetricConversion; //QI pCadaObjSetup.AddExtendedAttributes(pGSAttributes); pCadaObjSetup.SetDefaultValues(pGSAttributes); } //Compute the new end point for the line. //FromPointInToPointOut is in units of the map projection. ICurve pCurv = MetricConversion.GetSurveyedLine(pLine, CadastralPoints, false, FromPointInToPointOut); //pCurv is also in the units of the map projection. Convert the end point to metric units. FromPointInToPointOut = pCurv.ToPoint;//pass the new To point back out FromPointInToPointOut.Z = 0; IGSPoint pGSPointTo = MetricConversion.SetGSPoint(FromPointInToPointOut); if (ComputeToPoint) { CadastralPoints.AddPoint(pGSPointTo); pLine.ToPoint = pGSPointTo.Id; ToPointID = pLine.ToPoint; } else { ToPointID = -1; } if (pCurv is ICircularArc) { ICircularArc pCircArc = (ICircularArc)pCurv; IPoint pCtrPt = pCircArc.CenterPoint; IZAware pZAw = (IZAware)pCtrPt; pZAw.ZAware = true; pCtrPt.Z = 0; IGSPoint pGSCtrPt = MetricConversion.SetGSPoint(pCtrPt); CadastralPoints.AddPoint(pGSCtrPt); pLine.CenterPoint = pGSCtrPt.Id; } return(pLine); }
public static List <Edge> ToEdges(this ICurve curve) { return(curve.ICollapseToPolyline(BH.oM.Geometry.Tolerance.Angle).ToEdges()); }
public static IElement1D NewElement1D(this Opening opening, ICurve curve) { return(Query.NewElement1D(opening, curve)); }
/***************************************************/ private static bool IsContaining(this ICurve curve1, ICurve curve2, bool acceptOnEdge = true, double tolerance = Tolerance.Distance) { throw new NotImplementedException($"IsContaining is not implemented for a combination of {curve1.GetType().Name} and {curve2.GetType().Name}."); }
/***************************************************/ /**** Public Methods - Interface ****/ /***************************************************/ public static Polyline IToPolyline(ICurve curve) { return(ToPolyline(curve as dynamic)); }
/***************************************************/ /**** Private Fallback Methods ****/ /***************************************************/ private static bool IsContaining(this ICurve curve, List <Point> points, bool acceptOnEdge = true, double tolerance = Tolerance.Distance) { throw new NotImplementedException($"IsContaining is not implemented for ICurves of type: {curve.GetType().Name}."); }
/***************************************************/ public static bool IsContaining(this Line curve1, ICurve curve2, bool acceptOnEdge = true, double tolerance = Tolerance.Distance) { return(false); }
public Brep BrepToSpeckle(Solid solid) { #if REVIT2021 // TODO: Incomplete implementation!! var brep = new Brep(); brep.units = ModelUnits; if (solid is null || solid.Faces.IsEmpty) { return(null); } var faceIndex = 0; var edgeIndex = 0; var curve2dIndex = 0; var curve3dIndex = 0; var loopIndex = 0; var trimIndex = 0; var surfaceIndex = 0; var speckleFaces = new Dictionary <Face, BrepFace>(); var speckleEdges = new Dictionary <Edge, BrepEdge>(); var speckleEdgeIndexes = new Dictionary <Edge, int>(); var speckle3dCurves = new ICurve[solid.Edges.Size]; var speckle2dCurves = new List <ICurve>(); var speckleLoops = new List <BrepLoop>(); var speckleTrims = new List <BrepTrim>(); foreach (var face in solid.Faces.Cast <Face>()) { var surface = FaceToSpeckle(face, out bool orientation, 0.0); var iterator = face.EdgeLoops.ForwardIterator(); var loopIndices = new List <int>(); while (iterator.MoveNext()) { var loop = iterator.Current as EdgeArray; var loopTrimIndices = new List <int>(); // Loop through the edges in the loop. var loopIterator = loop.ForwardIterator(); while (loopIterator.MoveNext()) { // Each edge should create a 2d curve, a 3d curve, a BrepTrim and a BrepEdge. var edge = loopIterator.Current as Edge; var faceA = edge.GetFace(0); // Determine what face side are we currently on. var edgeSide = face == faceA ? 0 : 1; // Get curve, create trim and save index var trim = edge.GetCurveUV(edgeSide); var sTrim = new BrepTrim(brep, edgeIndex, faceIndex, loopIndex, curve2dIndex, 0, BrepTrimType.Boundary, edge.IsFlippedOnFace(edgeSide), -1, -1); var sTrimIndex = trimIndex; loopTrimIndices.Add(sTrimIndex); // Add curve and trim, increase index counters. speckle2dCurves.Add(CurveToSpeckle(trim.As3DCurveInXYPlane())); speckleTrims.Add(sTrim); curve2dIndex++; trimIndex++; // Check if we have visited this edge before. if (!speckleEdges.ContainsKey(edge)) { // First time we visit this edge, add 3d curve and create new BrepEdge. var edgeCurve = edge.AsCurve(); speckle3dCurves[curve3dIndex] = CurveToSpeckle(edgeCurve); var sCurveIndex = curve3dIndex; curve3dIndex++; // Create a trim with just one of the trimIndices set, the second one will be set on the opposite condition. var sEdge = new BrepEdge(brep, sCurveIndex, new[] { sTrimIndex }, -1, -1, edge.IsFlippedOnFace(face), null); speckleEdges.Add(edge, sEdge); speckleEdgeIndexes.Add(edge, edgeIndex); edgeIndex++; } else { // Already visited this edge, skip curve 3d var sEdge = speckleEdges[edge]; var sEdgeIndex = speckleEdgeIndexes[edge]; sTrim.EdgeIndex = sEdgeIndex; // Update trim indices with new item. // TODO: Make this better. var trimIndices = sEdge.TrimIndices.ToList(); trimIndices.Append(sTrimIndex); sEdge.TrimIndices = trimIndices.ToArray(); } } var speckleLoop = new BrepLoop(brep, faceIndex, loopTrimIndices, BrepLoopType.Outer); speckleLoops.Add(speckleLoop); var sLoopIndex = loopIndex; loopIndex++; loopIndices.Add(sLoopIndex); } speckleFaces.Add(face, new BrepFace(brep, surfaceIndex, loopIndices, loopIndices[0], !face.OrientationMatchesSurfaceOrientation)); faceIndex++; brep.Surfaces.Add(surface); surfaceIndex++; } var mesh = new Mesh(); (mesh.faces, mesh.vertices) = GetFaceVertexArrFromSolids(new List <Solid> { solid }); mesh.units = ModelUnits; // TODO: Revit has no brep vertices. Must call 'brep.SetVertices()' in rhino when provenance is revit. // TODO: Set tolerances and flags in rhino when provenance is revit. brep.Faces = speckleFaces.Values.ToList(); brep.Curve2D = speckle2dCurves; brep.Curve3D = speckle3dCurves.ToList(); brep.Trims = speckleTrims; brep.Edges = speckleEdges.Values.ToList(); brep.Loops = speckleLoops; brep.displayValue = mesh; return(brep); #else throw new Exception("Converting BREPs to Speckle is currently only supported in Revit 2021."); #endif }
static Point Middle(ICurve iCurve) { return(iCurve[iCurve.ParStart + 0.5 * (iCurve.ParEnd - iCurve.ParStart)]); }
/***************************************************/ public static bool IIsContaining(this ICurve curve1, ICurve curve2, bool acceptOnEdge = true, double tolerance = Tolerance.Distance) { return(IsContaining(curve1 as dynamic, curve2 as dynamic, acceptOnEdge, tolerance)); }
private static List <Bar> AnalyticalBars(ConstantFramingElementProperty property, ICurve centreLine, string name, double angleTolerance, int maxNbBars) { if (centreLine is NurbsCurve) { Engine.Reflection.Compute.RecordError("The analytical bars method is currently not supported for NurbsCurves. Please use another method to split up the nurbs to polylines that can be used to construct the bars."); return(new List <Bar>()); } return(centreLine.ISubParts().SelectMany(x => x.ICollapseToPolyline(angleTolerance, maxNbBars).SubParts()).Select(x => Create.Bar(x, property.SectionProperty, property.OrientationAngle, Create.BarReleaseFixFix(), BarFEAType.Flexural, name)).ToList()); }
/***************************************************/ /**** Private Methods ****/ /***************************************************/ private static List <Bar> AnalyticalBars(BHP.FramingProperties.ConstantFramingProperty property, ICurve centreLine, string name, double angleTolerance, int maxNbBars, ref Dictionary <BHP.FramingProperties.IFramingElementProperty, object> convertedProps) { if (centreLine is NurbsCurve) { Engine.Reflection.Compute.RecordError("The analytical bars method is currently not supported for NurbsCurves. Please use another method to split up the nurbs to polylines that can be used to construct the bars."); return(new List <Bar>()); } bool isLinear = centreLine.IIsLinear(); Plane curvePlane = null; if (!isLinear) { curvePlane = centreLine.IFitPlane(); } ISectionProperty section; if (convertedProps.ContainsKey(property)) { section = convertedProps[property] as ISectionProperty; } else { section = ToSectionProperty(property); convertedProps[property] = section; } List <Bar> bars = new List <Bar>(); foreach (ICurve part in centreLine.ISubParts()) { foreach (Line line in part.ICollapseToPolyline(angleTolerance, maxNbBars).SubParts()) { if (isLinear) { bars.Add(Create.Bar(line, section, property.OrientationAngle, Create.BarReleaseFixFix(), BarFEAType.Flexural, name)); } else { Vector nomal = curvePlane.Normal.Rotate(property.OrientationAngle, line.Direction()); bars.Add(Create.Bar(line, section, nomal, Create.BarReleaseFixFix(), BarFEAType.Flexural, name)); } } } return(bars); }
void ProcessExpandingSearchOnSide(int index, List <KeyValuePair <double, Point> > curvePoints, ICurve curve, double side, double radius, double distanceFromCurve, Point wh, ref double coveredLength, PointSetList placedPoints, double labelLength) { foreach (int i in ExpandingSearch(index, 0, curvePoints.Count)) { KeyValuePair <double, Point> p = curvePoints[i]; Point der = curve.Derivative(p.Key); if (der.LengthSquared < ApproximateComparer.DistanceEpsilon) { continue; } Point o = der.Rotate(Math.PI / 2).Normalize() * side; Point labelPos = p.Value + (radius + distanceFromCurve) * o; if (!Conflict(labelPos, radius, wh)) { // found a valid candidate position var ps = new PointSet { Key = p.Key, Center = labelPos, Inner = p.Value + distanceFromCurve * o, Outer = p.Value + (2.0 * radius + distanceFromCurve) * o }; coveredLength = i <= index ? placedPoints.AddFirst(ps) : placedPoints.AddLast(ps); Debug.Assert(Math.Abs(PointSetLength(placedPoints.Points) - coveredLength) < 0.01); if (coveredLength >= labelLength) { break; } } else { // not going to work! break; } } }
public static bool IsNurbsCurve(this ICurve curve) { return(curve.ISubParts().Any(x => x is NurbsCurve));; }
private void ValidateCurveLimits(ICurve curve, CurveLimitSides side) { switch (side) { case CurveLimitSides.Left: { IControlPoint firstPt = curve.ControlPoints.Count > 0 ? curve.ControlPoints[0] : null; float left = firstPt != null ? firstPt.X : curve.MaxX - CurveUtils.Epsilone; if (curve.MinX > left) curve.MinX = left; } break; case CurveLimitSides.Right: { IControlPoint lastPt = curve.ControlPoints.Count > 0 ? curve.ControlPoints[curve.ControlPoints.Count-1] : null; float right = lastPt != null ? lastPt.X : curve.MinX + CurveUtils.Epsilone; if (curve.MaxX < right) curve.MaxX = right; } break; case CurveLimitSides.Top: { float top = curve.MinY + CurveUtils.Epsilone; foreach (var cpt in curve.ControlPoints) if (cpt.Y > top) top = cpt.Y; if (curve.MaxY < top) curve.MaxY = top; } break; case CurveLimitSides.Bottom: { float bottom = curve.MaxY - CurveUtils.Epsilone; foreach (var cpt in curve.ControlPoints) if (cpt.Y < bottom) bottom = cpt.Y; if (curve.MinY > bottom) curve.MinY = bottom; } break; } }
public static void ComputeOffsetDirection(this NXOpen.Features.OffsetCurveBuilder obj, ICurve seedEntity, Point3d seedPoint, out Vector3d offsetDirection, out Point3d startPoint) { offsetDirection = new Vector3d(); startPoint = new Point3d(); }
private void m_selection_SelectionChanged(object sender, EventArgs e) { Dictionary<ICurve, object> curves = new Dictionary<ICurve, object>(); foreach (IControlPoint cpt in m_selection) { if (cpt.EditorData.SelectedRegion == PointSelectionRegions.None) cpt.EditorData.SelectedRegion = PointSelectionRegions.Point; curves[cpt.Parent] = null; } m_selectedCurves = new ICurve[curves.Count]; curves.Keys.CopyTo(m_selectedCurves, 0); SelectionChanged(this, EventArgs.Empty); }
static void ExtendPolylineEndToClusterBoundary(Polyline poly, ICurve curve) { var par = curve.ClosestParameter(poly.End); poly.AddPoint(curve[par]); }
/// <summary> /// Create a node instance with the given curve and user data. /// </summary> public Node(ICurve curve, object userData) { this.boundaryCurve = curve; this.UserData = userData; }
static void ExtendPolylineStartToClusterBoundary(Polyline poly, ICurve curve) { var par = curve.ClosestParameter(poly.Start); poly.PrependPoint(curve[par]); }
internal NodeRestoreData(ICurve boundaryCurve) { this.boundaryCurve = boundaryCurve; }
private void inputDimCurvesChanged(CurveInput sender, ICurve SelectedCurve) { dimCurve = SelectedCurve; }