/// <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; } } } }
static void SegmentsPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args) { PathFigure3D fig = obj as PathFigure3D; if (fig.figFlattened != null) { fig.SegmentsPropertyChanged(); } }
static void StartPointPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args) { PathFigure3D fig = obj as PathFigure3D; if (fig.figFlattened != null) { fig.figFlattened.StartPoint = (Point3D)args.NewValue; SegmentsPropertyChanged(obj, args); } }
/// <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; } } } }
/// <summary> /// /// </summary> public PathFigure3D() { figFlattened = new PathFigure3D(0); Segments = new PathSegment3DCollection(); }