private int Area(ContourData a, ContourData b) { float areaA = (a.maxPoint.x - a.minPoint.x) * (a.maxPoint.y - a.minPoint.y); float areaB = (b.maxPoint.x - b.minPoint.x) * (b.maxPoint.y - b.minPoint.y); if (areaA < areaB) { return(-1); } if (areaB < areaA) { return(1); } return(0); }
private Vector2[] RenderContourPoints(ContourData contour, int resolution, bool initialTest) { // var baseLine = new VectorLine("base", contour.points, null, 2.0f, LineType.Continuous); // baseLine.depth = 1; // baseLine.Draw(); // var col = new Color[contour.points.Length]; // for (var i = 0; i < col.Length; i++) { // col[i] = (contour.onCurves[i] == true)? Color.green : Color.red; // } // var pts = new VectorPoints("points", contour.points, col, null, 15.0f); // pts.Draw(); _resolution = resolution; var originalPoints = contour.points; var onCurves = contour.onCurves; int numberOfPoints = originalPoints.Length; var points = new List<Vector2>(numberOfPoints * resolution); float baseDist = (_unitsPerEm / 2) / (float)(resolution + 2); Vector2 p0, p1, p2, p = Vector2.zero; int iAdd = 0; int i0 = 0; while (i0 < numberOfPoints) { int i1 = i0 + 1; if (i1 == numberOfPoints) i1 = 0; if (onCurves[i0]) { // Straight line (two on-curve points in a row) if (onCurves[i1]) { points.Add (originalPoints[i0]); i0++; continue; } else { // Curve that starts with an on-curve point, and might end with one int i2 = i1 + 1; if (i2 == numberOfPoints) i2 = 0; p0 = originalPoints[i0]; p1 = originalPoints[i1]; if (onCurves[i2]) { p2 = originalPoints[i2]; } else { p2 = (originalPoints[i1] + originalPoints[i2]) / 2; } iAdd = 2; } } else { // Curve that doesn't start with an on-curve point, but might end with one int ip = i0 - 1; if (ip == -1) ip = numberOfPoints-1; p0 = (originalPoints[ip] + originalPoints[i0]) / 2; p1 = originalPoints[i0]; if (onCurves[i1]) { p2 = originalPoints[i1]; } else { p2 = (originalPoints[i0] + originalPoints[i1]) / 2; } iAdd = 1; } // Limit subdivision for short segments int thisRes; float segmentLength = (p0 - p2).magnitude; if (initialTest || segmentLength < baseDist) { thisRes = 1; } else { thisRes = (int)(segmentLength / baseDist); } // Do Bezier curve float t = 0.0f; float tAdd = 1.0f / (thisRes+1); for (int i = 0; i <= thisRes; i++) { float ti = (1.0f-t); p.x = ti*ti*p0.x + 2*t*ti*p1.x + t*t*p2.x; p.y = ti*ti*p0.y + 2*t*ti*p1.y + t*t*p2.y; points.Add (p); t += tAdd; } i0 += iAdd; } // Un-subdivide subsequent segments that are nearly a straight line anyway if (!initialTest) { int pCount = points.Count; baseDist *= 4; for (int i = 0; i < pCount;) { int ia = i - 1; if (ia < 0) ia = pCount - 1; int ib = i + 1; if (ib > pCount - 1) ib = 0; p0 = points[ia]; p1 = points[i]; p2 = points[ib]; if ((p0 - p2).magnitude > baseDist && LineToPointSqrDistance (ref p0, ref p2, ref p1) < .1f) { points.RemoveAt (i); pCount--; } else { i++; } } } // if (points.Count > 1 && !initialTest) { // var renderedLine = new VectorLine("render", points.ToArray(), Color.cyan, null, 5.0f, LineType.Continuous); // renderedLine.Draw(); // } var pointsArray = points.ToArray(); if (_reverse) { Array.Reverse (pointsArray); } return pointsArray; }
private int Area(ContourData a, ContourData b) { float areaA = (a.maxPoint.x - a.minPoint.x) * (a.maxPoint.y - a.minPoint.y); float areaB = (b.maxPoint.x - b.minPoint.x) * (b.maxPoint.y - b.minPoint.y); if (areaA < areaB) return -1; if (areaB < areaA) return 1; return 0; }
private Vector2[] RenderContourPoints(ContourData contour, int resolution, bool initialTest) { // var baseLine = new VectorLine("base", contour.points, null, 2.0f, LineType.Continuous); // baseLine.depth = 1; // baseLine.Draw(); // var col = new Color[contour.points.Length]; // for (var i = 0; i < col.Length; i++) { // col[i] = (contour.onCurves[i] == true)? Color.green : Color.red; // } // var pts = new VectorPoints("points", contour.points, col, null, 15.0f); // pts.Draw(); _resolution = resolution; var originalPoints = contour.points; var onCurves = contour.onCurves; int numberOfPoints = originalPoints.Length; var points = new List <Vector2>(numberOfPoints * resolution); float baseDist = (_unitsPerEm / 2) / (float)(resolution + 2); Vector2 p0, p1, p2, p = Vector2.zero; int iAdd = 0; int i0 = 0; while (i0 < numberOfPoints) { int i1 = i0 + 1; if (i1 == numberOfPoints) { i1 = 0; } if (onCurves[i0]) { // Straight line (two on-curve points in a row) if (onCurves[i1]) { points.Add(originalPoints[i0]); i0++; continue; } else { // Curve that starts with an on-curve point, and might end with one int i2 = i1 + 1; if (i2 == numberOfPoints) { i2 = 0; } p0 = originalPoints[i0]; p1 = originalPoints[i1]; if (onCurves[i2]) { p2 = originalPoints[i2]; } else { p2 = (originalPoints[i1] + originalPoints[i2]) / 2; } iAdd = 2; } } else { // Curve that doesn't start with an on-curve point, but might end with one int ip = i0 - 1; if (ip == -1) { ip = numberOfPoints - 1; } p0 = (originalPoints[ip] + originalPoints[i0]) / 2; p1 = originalPoints[i0]; if (onCurves[i1]) { p2 = originalPoints[i1]; } else { p2 = (originalPoints[i0] + originalPoints[i1]) / 2; } iAdd = 1; } // Limit subdivision for short segments int thisRes; float segmentLength = (p0 - p2).magnitude; if (initialTest || segmentLength < baseDist) { thisRes = 1; } else { thisRes = (int)(segmentLength / baseDist); } // Do Bezier curve float t = 0.0f; float tAdd = 1.0f / (thisRes + 1); for (int i = 0; i <= thisRes; i++) { float ti = (1.0f - t); p.x = ti * ti * p0.x + 2 * t * ti * p1.x + t * t * p2.x; p.y = ti * ti * p0.y + 2 * t * ti * p1.y + t * t * p2.y; points.Add(p); t += tAdd; } i0 += iAdd; } // Un-subdivide subsequent segments that are nearly a straight line anyway if (!initialTest) { int pCount = points.Count; baseDist *= 4; for (int i = 0; i < pCount;) { int ia = i - 1; if (ia < 0) { ia = pCount - 1; } int ib = i + 1; if (ib > pCount - 1) { ib = 0; } p0 = points[ia]; p1 = points[i]; p2 = points[ib]; if ((p0 - p2).magnitude > baseDist && LineToPointSqrDistance(ref p0, ref p2, ref p1) < .1f) { points.RemoveAt(i); pCount--; } else { i++; } } } // if (points.Count > 1 && !initialTest) { // var renderedLine = new VectorLine("render", points.ToArray(), Color.cyan, null, 5.0f, LineType.Continuous); // renderedLine.Draw(); // } var pointsArray = points.ToArray(); if (_reverse) { Array.Reverse(pointsArray); } return(pointsArray); }