/// <summary> /// Sets the coordinates of all the individual lines in the visual. /// </summary> /// <param name="args"> /// The <c>DependencyPropertyChangedEventArgs</c> object associated /// with the property-changed event that resulted in this method /// being called. /// </param> /// <param name="lines"> /// The <c>Point3DCollection</c> to be filled. /// </param> /// <remarks> /// <para> /// Classes that derive from <c>WireBase</c> override this /// method to fill the <c>lines</c> collection. /// It is custmary for implementations of this method to clear /// the <c>lines</c> collection first before filling it. /// Each pair of successive members of the <c>lines</c> /// collection indicate one straight line. /// </para> /// </remarks> protected override void Generate(DependencyPropertyChangedEventArgs args, Point3DCollection lines) { lines.Clear(); if (Data == null) { return; } Transform3D xform = Data.Transform; foreach (PathFigure3D fig in Data.Figures) { PathFigure3D figFlattened = fig.GetFlattenedPathFigure(); Point3D pointStart = xform.Transform(figFlattened.StartPoint); foreach (PathSegment3D seg in figFlattened.Segments) { PolyLineSegment3D segPoly = seg as PolyLineSegment3D; for (int i = 0; i < segPoly.Points.Count; i++) { lines.Add(pointStart); Point3D point = xform.Transform(segPoly.Points[i]); lines.Add(point); pointStart = point; } } } }
/// <summary> /// /// </summary> /// <param name="progress"></param> /// <param name="point"></param> /// <param name="tangent"></param> public void GetPointAtFractionLength(double progress, out Point3D point, out Vector3D tangent) { progress = Math.Max(0, Math.Min(1, progress)); point = new Point3D(); tangent = new Vector3D(); double lengthTotal = 0, length = 0; foreach (PathFigure3D fig in Figures) { PathFigure3D figFlattened = fig.GetFlattenedPathFigure(); Point3D ptStart = figFlattened.StartPoint; foreach (PathSegment3D seg in figFlattened.Segments) { PolyLineSegment3D segPoly = seg as PolyLineSegment3D; foreach (Point3D pt in segPoly.Points) { lengthTotal += (pt - ptStart).Length; ptStart = pt; } } } foreach (PathFigure3D fig in Figures) { PathFigure3D figFlattened = fig.GetFlattenedPathFigure(); Point3D ptStart = figFlattened.StartPoint; foreach (PathSegment3D seg in figFlattened.Segments) { PolyLineSegment3D segPoly = seg as PolyLineSegment3D; foreach (Point3D pt in segPoly.Points) { tangent = pt - ptStart; double lengthSeg = tangent.Length; length += lengthSeg; if (length / lengthTotal >= progress) { double factor1 = ((length / lengthTotal) - progress) / (lengthSeg / lengthTotal); double factor2 = 1 - factor1; point = (Point3D)(factor1 * (Vector3D)ptStart + factor2 * (Vector3D)pt); return; } ptStart = pt; } } } }
void SegmentsPropertyChanged() { PolyLineSegment3D polyseg = figFlattened.Segments[0] as PolyLineSegment3D; Point3DCollection points = polyseg.Points; polyseg.Points = null; points.Clear(); Point3D ptStart = StartPoint; foreach (PathSegment3D seg in Segments) { if (seg is LineSegment3D) { LineSegment3D segLine = seg as LineSegment3D; points.Add(segLine.Point); ptStart = segLine.Point; } else if (seg is PolyLineSegment3D) { PolyLineSegment3D segPoly = seg as PolyLineSegment3D; foreach (Point3D pt in segPoly.Points) { points.Add(pt); ptStart = pt; } } else if (seg is BezierSegment3D) { BezierSegment3D segBez = seg as BezierSegment3D; ConvertBezier(points, ptStart, segBez.Point1, segBez.Point2, segBez.Point3); ptStart = segBez.Point3; } else if (seg is PolyBezierSegment3D) { PolyBezierSegment3D segPoly = seg as PolyBezierSegment3D; for (int i = 0; i < segPoly.Points.Count; i += 3) { ConvertBezier(points, ptStart, segPoly.Points[i], segPoly.Points[i + 1], segPoly.Points[i + 2]); ptStart = segPoly.Points[i + 2]; } } } polyseg.Points = points; }