JavaScriptで曲線、直線の判断

[16089]JavaScriptで曲線、直線の判断 投稿者:SH 投稿日:2007/05/17 18:28:18
はじめまして。

JavaScriptで、Illustratorのオブジェクトが曲線か直線かの判断をしたいのですが、方法がわかりません。何かプロパティを持っているのかと思い、いろいろと調べてみましたが、それらしいものは見つかりませんでした。
曲線と直線を区別する方法はないでしょうか。
よろしくお願いします。
Re: JavaScriptで曲線、直線の判断 投稿者:倉田タカシ 投稿日:2007/05/17 19:30:19
各アンカーポイントからハンドルが伸びているかどうかで判別するのが、一番簡単だと思います。
ハンドルの先端の座標が、PathPointオブジェクトのleftDirectionとrightDirectionという2つのプロパティで取得できますので、これらがポイント自体の座標と同じなら、ハンドルは伸びていないということになります。

始点←終点方向のハンドルの座標:leftDirection
始点→終点方向のハンドルの座標:rightDirection

です。

詳しくはリファレンスでご確認ください。
Re: JavaScriptで曲線、直線の判断 投稿者:SH 投稿日:2007/05/18 10:55:18
倉田タカシ様、ありがとうございます。

教えていただいたとおり、anchor、LeftDirection、RightDirectionを取得し、それらを比較し、同じなら直線というプログラムを作成し、直線と曲線の判断をすることが出来ました。大変助かりました。ありがとうございました。


以下、ソースになります。

function ChkStraightLine(objPath){

try{
var i;
var pPoint; // パスポイントオブジェクト
var StraightFlg; // 直線フラグ

// 変数初期化
StraightFlg = false;

pPoint = objPath.pathPoints;

// 各アンカーポイントからハンドルが伸びているか
// ハンドルが伸びていなければ直線
for (i=0;i<pPoint.length;i++) {
with(pPoint[i]){
// アンカー座標、ハンドルの座標が同じ座標の場合は、直線と判断
if (anchor[0] == leftDirection[0]
&& anchor[1] == leftDirection[1]
&& anchor[0] == rightDirection[0]
&& anchor[1] == rightDirection[1]) {
StraightFlg = true;
} else {
return false;
}
}
}
return StraightFlg;

}catch(e){
alert(e.description);
}
}

もっとここをこうした方が良いなど、ありましたらご指摘下さい。

どうもありがとうございました。
Re: JavaScriptで曲線、直線の判断 投稿者:sgr 投稿日:2007/05/19 18:51:59
attached imageそれだと折れ線もtrueを返しますが良いのでしょうか?
あと、添付図のような線も、ハンドルは伸びてますが、見た目は直線です。
こういうのも直線と判断させようとすると、もっと面倒な処理が必要になります。
(「パスのアウトライン」で作った図形などに、よくこんな余計なハンドルが付きます。)
Re: JavaScriptで曲線、直線の判断 投稿者:倉田タカシ 投稿日:2007/05/19 23:00:25
たしかにsgrさんのおっしゃる通りですね。中途半端なアドバイスをしてしまいました、すみません。

折れ線については、SHさんのご質問にも特に書かれていなかったので、単純に各ポイントの間が直線で結ばれているかどうかだけが問題なのかと思っていました。

いずれにしても、曲線かどうかの判別は、ポイント単位ではなく、区間単位で行う方がいいと思います。
Re: JavaScriptで曲線、直線の判断 投稿者:倉田タカシ 投稿日:2007/05/20 00:32:58
SHさんの書かれたコードを基に、「全てのポイントが直線で結ばれているかどうかの判定」という前提で試しに自分でも考えてみましたが、どうもうまくいきませんでした。
以下の形だと、ハンドルの先端がパスに重なっていても、傾きの数値が小数点以下3桁のあたりで一致せず、falseが返されてしまいます。これを丸めてしまってもいいものかどうか、迷います。
もっとうまい方法があるような気がするんですが…

function ChkStraightLine(objPath){
try{
var i;
var pPoint; // パスポイントオブジェクト
var StraightFlg; // 直線フラグ

// 変数初期化
StraightFlg = true;

pPoint = objPath.pathPoints;

for( i=0; i<pPoint.length-1; i++ ){
p1 = pPoint[i].anchor ;
p2 = pPoint[i+1].anchor ;
p1h = pPoint[i].rightDirection ;
p2h = pPoint[i+1].leftDirection ;

s = getSlope( p1 , p2 ) ;

if( p1.join("") != p1h.join("") ){
if( getSlope( p1 , p1h ) != s ){ StraightFlg = false }
}

if( p2.join("") != p2h.join("") ){
if( getSlope( p2h , p2 ) != s ){ StraightFlg = false }
}
}
return StraightFlg ;

}catch(e){
alert(e.description);
}
}

// 2点を結ぶ直線の傾きを返す
function getSlope( pa , pb ){
return( (pb[1]-pa[1]) / (pb[0]-pa[0]) ) ;
}
この記事の書き込み元へのリンク (コメントや質問などはこちらへどうぞ)