示例#1
0
        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));
        }
示例#2
0
 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);
 }
示例#3
0
        // 接合面とボーンの交差判定
        // ボーンのひとつの端点は内で逆の端点は外
        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);
        }
示例#4
0
        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);
        }