1

したがって、パスを形成するポイント (x, y) の配列があります。周囲のポリゴンのポイントを計算する必要があります。基本的CGPathCreateCopyByStrokingPathに、iOS に精通している場合。残念ながら、ObjC はオプションではありません。Javascript、PHPなどで実装する必要があります。

    -------
    |  |  |
    |  |  |
    \  \  \
     \  \  \
      \  \  \
       \  \  \
        \  \  \-----------
         \  \----------- |
          \---------------

悪いアスキー アートをお詫びします。

私は Javascript で半作業バージョンを持っていますが、コーナーに問題があります。

        function pathToPoly(points) {
            var numOfPoints = points.length;

            var fullPath = [];
            var leftPaths = [];
            var rightPaths = [];

            var pad = 20;

            for(var i=0; i<numOfPoints-1; i++) {
                var pointA = points[i];
                var pointB = points[i+1];

                var slope = (pointB.Y - pointA.Y) / (pointB.X - pointA.X);
                var inverseSlope = -1 / slope;
                var inverseAngle = Math.atan(inverseSlope);

                if(inverseAngle < 0) {
                    leftPaths.push({
                        X1: pointA.X - pad * Math.cos(inverseAngle),
                        Y1: pointA.Y - pad * Math.sin(inverseAngle),
                        X2: pointB.X - pad * Math.cos(inverseAngle),
                        Y2: pointB.Y - pad * Math.sin(inverseAngle)
                    });

                    rightPaths.push({
                        X1: pointA.X + pad * Math.cos(inverseAngle),
                        Y1: pointA.Y + pad * Math.sin(inverseAngle),
                        X2: pointB.X + pad * Math.cos(inverseAngle),
                        Y2: pointB.Y + pad * Math.sin(inverseAngle)
                    });
                } else {
                    rightPaths.push({
                        X1: pointA.X - pad * Math.cos(inverseAngle),
                        Y1: pointA.Y - pad * Math.sin(inverseAngle),
                        X2: pointB.X - pad * Math.cos(inverseAngle),
                        Y2: pointB.Y - pad * Math.sin(inverseAngle)
                    });

                    leftPaths.push({
                        X1: pointA.X + pad * Math.cos(inverseAngle),
                        Y1: pointA.Y + pad * Math.sin(inverseAngle),
                        X2: pointB.X + pad * Math.cos(inverseAngle),
                        Y2: pointB.Y + pad * Math.sin(inverseAngle)
                    });
                }

                if(drawSides) {
                    var leftSide = leftPaths[i];
                    var rightSide = rightPaths[i];

                    context.beginPath();

                    context.moveTo(leftSide.X1, leftSide.Y1);
                    context.lineTo(leftSide.X2, leftSide.Y2);

                    context.lineWidth = 1;
                    context.strokeStyle = 'yellow';
                    context.stroke();

                    context.beginPath();

                    context.moveTo(rightSide.X1, rightSide.Y1);
                    context.lineTo(rightSide.X2, rightSide.Y2);

                    context.lineWidth = 1;
                    context.strokeStyle = 'cyan';
                    context.stroke();
                }
            }

            for(var i=0; i<numOfPoints-1; i++) {
                var line1 = leftPaths[i];
                var line2 = leftPaths[i+1];

                fullPath.push({
                    X: line1.X1,
                    Y: line1.Y1
                });
                fullPath.push({
                    X: line1.X2,
                    Y: line1.Y2,
                });

                if(line2) {
                    fullPath.push({
                        X: line2.X1,
                        Y: line2.Y1,
                    });
                }
            }

            fullPath.push({
                X: leftPaths[numOfPoints-2].X2,
                Y: leftPaths[numOfPoints-2].Y2
            });

            for(var i=numOfPoints-2; i>=0; i--) {
                var line1 = rightPaths[i];
                var line2 = rightPaths[i-1];

                fullPath.push({
                    X: line1.X2,
                    Y: line1.Y2
                });

                fullPath.push({
                    X: line1.X1,
                    Y: line1.Y1,
                });
                if(line2) {
                    fullPath.push({
                        X: line2.X2,
                        Y: line2.Y2,
                    });
                }
            }

            fullPath.push({
                X: rightPaths[0].X1,
                Y: rightPaths[0].Y1
            });

            return fullPath;
        }

このコードは、すべてのセグメントの両側に平行線を描画し、それらを接続します。しかし、順番に、私のメソッドは無効なポリゴンを作成します。側面が「交換」され、「反転」領域が生成されます。面積を計算できることは、私のアプリケーションにとって非常に重要です。

例 (評判が低すぎて画像を投稿できません): 青は正常に機能しますが、赤は失敗します (右下がどのように回転し、左右が入れ替わるかに注目してください)。

![example](http://www.originalfunction.com/stackoverflow_16590082-1.png)

助言がありますか?

4

2 に答える 2

0

(小さなサンプルに基づいて)線が鋭角に曲がる場合にのみ失敗するように見えますが、正しいですか?

atan(slope)アルゴリズムを徹底的に調べたわけではありませんが、知識に基づいた推測です: forには 2 つの正しい答えがあり、javascriptatan()関数が期待する答えを返さない可能性があるという事実を考慮したかどうか疑問に思います。 (180 度オフ)?

atan2(y, x)を使用できれば、このあいまいさが解消されます。

于 2013-05-16T20:14:40.443 に答える