Beispiel #1
0
        private bool Push(Vector3[] targets, Vector3[] opposites, ref List <int> targetIndices, ref List <int> oppositeIndices, bool isLeft)
        {
            // 進めた際にFunnnelの反対側の頂点リストを追い越さないかを調べる
            var crossedIndex = IsCrossedOppositeVertices(targets, opposites, targetIndices, oppositeIndices);

            if (crossedIndex > 0 && crossedIndex < targets.Count() - 1)
            {
                // 追い越した場合は現在のFunnelの先端を記録する
                apexes.Add(apex);

                // Funnelの先端を追い越されたほうの頂点にセットする
                apex = new Apex(crossedIndex, opposites[crossedIndex], !isLeft);

                // Funnelの両サイドのインデックスをセットする
                var nextIndex = apex.Index + 1;
                while (opposites.Length > nextIndex)
                {
                    // Funnelの先端と同じ座標にいる場合は座標が変わるまでインデックスを進める
                    if (!apex.Position.Equals(opposites[nextIndex]))
                    {
                        break;
                    }

                    nextIndex++;
                }

                targetIndices = new List <int>()
                {
                    nextIndex
                };
                oppositeIndices = new List <int> {
                    nextIndex
                };

                // 進めることができなかったのでFalseを返す
                return(false);
            }

            // 進めることができる

            var next = targetIndices.Last() + 1;

            // 進めた場合Funnelが絞られるかを調べる
            if (IsTightened(targets, opposites, targetIndices, oppositeIndices))
            {
                // Funnelが絞られるので一度頂点リストをクリアする
                targetIndices.Clear();
            }

            // 新しい頂点として追加
            targetIndices.Add(next);

            // 進めることができたのでTrueを返す
            return(true);
        }
Beispiel #2
0
        public Path FindPath(IEnumerable <Triangle> triangles)
        {
            // 三角形の数が2つ未満の場合は計算できないので空のパスを返す
            if (triangles.Count() < 2)
            {
                return(null);
            }

            // 与えられた三角形リストから3次元における左右の頂点配列を作成する
            if (!CreateVertices3D(triangles))
            {
                return(null);
            }

            // 3次元における頂点配列を2次元における頂点配列にコピーする
            CopyVertices3DToVertices2D();

            // コピーした頂点配列を2次元に変換する
            ConvertTo2D();

            // XY平面上に変換する
            ConvertToXYPlane();

            // Funnelの先端を始点にセットする (右側も左側も同じなのでどっちを採用してももいい。ここでは左側を採用)
            apex = new Apex(0, leftVertices2d[0], true);

            // Funnelの左側の頂点リストに最初の頂点を追加する(先端から1つ進んだとこから開始する)
            leftIndices.Add(1);

            // Funnelの右側の頂点リストに最初の頂点を追加する(先端から1つ進んだとこから開始する)
            rightIndices.Add(1);

            // 終点にたどり着くまでFunnelに頂点を追加していく
            while (UpdateFunnel())
            {
            }

            // 終点にたどり着いたら現在のFunnelの先端を追加する
            apexes.Add(apex);

            // 終点を追加する(ここも左、右側のどちらを採用してもOK)
            apexes.Add(new Apex(leftVertices2d.Length - 1, leftVertices2d.Last(), true));

            // 共有辺との交点()を求め、最終的なパスを計算する
            var path = MakePath();

            return(path);
        }