public void IsPointInPolygonTest() { var path = new List <PointF>() { new PointF(0, 0), new PointF(5, 5), new PointF(10, 0), new PointF(10, 10), new PointF(0, 10), }; Assert.IsTrue(FMath.IsPointInPolygon(new PointF(5, 7), path)); Assert.IsTrue(FMath.IsPointInPolygon(new PointF(4, 5), path)); Assert.IsTrue(FMath.IsPointInPolygon(new PointF(4, 4), path)); Assert.IsTrue(FMath.IsPointInPolygon(new PointF(7, 4), path)); Assert.IsTrue(FMath.IsPointInPolygon(new PointF(3, 9), path)); Assert.IsFalse(FMath.IsPointInPolygon(new PointF(-1, -1), path)); Assert.IsFalse(FMath.IsPointInPolygon(new PointF(0, 0), path)); Assert.IsFalse(FMath.IsPointInPolygon(new PointF(5, 3), path)); Assert.IsFalse(FMath.IsPointInPolygon(new PointF(-1, 5), path)); Assert.IsFalse(FMath.IsPointInPolygon(new PointF(11, 5), path)); Assert.IsFalse(FMath.IsPointInPolygon(new PointF(5, 11), path)); Assert.IsFalse(FMath.IsPointInPolygon(new PointF(0, 5), path)); Assert.IsFalse(FMath.IsPointInPolygon(new PointF(5, 10.00001f), path)); Assert.IsFalse(FMath.IsPointInPolygon(new PointF(5, 4.9999f), path)); }
Segment GetSegment(List <Segment> segments, Dictionary <string, SegmentMeshInfo> transformDict, PointF point) { for (int i = segments.Count - 1; i >= 0; i--) { var seg = segments[i]; if (seg == null || !transformDict.ContainsKey(seg.name)) { continue; } var transform = transformDict[seg.name]; if (transform == null || transform.arap == null) { continue; } if (FMath.IsPointInPolygon(point, transform.arap.GetPath())) { return(segments[i]); } } return(null); }
// 接合面とボーンの交差判定 // ボーンのひとつの端点は内で逆の端点は外 static Dictionary <BoneAnnotation, CrossBoneSection> GetBoneSectionCrossDict(List <PointF> path, List <CharacterRange> sections, SkeletonAnnotation an) { var crossDict = new Dictionary <BoneAnnotation, CrossBoneSection>(); if (path == null || path.Count <= 0 || an == null || an.bones == null) { return(crossDict); } foreach (var section in sections) { var pts = new List <PointF>(); for (int i = section.First; i < section.First + section.Length; i++) { pts.Add(path[i % path.Count]); } foreach (var b in an.bones) { if (FMath.IsCrossed(b.src.position, b.dst.position, pts)) { bool srcIn = FMath.IsPointInPolygon(b.src.position, path); bool dstIn = FMath.IsPointInPolygon(b.dst.position, path); if (srcIn && !dstIn) { crossDict[b] = new CrossBoneSection(b, section, 1); } if (!srcIn && dstIn) { crossDict[b] = new CrossBoneSection(b, section, -1); } } } } return(crossDict); }
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); }