|
|
|
2006/12/18(Mon) 23:12:46|NO.4189
マス単位で直線を引きたく、次のような方法をとりました。
まずバッファーにline命令で直線を引き、そのバッファーを1ドットずつ見ていき、
黒なら描画したいウィンドウの対応するマスにboxfで色を塗る
という方法です。
そのスクリプトを組んでみたのですが、うまくいきませんでした。
このスクリプトの問題点が分かる方、教えてください!お願いします。
//元々のスクリプトの一部分を切り出して編集したものなので一部無駄な所があります。
#const size 10
randomize
*main
stick kkk,256
if (mmmk=0)&((kkk&256)!0){ //クリックされた瞬間(訳があってstickの非トリガーキーに
mmmk=1 // マウスの左ボタンを指定しています)
gsel 0
color
boxf int(mousex/size)*size,int(mousey/size)*size,int(mousex/size)*size+size,int(mousey/size)*size+size
f1_msx=mousex //線を引く
f1_msy=mousey //始点
}
if mmmk&((kkk&256)=0){ //マウスが離された瞬間
mmmk=0
f1_mssx=f1_msx/size //始点をマスごとに区切る
f1_mssy=f1_msy/size
f1_mex =mousex/size //終点をマスごとに区切る
f1_mey =mousey/size
color 255,255,255
boxf int(f1_msx/size)*size,int(f1_msy/size)*size,int(f1_msx/size)*size+size,int(f1_msy/size)*size+size
buffer 10,abs(f1_mex-f1_mssx),abs(f1_mey-f1_mssy) //このバッファにlineで線を引く
line limit(f1_mex-f1_mssx,0,$FFFF),limit(f1_mey-f1_mssy,0,$FFFF),limit(f1_mssx-f1_mex,0,$FFFF),limit(f1_mssy-f1_mey,0,$FFFF)
//↑がうまくいきません
bx=ginfo_winx
by=ginfo_winy
color 0,0,255
gsel 10
repeat bx
xcnt=cnt
repeat by
pget xcnt,cnt
if ginfo_r|ginfo_g|ginfo_b:continue //色が黒以外(白)なら次へ
gsel 0
bbx = f1_mssx+xcnt*(-2*(f1_mssx>f1_mex)+1)
bby = f1_mssy+cnt*(-2*(f1_mssy>f1_mey)+1)
boxf bbx*size,bby*size,bbx*size+size,bby*size+size
gsel 10
loop
loop
}
wait 5
goto *main
| |
|
2006/12/19(Tue) 01:58:27|NO.4192
> そのスクリプトを組んでみたのですが、うまくいきませんでした。
これだけではこのプログラムのどういう動作がますさんにとっての「うまくいかない」動作なのかが
他人にはわからないので、回答をするのは難しいです。
とりあえず自力で解決するためのポイントをいくつか指摘しておくと、
1. 以下の部分の buffer 命令を screen 命令に変更し実行して動作の様子を確かめてみる。
> buffer 10,abs(f1_mex-f1_mssx),abs(f1_mey-f1_mssy) //このバッファにlineで線を引く
> line limit(f1_mex-f1_mssx,0,$FFFF),limit(f1_mey-f1_mssy,0,$FFFF),limit(f1_mssx-f1_mex,0,$FFFF),limit(f1_mssy-f1_mey,0,$FFFF)
> //↑がうまくいきません
2. 描画色の設定はウィンドウごとに保存されています。例えば
screen 0 : color 255, 0, 0
screen 1 : color 0, 255, 0
gsel 0 : boxf
の場合、255,0,0 の色で四角が描画されます。
|
|
2006/12/19(Tue) 15:45:13|NO.4206
すみませんでした。とりあえず言いたいことが分かるようなスクリプトに
書き換えました。
>buffer命令をscreen命令に変更し
どうやら、ここはうまく描画されているようです。
>描画色の設定はウィンドウごとに保存されています。
ありがとうございます。ここのせいで上の表示されていなかったようです。
もっと詳しく説明すると、
このプログラムでマウスの左ボタンを押すと黒い四角が表示され、
マウスを移動してからボタンを離すと黒い四角からマウスの場所まで線が引かれます。
しかし、左上→右下 又は 右下→左上ならばうまくいくのですが、
左下→右上 又は 右上→左下 は左右逆に描画されてしまいます。
また、斜めではない縦か横の直線の場合、まったく描画されません。
よろしくお願いします。
|
|
2006/12/19(Tue) 22:35:27|NO.4223
「拡大コピーして升を引く」じゃ駄目ですか?
こっちの方が断然速いと思いますが
|
|
2006/12/20(Wed) 03:24:32|NO.4235
ヒント。
> 左下→右上 又は 右上→左下 は左右逆に描画されてしまいます。
考え方はいろいろありますが直線の始点と終点の関係だけで考えるのではなく
直線を囲む長方形の左上の頂点を加えた関係を考えてみてはどうでしょう?
> また、斜めではない縦か横の直線の場合、まったく描画されません。
縦か横の直線の場合 abs(f1_mex-f1_mssx), abs(f1_mey-f1_mssy) の値はどうなるでしょうか?
以下は余談。
>「拡大コピーして升を引く」じゃ駄目ですか?
> こっちの方が断然速いと思いますが
実際のところ、この方法で構わない状況ならこっちの方が楽です。
(ただし元の方法の pgetの処理(かなり遅い)を他の手法で代替すれば
この方法の速度面での優位性はなくなります。)
|
|
2006/12/20(Wed) 20:39:26|NO.4256
こんなんでしょうか?
//マクロ
#define global WM_LBUTTONDOWN 0x0201 //マウス左ボタンを押し下げ
#define global WM_LBUTTONUP 0x0202 //マウス左ボタンを離した
#define global WM_MOUSEMOVE 0x0200 //マウス移動時に実行
#define global ctype LOWORD(%1) (%1 & 0xFFFF) //下位ワード値を取得
#define global ctype HIWORD(%1) ((%1 >> 16 ) & 0xFFFF) //下位ワード値を取得
#define global size 10//マスの一辺のサイズ
//プロシージャ
oncmd gosub *ON_WM_LBUTTONDOWN,WM_LBUTTONDOWN
oncmd gosub *ON_WM_LBUTTONUP,WM_LBUTTONUP
oncmd gosub *ON_WM_MOUSEMOVE,WM_MOUSEMOVE
#module
//Pen画像の取得=
// コピータイプ(-1=通常コピー 0=白を透明化,1=黒を透明化,2=アルファブレンドコピーgmode7),
// 画像があるウィンドウID,
// コピーする左上X,
// コピーする右上Y,
// コピーする大きさX,
// コピーする大きさY),
// 始点X,始点Y,終点X,終点Y
#deffunc pline array p1, int p2, int p3, int p4,int p5
redraw 0
//初期位置
sx=p2
sy=p3
//大きいほうの値を優先
//幅の取得
if p4>p2:xx=p4-p2:else:xx=p2-p4
if p5>p3:yy=p5-p3:else:yy=p3-p5
if xx>yy{
lop=xx
if yy!0:ss=lop/yy:else:ss=0
}else{
lop=yy
if xx!0:ss=lop/xx:else:ss=0
}
//2点間の距離を求める
if p2<p4:s1=p4-p2:else:s1=p2-p4
if p3<p5:s2=p5-p3:else:s2=p3-p5
ssss=int(sqrt(s1*s1+s2*s2))+1
lorgb=ginfo_r,ginfo_g,ginfo_b
//コピータイプ指定
switch p1(0)
case -1
gmode 1
swbreak
case 0
gmode 4,,,256
color 255,255,255
swbreak
case 1
gmode 2
swbreak
case 2
gmode 2//3
//未実装です
swbreak
swend
//ドットライン描画
repeat ssss
dir=atan(p4-p2,p5-p3)
x=sin(dir)*cnt+p2:y=cos(dir)*cnt+p3
pos x,y:gcopy p1(1),p1(2),p1(3),p1(4),p1(5)
loop
color lorgb(0),lorgb(1),lorgb(2)
redraw 1
return
#global
buffer 2,100,100
cls 4
gsel 0
pen=-1,2,0,0,size,size //ペン情報
stop
*ON_WM_MOUSEMOVE //マウス移動
if click=1{
redraw 0
color 255,255,255
boxf
y=0
repeat ginfo_winy/size
x=0
repeat ginfo_winx/size
if (x*size<=mousex)&(y*size<=mousey)&(x*size+size>mousex)&(y*size+size>mousey){
//Pen画像の取得=
// コピータイプ(-1=通常コピー 0=白を透明化,1=黒を透明化,2=アルファブレンドコピーgmode7),
// 画像があるウィンドウID,
// コピーする左上X,
// コピーする右上Y,
// コピーする大きさX,
// コピーする大きさY),
// 始点X,始点Y,終点X,終点Y
pline pen,lomx*size,lomy*size,x*size,y*size
}
x+
loop
y+
loop
redraw 1
}
return
*ON_WM_LBUTTONDOWN
click=1
y=0
repeat ginfo_winy/size
x=0
repeat ginfo_winx/size
if (x*size<=mousex)&(y*size<=mousey)&(x*size+size>mousex)&(y*size+size>mousey){
//始点を記憶
lomx=x
lomy=y
gosub *ON_WM_MOUSEMOVE
}
x+
loop
y+
loop
return
*ON_WM_LBUTTONUP
click=0
color 255,255,255
boxf
return
| |
|
2006/12/24(Sun) 01:20:55|NO.4367
修正例。
#const size 10
randomize
buffer 10, ginfo_winx / SIZE + 1, ginfo_winy / SIZE + 1
*main
stick kkk,256
if (mmmk=0)&((kkk&256)!0){ //クリックされた瞬間(訳があってstickの非トリガーキーに
mmmk=1 // マウスの左ボタンを指定しています)
gsel 0
color
boxf int(mousex/size)*size,int(mousey/size)*size,int(mousex/size)*size+size,int(mousey/size)*size+size
f1_msx=mousex //線を引く
f1_msy=mousey //始点
}
if mmmk&((kkk&256)=0){ //マウスが離された瞬間
mmmk=0
f1_mssx=f1_msx/size //始点をマスごとに区切る
f1_mssy=f1_msy/size
f1_mex =mousex/size //終点をマスごとに区切る
f1_mey =mousey/size
if ( f1_mssx < f1_mex ) { xl = f1_mssx } else { xl = f1_mex } // 直線全体を囲む矩形の左上頂点
if ( f1_mssy < f1_mey ) { yt = f1_mssy } else { yt = f1_mey }
cx = abs( f1_mex - f1_mssx ) + 1 // 直線全体を囲む矩形の大きさ
cy = abs( f1_mey - f1_mssy ) + 1
gsel 0
color 255,255,255
boxf int(f1_msx/size)*size,int(f1_msy/size)*size,int(f1_msx/size)*size+size,int(f1_msy/size)*size+size
gsel 10
color 255, 255, 255
boxf xl, yt, xl + cx, yt + cy // 下地をクリア
color 0, 0, 0
line f1_mex, f1_mey, f1_mssx, f1_mssy // 線を引く
;pset f1_mex, f1_mey // 終端の一点
repeat cx, xl
xcnt = cnt
repeat cy, yt
gsel 10
pget xcnt, cnt
if ginfo_r|ginfo_g|ginfo_b:continue //色が黒以外(白)なら次へ
gsel 0
color 0, 0, 0
boxf xcnt * size, cnt * size, xcnt * size + size, cnt * size + size
loop
loop
}
wait 5
goto *main
| |
|