int GetWindingNumber(ControlPoint p, Glyph glyphData) { ControlPoint p2 = new ControlPoint(p.X + 1000, p.Y); int result = 0; foreach (var contour in glyphData.Contours) { for (int a = contour.Count - 1, b = 0; b < contour.Count; a = b, b++) { ControlPoint pa = contour[a]; ControlPoint pb = contour[b]; if (pa.Y > p.Y && pb.Y < p.Y) { if (pa.X > p.X && pb.X > p.X) { result++; } else if ((pa.X > p.X && pb.X < p.X) || (pa.X < p.X && pb.X > p.X)) { ControlPoint r = p2 - p; ControlPoint s = pb - pa; double t = ControlPoint.VectorProduct((pa - p), s) / ControlPoint.VectorProduct(r, s); double u = ControlPoint.VectorProduct((p - pa), r) / ControlPoint.VectorProduct(s, r); if (t >= 0 && u >= 0 && u <= 1) { result++; } } } else if (pa.Y < p.Y && pb.Y > p.Y) { if (pa.X > p.X && pb.X > p.X) { result--; } else if ((pa.X > p.X && pb.X < p.X) || (pa.X < p.X && pb.X > p.X)) { ControlPoint r = p2 - p; ControlPoint s = pb - pa; double t = ControlPoint.VectorProduct((pa - p), s) / ControlPoint.VectorProduct(r, s); double u = ControlPoint.VectorProduct((p - pa), r) / ControlPoint.VectorProduct(s, r); if (t >= 0 && u >= 0 && u <= 1) { result--; } } } } } return(result); }
void SearchTree(InputGeometry inputGeometry, ref int pointIndex, PolyNode node) { foreach (PolyNode childNode in node.Childs) { int startIndex = pointIndex; foreach (ControlPoint point in childNode.Contour) { inputGeometry.AddPoint(point.X, point.Y); if (pointIndex > startIndex) { inputGeometry.AddSegment(pointIndex - 1, pointIndex); } pointIndex++; } inputGeometry.AddSegment(pointIndex - 1, startIndex); if (childNode.IsHole) { for (int i = 0, j = childNode.Contour.Count - 1, k = childNode.Contour.Count - 2; i < childNode.Contour.Count; k = j, j = i, i++) { ControlPoint a1 = childNode.Contour[k]; ControlPoint a2 = childNode.Contour[j]; ControlPoint a3 = childNode.Contour[i]; if (ControlPoint.VectorProduct(a2 - a1, a3 - a1) < 0) { ControlPoint c = ((a1 + a3) / 2) - a2; double x = 2; ControlPoint hole; do { x /= 2; hole = a2 + (c * x); } while (!IsInside(childNode, hole)); inputGeometry.AddHole(hole.X, hole.Y); break; } } } SearchTree(inputGeometry, ref pointIndex, childNode); } }