static float GetSectionWidth(List <PointF> path, Tuple <CharacterRange, CharacterRange> curves, BoneAnnotation b) { float width = 0; int cnt = Math.Min(curves.Item1.Length, curves.Item2.Length); for (int i = 0; i < cnt; i++) { int idx1 = curves.Item1.First + curves.Item1.Length - 1 - i; int idx2 = curves.Item2.First + i; while (idx1 < 0) { idx1 += path.Count; } while (idx2 < 0) { idx2 += path.Count; } PointF pt1 = path[idx1 % path.Count]; PointF pt2 = path[idx2 % path.Count]; PointF pt = new PointF(pt2.X - pt1.X + b.src.position.X, pt2.Y - pt1.Y + b.src.position.Y); width += FMath.GetDistanceToLine(pt, b.src.position, b.dst.position, false); } width /= cnt; return(width); }
public BoneAnnotation GetNearestBone(PointF point, int threshold, Matrix transform) { float minDist = threshold; BoneAnnotation bone = null; for (int i = 0; i < bones.Count; i++) { PointF[] bonePts = new[] { bones[i].src.position, bones[i].dst.position }; transform.TransformPoints(bonePts); float dist = FMath.GetDistanceToLine(point, bonePts[0], bonePts[1]); if (dist < minDist) { minDist = dist; bone = bones[i]; } } return(bone); }
public static List <PointF> CreateMeshPoints(List <PointF> path, int gridSize, int threhold) { if (path == null || path.Count <= 2) { return(new List <PointF>()); } // パス var points = new List <PointF>(path); float minx = path.Select(p => p.X).Min(); float maxx = path.Select(p => p.X).Max(); float miny = path.Select(p => p.Y).Min(); float maxy = path.Select(p => p.Y).Max(); // 外側 for (int i = 0; i < path.Count; i++) { PointF pt1 = path[i]; PointF pt2 = path[(i + 1) % path.Count]; float cx = (pt1.X + pt2.X) * 0.5f; float cy = (pt1.Y + pt2.Y) * 0.5f; float vx = pt2.Y - pt1.Y; float vy = pt1.X - pt2.X; float len = (float)Math.Sqrt(vx * vx + vy * vy); if (len <= 1e-4f) { continue; } vx /= len; vy /= len; PointF pt = new PointF(cx + vx, cy + vy); float shift = 5; if (FMath.IsPointInPolygon(pt, path)) { // (vx, vy) がパスの内側を向いている points.Add(new PointF(cx - vx * shift, cy - vy * shift)); } else { points.Add(new PointF(cx + vx * shift, cy + vy * shift)); } } // 内側 for (float y = miny + gridSize; y < maxy; y += gridSize) { for (float x = minx + gridSize; x < maxx; x += gridSize) { var pt = new PointF(x, y); if (!FMath.IsPointInPolygon(pt, path)) { continue; } float mindist = float.MaxValue; for (int i = 0; i < path.Count; i++) { float dist = FMath.GetDistanceToLine(pt, path[i], path[(i + 1) % path.Count]); if (mindist > dist) { mindist = dist; } } if (mindist <= threhold) { continue; } points.Add(pt); } } return(points); }