public static CurvePart CreateCurvePart(FTVector[] orgPointCoords, byte[] pointTags, short[] curvePartEndPoints, int i, List <float3> partVerts, List <byte> partTags) { var index = Array.IndexOf(curvePartEndPoints, (short)i); var cp = new CurvePart { IsClosed = true, CurveSegments = new List <CurveSegment>() }; //Marginal case - first contour ( 0 to contours[0] ). if (index == 0) { for (var j = 0; j <= i; j++) { CurvePartVertice(cp, j, orgPointCoords, partVerts); partTags.Add(pointTags[j]); } //The start point is the first point in the outline.Points array. cp.StartPoint = new float3(orgPointCoords[0].X.Value, orgPointCoords[0].Y.Value, 0); } //contours[0]+1 to contours[1] else { for (var j = curvePartEndPoints[index - 1] + 1; j <= curvePartEndPoints[index]; j++) { CurvePartVertice(cp, j, orgPointCoords, partVerts); partTags.Add(pointTags[j]); } //The index in outline.Points which describes the start point is given by the index of the foregone outline.contours index +1. cp.StartPoint = new float3(orgPointCoords[curvePartEndPoints[index - 1] + 1].X.Value, orgPointCoords[curvePartEndPoints[index - 1] + 1].Y.Value, 0); } return(cp); }
private CurvePart CreatePart(int startIndex) { CurvePart part = new CurvePart(); part.StartIndex = startIndex; part.Count = 0; _Parts.Add(part); return(part); }
/// <summary> /// Splits a CurvePart into CurveSegments by reading the byte pattern from a tag array. /// </summary> /// <param name="part">The CurvePart to be split into CurveSegments.</param> /// <param name="partTags">Tags of the CurvePart (on curve point, off curve point).</param> /// <param name="partVerts">Vertices of the CurvePart</param> /// <returns></returns> public static List <CurveSegment> SplitPartIntoSegments(CurvePart part, List <byte> partTags, List <float3> partVerts) { byte[] linearPattern = { 1, 1 }; byte[] conicPattern = { 1, 0, 1 }; byte[] cubicPattern = { 1, 0, 0, 1 }; byte[] conicVirtualPattern = { 1, 0, 0, 0 }; var segments = new List <CurveSegment>(); for (var i = 0; i < partTags.Count; i++) { if (partTags.Skip(i).Take(linearPattern.Length).SequenceEqual(linearPattern)) { Type = SegmentType.Linear; segments.Add(CreateCurveSegment(i, linearPattern, partVerts)); } else if (partTags.Skip(i).Take(conicPattern.Length).SequenceEqual(conicPattern)) { Type = SegmentType.Conic; segments.Add(CreateCurveSegment(i, conicPattern, partVerts)); i += 1; } else if (partTags.Skip(i).Take(cubicPattern.Length).SequenceEqual(cubicPattern)) { Type = SegmentType.Cubic; segments.Add(CreateCurveSegment(i, cubicPattern, partVerts)); i += 2; } else if (partTags.Skip(i).Take(conicVirtualPattern.Length).SequenceEqual(conicVirtualPattern)) { Type = SegmentType.Conic; var count = 0; var cs = CreateCurveSegment(i, conicVirtualPattern, partVerts); i += 3; for (var j = i + 1; j < partTags.Count; j++) { cs.Vertices.Add(partVerts[j]); if (partTags[j].Equals(0)) { continue; } count = j; break; } //If count = 0 it is the last segment of the curve. We need to add the first vertex in the list to the segment and leave it as it is. if (!count.Equals(0)) { i = count - 1; } else { cs.Vertices.Add(partVerts[0]); } //Create "on" points between two successive "off points. CreateOnPointsAndAddToList(cs.Vertices); segments.Add(cs); } else { //Is needed only for "closed" CurveParts. var lastSegment = new List <byte>(); lastSegment.AddRange(partTags.Skip(i).Take(partTags.Count - i)); lastSegment.Add(partTags[0]); if (lastSegment.SequenceEqual(conicPattern)) { segments.Add(CreateCurveSegment(i, conicPattern, partVerts[0], partVerts)); } else if (lastSegment.SequenceEqual(cubicPattern)) { segments.Add(CreateCurveSegment(i, cubicPattern, partVerts[0], partVerts)); } else if (lastSegment.SequenceEqual(conicVirtualPattern)) { segments.Add(CreateCurveSegment(i, cubicPattern, partVerts[0], partVerts)); } } } return(segments); }
/// <summary> /// Combines CurveSegments with the same type and adds them to a CurvePart. /// </summary> /// <param name="segments">List of CurveSegments - segments of the same type are combined.</param> /// <param name="part">Curve part to which the combined segments belong.</param> public static void CombineCurveSegmentsAndAddThemToCurvePart(List <CurveSegment> segments, CurvePart part) { //Combines segments that follow each other and have the same interpolation method. for (var i = 0; i < segments.Count; i++) { //Constraint if (i + 1 >= segments.Count) { break; } //Checks whether two successive segments have the same interpolation method, if so combine them. if (segments[i].GetType() == segments[i + 1].GetType()) { foreach (var vertex in segments[i + 1].Vertices) { if (vertex.Equals(segments[i + 1].Vertices[0])) { continue; } segments[i].Vertices.Add(vertex); } segments.RemoveAt(i + 1); //Sets the for loop one step back, to check the "new" CurvePart with its follower. if (i >= 0) { i = i - 1; } } } FixSegments(segments); part.CurveSegments = segments; }
private void Resample() { if (_Resample) { _UpdatePoints = true; _Resample = false; _Parts.Clear(); if (Curve.length > 1) { _MinValue = float.MaxValue; _MaxValue = float.MinValue; float minTime, maxTime; GetTimeBounds(out minTime, out maxTime); int index = -1; CurvePart part = null; double startTime = View.TimeLine.StartVisible; if (startTime < minTime) { startTime = minTime; } double endTime = View.TimeLine.EndVisible; if (endTime > maxTime) { endTime = maxTime; } double stepTime = (endTime - startTime) / View.RenderArea.width; if (stepTime <= 0.0) { _MinValue = 0; _MaxValue = 1; return; } double time = startTime; while (time <= endTime) { float fTime = (float)time; float value = Curve.Evaluate(fTime); _MinValue = Mathf.Min(_MinValue, value); _MaxValue = Mathf.Max(_MaxValue, value); if (value >= View.MinVisibleValue && value <= View.MaxVisibleValue) { index++; Vector2 sample = GetPoint(fTime, value, false); if (part == null) { part = CreatePart(index); } if (_Samples.Count > index) { _Samples[index] = sample; } else { _Samples.Add(sample); } part.Count++; } else if (part != null) { part = null; index++; if (_Samples.Count > index) { _Samples[index] = _Samples[index - 1]; } else { _Samples.Add(_Samples[index - 1]); } } time += stepTime; } } else { _MinValue = 0; _MaxValue = 1; } } }
public static void CurvePartVertice(CurvePart cp, int j, FTVector[] orgPointCoords, List <float3> partVerts) { var vert = new float3(orgPointCoords[j].X.Value, orgPointCoords[j].Y.Value, 0); partVerts.Add(vert); }