ログインしてさらにmixiを楽しもう

コメントを投稿して情報交換!
更新通知を受け取って、最新情報をゲット!

VectorScriptコミュの【Script】同一線上の線分結合

  • mixiチェック
  • このエントリーをはてなブックマークに追加
仕事が忙しく久しぶりの投稿となりますが、Sky-blueさんの「整列...」に感激したので、以前(10年くらい前。。。笑)に作成したモノですが、提供致します。

■作った理由
1)VectorWorksの「線分を結合」では同一線上にある平行な線分を結合できない。
2)VectorWorksの「結合/合成」ツールでは延長され2つの線分のままである。
要するに、VectorWorksでは、一度、線分を切り欠いたり切断すると、2度と1つの線分には戻せないため、それを解決するツールです。

■使い方
1)「同一線上の線分結合」ツールを選択
2)一つ目の線分をクリック
3)上記2)と同一線上にある平行な線分を次にクリック
結果:2つの線分が繋がり1つの線分オブジェクトとなります。

■インストール方法
1)通常のスクリプトと同様に下記のSCRIPTをエディタの「コマンド編集...」にコピベしていれます。
2)必ず添付画像の様にフィールドフォーマットの設定を「パラメータ...」に手入力して下さい。(添付画像「フィールドフォーマットの設定」参照)
3)可能であれば、添付画像の様に「プロパティ...」から説明分とアイコンを設定します。(添付画像「プロパティ(ツール)」参照 アイコンは、MacOS9で昔作ったので、リソース画像が行方不明。。。お好みで、ご自由に自作して下さい。)

■このツールの設定ダイアログの説明(添付画像「プロパティ」):興味ある方のみお読み下さい。
【許容角度】
2つの線分が微妙に平行でなくても、無理矢理始点と終点を結ぶ1つの線にしてしまう際の許容限界角度差を手動で設定できますが、デフォルト値はもちろんですが0度に設定してあります。
他のCADから持ってきたデータ等では、CAD自体の浮動小数点の精度差があるため、0度では上手く作動しないケースでの対処ですが、基本的には0度で作動しない2つの直線は、同一線上でないか平行でない線分であるため無理矢理結合すると加重平均された線分になってしまいます。(0度以外はお勧めしません!)
【許容距離】
これは、角度は全く同じであっても、微妙に同一線上にない(ズレている)場合の線分同士を無理矢理結合する場合の許容平行距離(単位:mm)ですが、これもデフォルト値の0mmがお勧めです。
【垂直・水平線は保持】
強制的に、垂直(90度)や水平(0度)の線分は、絶対に保持させるため最初にクリックした線分の方の角度に強制的に合わせるラジオボタンです。
上記の設定を0以外に設定した場合に角度を加重平均させないための保険ですので、基本は常にチェックを入れておく事をお勧めします。

IF文とGOTOだらけで、かなり見た目に美しくないですが、取りあえず動きます。
誰か、綺麗にして頂けるとうれしい位です。。。(笑)
遠い昔に作ったので自分でも関数名やら何故そうしたのか忘れました。。。

==========SCRIPT==========
{■同一線上の線分結合(ツール用スクリプト)}
procedure test;
LABEL 1 , 2 , 3 , 4 ;
VAR
h1 , h2 , h3 , H , Lh1 , ALH : HANDLE ;
pX1,pX2,pY1,pY2,
aX1,aX2,aY1,aY2,
bX1,bX2,bY1,bY2,
aDx,aDy,bDx,bDy,
aA , aB ,
Deg1 , Deg2 , Deg3 ,
TotalDeg1 , TotalDeg2 , TotalDeg3 ,
KyoyoDeg, KyoyoDis , DisX , DisY : REAL ;
OT1,OT2 : INTEGER ;
Hoji , Muki : BOOLEAN ;
Lh1Name , ALHName : STRING ;

BEGIN

ALH := ActLayer ;
ALHName := GetLName( ALH ) ;
Muki := TRUE ;
SetCursor ( SmCrossC );
GetPt ( pX1 , pY1 ) ;
h1 := PickObject ( pX1 , pY1 ) ;
Lh1 := GetLayer( h1 ) ;
Lh1Name := GetLName( Lh1 ) ;
GetPt ( pX2 , pY2 ) ;
h2 := PickObject ( pX2 , pY2 ) ;
OT1 := Eval ( h1 ,(T)) ;
OT2 := Eval ( h2 ,(T)) ;

Layer( Lh1Name );

IF ( pX1 > pX2 ) OR (( pX1 = pX2 ) AND ( pY1 > pY2 )) THEN
BEGIN
H := h1 ;
h1 := h2 ;
h2 := H ;
Muki := False ;
END ;

IF (OT1<>2) AND (OT2<>2) THEN
BEGIN
GOTO 4 ;
END ;

GetSegPt1 ( h1 , aX1 , aY1 ) ;
GetSegPt2 ( h1 , aX2 , aY2 ) ;

GetSegPt1 ( h2 , bX1 , bY1 ) ;
GetSegPt2 ( h2 , bX2 , bY2 ) ;

IF ( aX1 > aX2 ) OR (( aX1 = aX2 ) AND ( aY1 > aY2 )) THEN
BEGIN
SetSegPt1(h1,aX2,aY2);
SetSegPt2(h1,aX1,aY1);
GetSegPt1 ( h1 , aX1 , aY1 ) ;
GetSegPt2 ( h1 , aX2 , aY2 ) ;
END ;
IF ( bX1 > bX2 ) OR (( bX1 = bX2 ) AND ( bY1 > bY2 )) THEN
BEGIN
SetSegPt1(h2,bX2,bY2);
SetSegPt2(h2,bX1,bY1);
GetSegPt1 ( h2 , bX1 , bY1 ) ;
GetSegPt2 ( h2 , bX2 , bY2 ) ;
END ;

aDx := (aX2-aX1) ;
aDy := (aY2-aY1) ;
bDx := (bX2-bX1) ;
bDy := (bY2-bY1) ;
aA := aDy/aDx ;
aB := aY1-aA*aX1 ;
Deg1 := HAngle ( h1 ) ;
Deg2 := HAngle ( h2 ) ;
MoveTo ( aX1 , aY1 ) ;
LineTo ( bX2 , bY2 ) ;
h3 := LNewObj ;
Deg3 := HAngle ( h3 ) ;
DelObject( h3 ) ;
DisX := Abs(bX2-aX1) ;
DisY := Abs(bY2-aY1) ;

TotalDeg1 := Abs(Deg1-Deg3);
TotalDeg2 := Abs(Deg2-Deg3) ;
TotalDeg3 := Abs(Deg2-Deg1);

IF (PHoji=TRUE) THEN
BEGIN
GOTO 1 ;
END ;
{=== これ以降は保持がチェックされていない場合 ===}

IF (TotalDeg1<= PKyoyoDeg) AND (TotalDeg2<= PKyoyoDeg) AND (TotalDeg3<= PKyoyoDeg) THEN
BEGIN
GOTO 3 ;
END ;
BEGIN
GOTO 4 ;
END ;
{=================================}

1 : {=== 保持がチェックされた場合 ===}
IF (Muki=False) THEN
GOTO 2 ;

IF (aDx=0) AND (DisX<=PKyoyoDis) THEN
BEGIN
bX2 := aX1 ;
GOTO 3 ;
END ;

IF (aDy=0) AND (DisY<=PKyoyoDis) THEN
BEGIN
bY2 := aY1 ;
GOTO 3 ;
END ;

IF (bDx=0) AND (aDx<>0) AND (DisX<=PKyoyoDis) THEN
BEGIN
aX1 := bX2 ;
GOTO 3 ;
END ;

IF (bDy=0) AND (aDy<>0) AND (DisY<=PKyoyoDis) THEN
BEGIN
aY1 := bY2 ;
GOTO 3 ;
END ;

IF (TotalDeg1<= PKyoyoDeg) AND (TotalDeg2<= PKyoyoDeg) AND (TotalDeg3<= PKyoyoDeg) THEN
BEGIN
GOTO 3 ;
END ;
BEGIN
GOTO 4 ;
END ;

2 : {=== 保持がチェックされ更に選択順の向きが逆の場合 ===}

IF (bDx=0) AND (DisX<=PKyoyoDis) THEN
BEGIN
aX1 := bX2 ;
GOTO 3 ;
END ;

IF (bDy=0) AND (DisY<=PKyoyoDis) THEN
BEGIN
aY1 := bY2 ;
GOTO 3 ;
END ;

IF (aDx=0) AND (bDx<>0) AND (DisX<=PKyoyoDis) THEN
BEGIN
bX2 := aX1 ;
GOTO 3 ;
END ;

IF (aDy=0) AND (bDy<>0) AND (DisY<=PKyoyoDis) THEN
BEGIN
bY2 := aY1 ;
GOTO 3 ;
END ;

IF (TotalDeg1<= PKyoyoDeg) AND (TotalDeg2<= PKyoyoDeg) AND (TotalDeg3<= PKyoyoDeg) THEN
BEGIN
GOTO 3 ;
END ;
BEGIN
GOTO 4 ;
END ;

3 : {=== 結合の処理 ===}
SetSegPT1 ( h1 , aX1 , aY1 ) ;
SetSegPT2 ( h1 , bX2 , bY2 ) ;
DelObject ( h2 ) ;

4 :
Layer( ALHName );
END;
run ( test);

コメント(2)

僕も以前から作りたいとは思っていたのですが、本当にありがたいです。
是非、利用させてください。
sky-blue さんもおっしゃっていますが、1本にまとめたいときは良くあります。

許容値の設定はむずかしいと思います。
最近、多角形を四角形に変換するスクリプトを Ver. 2008 以降に合わせて作ったのですが、結構面倒なんですよね。

そういえば、「VectorWorksClub北海道」のScript相談室で「重なった直線の検出と処理」が最近ものすごい議論が行われていましたが、難しくて着いていけませんでした。

ログインすると、みんなのコメントがもっと見れるよ

mixiユーザー
ログインしてコメントしよう!

VectorScript 更新情報

VectorScriptのメンバーはこんなコミュニティにも参加しています

星印の数は、共通して参加しているメンバーが多いほど増えます。

人気コミュニティランキング