研究開発

ブロックを積む(10)

第10章 マウスクリックによる描画

VectorScriptには、ユーザが2D基準点を打つように、直線を引くように、四角形を描くように、マウスクリックの座標を取得できる手続きを用意しています。

例えば、2D基準点を打つようなマウスクリックを拾うことのできる、

手続きGetPt(VAR pX, pY : REAL);

を使うことで、ブロックを書類のどこから描くかを決めることができます。

PROCEDURE sample;
LABEL
9999;
VAR
pX, pY : REAL;
iX, iY : INTEGER;
rX, rY, rZ : REAL;
ii, jj : INTEGER;

BEGIN
IF NOT YNDialog( 'スクリプトを実行しますか?' ) THEN
BEGIN
GOTO 9999;
END;

GetPt( pX, pY );

iX := IntDialog( '横方向のブロック数?', '9' );
IF DidCancel OR ( ix = 0 ) THEN
BEGIN
GOTO 9999;
END;

iY := IntDialog( '縦方向のブロック数?', '5' );
IF DidCancel OR ( iy = 0 ) THEN
BEGIN
GOTO 9999;
END;

rX := RealDialog( 'ブロックのx方向の長さは?', '50' );
IF DidCancel OR ( rX = 0 ) THEN
BEGIN
GOTO 9999;
END;

rY := RealDialog( 'ブロックのy方向の長さは?', '30' );
IF DidCancel OR ( rY = 0 ) THEN
BEGIN
GOTO 9999;
END;

rZ := RealDialog( 'ブロックのz方向の長さは?', '30' );
IF DidCancel OR ( rZ = 0 ) THEN
BEGIN
GOTO 9999;
END;

FOR jj := 0 TO iy-1 DO
BEGIN
FOR ii := jj TO iX-1 DO
BEGIN
BeginXtrd( 0+jj*rZ, rZ+jj*rZ );
Rect( pX+ii*rX, pY, pX+rX+ii*rX, pY+rY );
IF ( jj MOD 2 = 0 ) AND ( ii MOD 2 <> 0 ) THEN
BEGIN
SetFillBack( LNewObj, 39321, 26214, 13107 );
END
ELSE IF ( jj MOD 2 <> 0 ) AND ( ii MOD 2 = 0 ) THEN
BEGIN
SetFillBack( LNewObj, 39321, 26214, 13107 );
END;
EndXtrd;
END;
END;

AlrtDialog( '計算が終了しました。' );
9999:
END;
Run( sample );

つぎに、 直線を引くようなマウスクリックを拾うことのできる、

手続きGetLine(VAR p1X, p1Y, p2X, p2Y : REAL);
手続きHRotate(h : HANDLE; centerX, centerY : REAL; rotationAngle : REAL);

を使って、四角形の位置と角度を変更してみましょう。

2点の座標から、計算による角度算出も可能ですが、

手続きMoveTo(pX, pY : REAL);
手続きLineTo(pX, pY : REAL);
関数HAngle(h : HANDLE):REAL;

を使って直線を引いてしまって、その図形から角度を取得するなんてことも可能です。

描いた直線は、

手続きDelObject(h : HANDLE);

を使って消すのをお忘れなく。

PROCEDURE sample;
LABEL
9999;
VAR
p1X, p1Y, p2X, p2Y : REAL;
rr : REAL;
iX, iY : INTEGER;
rX, rY, rZ : REAL;
ii, jj : INTEGER;

BEGIN
IF NOT YNDialog( 'スクリプトを実行しますか?' ) THEN
BEGIN
GOTO 9999;
END;

GetLine( p1X, p1Y, p2X, p2Y );
MoveTo( p1X, p1Y );
LineTo( p2X, p2Y );
rr := HAngle( LNewObj );
DelObject( LNewObj );

iX := IntDialog( '横方向のブロック数?', '9' );
IF DidCancel OR ( ix = 0 ) THEN
BEGIN
GOTO 9999;
END;

iY := IntDialog( '縦方向のブロック数?', '5' );
IF DidCancel OR ( iy = 0 ) THEN
BEGIN
GOTO 9999;
END;

rX := RealDialog( 'ブロックのx方向の長さは?', '50' );
IF DidCancel OR ( rX = 0 ) THEN
BEGIN
GOTO 9999;
END;

rY := RealDialog( 'ブロックのy方向の長さは?', '30' );
IF DidCancel OR ( rY = 0 ) THEN
BEGIN
GOTO 9999;
END;

rZ := RealDialog( 'ブロックのz方向の長さは?', '30' );
IF DidCancel OR ( rZ = 0 ) THEN
BEGIN
GOTO 9999;
END;

FOR jj := 0 TO iy-1 DO
BEGIN
FOR ii := jj TO iX-1 DO
BEGIN
BeginXtrd( 0+jj*rZ, rZ+jj*rZ );
Rect( p1X+ii*rX, p1Y, p1X+rX+ii*rX, p1Y+rY );
HRotate( LNewObj, p1X, p1Y, rr );
IF ( jj MOD 2 = 0 ) AND ( ii MOD 2 <> 0 ) THEN
BEGIN
SetFillBack( LNewObj, 39321, 26214, 13107 );
END
ELSE IF ( jj MOD 2 <> 0 ) AND ( ii MOD 2 = 0 ) THEN
BEGIN
SetFillBack( LNewObj, 39321, 26214, 13107 );
END;
EndXtrd;
END;
END;

AlrtDialog( '計算が終了しました。' );
9999:
END;
Run( sample );