|
 |
|
2020/4/16(Thu) 10:28:16|NO.90115
画像を左クリックで拡大、右クリックで縮小するスクリプトを作ったんですけど
何故か拡大を続けるとマウスの基点と誤差が生じてしまいます
どうすればよろしいでしょうかよろしくお願いします
; ウィンドウの作成
screen 0, GINFO_DISPX, GINFO_DISPY, SCREEN_HIDE
; 変数宣言
baseZoom = 3.0
nowZoom = 1.0
; 画像の読み込み
#const imageId 1
celload strf( "%s/sample/basic/fontchr.bmp", DIR_EXE ), imageId
gsel imageId
; 画像の大きさ
imageSizeX = GINFO_WINX
imageSizeY = GINFO_WINY
gsel 0
; ウィンドウのサイズを変更
gsel 0, 1
width ( baseZoom * imageSizeX ), ( baseZoom * imageSizeY ), 0
width GINFO_WINX, GINFO_WINY, ( 0.5 * ( GINFO_DISPX - GINFO_WINX ) ), ( 0.5 * ( GINFO_DISPY - GINFO_WINY ) )
repeat
;
stick key
; 倍率を上げる
if ( key == 256 ) {
; 適用
nowZoom += 1.0
; マウス座標
_mousex = mousex
_mousey = mousey
}
; 倍率を下げる
if ( key == 512 ) {
; 適用
nowZoom -= 1.0
}
; 適用範囲
nowZoom = limitf( nowZoom, 1.0, 10.0 )
; 描画開始
redraw 0
; 背景
color 0, 0, 0
boxf
; 画像
pos -( 1.0 * _mousex * ( nowZoom - 1.0 ) ), -( 1.0 * _mousey * ( nowZoom - 1.0 ) )
celput imageId, 0, ( baseZoom * nowZoom ), ( baseZoom * nowZoom ), 0.0
; 描画終了
redraw 1
; 情報
title strf( "表示座標( %.0f, %.0f ) 表示拡大率:%.0f%% 拡大率: %.0f%%", GINFO_CX, GINFO_CY, ( 100.0 * ( baseZoom * nowZoom ) ), ( 100.0 * nowZoom ) )
; 時間
await 16
loop

| |
|
2020/4/16(Thu) 10:30:06|NO.90116
stick key, ( 256 + 512 )
; 倍率を上げる
if ( key == 256 ) {
; 適用
nowZoom += 0.1
; ズームアップした時のマウス座標
_mousex = mousex
_mousey = mousey
}
; 倍率を下げる
if ( key == 512 ) {
; 適用
nowZoom -= 0.1
}
にスクリプトを置換したら分かりやすいかもしれません。
|
|
2020/4/16(Thu) 11:15:34|NO.90117
拡大にcelputではなく、gzoomを使ってはどうでしょうか。
拡大もしくは回転ありのcelputは、内部では(gzoomではなく)grotateと同様の処理を
行っているようで、回転ができる分拡大処理については厳密さに欠けるようです。
; ウィンドウの作成
screen 0, GINFO_DISPX, GINFO_DISPY, SCREEN_HIDE
; 変数宣言
baseZoom = 3.0
nowZoom = 1.0
; 画像の読み込み
#const imageId 1
celload strf( "%s/sample/basic/fontchr.bmp", DIR_EXE ), imageId
gsel imageId
; 画像の大きさ
imageSizeX = GINFO_WINX
imageSizeY = GINFO_WINY
gsel 0
; ウィンドウのサイズを変更
gsel 0, 1
width ( baseZoom * imageSizeX ), ( baseZoom * imageSizeY ), 0
width GINFO_WINX, GINFO_WINY, ( 0.5 * ( GINFO_DISPX - GINFO_WINX ) ), ( 0.5 * ( GINFO_DISPY - GINFO_WINY ) )
flag=1 //拡大率を変更したフラグ(初回の描画を行うため、初期値は1)
_mousex=0 : _mousey=0
repeat
;
stick key
; 倍率を上げる
if ( key == 256 ) {
; 適用
nowZoom += 1.0
; マウス座標
_mousex = mousex
_mousey = mousey
flag=1
}
; 倍率を下げる
if ( key == 512 ) {
; 適用
nowZoom -= 1.0
flag=1
}
if flag {
; 適用範囲
nowZoom = limitf( nowZoom, 1.0, 10.0 )
; 描画開始
redraw 0
; 背景
color 0, 0, 0
boxf
; 画像
pos -( 1.0 * _mousex * ( nowZoom - 1.0 ) ), -( 1.0 * _mousey * ( nowZoom - 1.0 ) )
gzoom imageSizeX*baseZoom * nowZoom,imageSizeY*baseZoom * nowZoom,imageID,0,0,imageSizeX,imageSizeY
; 描画終了
redraw 1
; 情報
title strf( "表示座標( %.0f, %.0f ) 表示拡大率:%.0f%% 拡大率: %.0f%%", GINFO_CX, GINFO_CY, ( 100.0 * ( baseZoom * nowZoom ) ), ( 100.0 * nowZoom ) )
flag=0
}
; 時間
await 16
loop

| |
|
2020/4/16(Thu) 15:44:50|NO.90118
ありがとうございます無事できました
もう一つ質問がありますが内容がほぼ同じなのでここでさせていただきます
今度は画像バージョンから座標バージョンの拡大縮小方法について教えてほしいです
例としては
; ウィンドウの作成
screen 0, 640, 480, SCREEN_NORMAL
; 初期処理
randomize
; 変数宣言
baseZoom = 3.0
dim ball, 100
foreach ball
ballX(cnt) = rnd(GINFO_WINX)
ballY(cnt) = rnd(GINFO_WINX)
loop
repeat
;
stick key, ( 256 + 512 )
; 倍率を上げる
if ( key == 256 ) {
; 適用
nowZoom += 0.1
; マウス座標
_mousex = mousex
_mousey = mousey
}
; 倍率を下げる
if ( key == 512 ) {
; 適用
nowZoom -= 0.1
}
; 適用範囲
nowZoom = limitf( nowZoom, 1.0, 10.0 )
; 描画開始
redraw 0
; 背景
color 255, 255, 255
boxf
; いろいろ
color 255, 0, 0
ballR = 4.0
foreach ball
bx = ballX(cnt)
by = ballY(cnt)
circle ( bx - ballR ), ( by - ballR ), ( bx + ballR ), ( by + ballR ), 1
loop
; 描画終了
redraw 1
; 情報
title strf( "拡大率: %.0f%%", ( 100.0 * nowZoom ) )
; 時間
await 16
loop
のような一つ一つに座標を持つボールたちの拡大縮小の方法を知りたいです
できればバッファーを使わずただの計算式で教えてほしいです
わがままで申し訳ないですがよろしくお願いします
|
|
2020/4/16(Thu) 15:45:48|NO.90119
すいません
ballX(cnt) = rnd(GINFO_WINX)
ballY(cnt) = rnd(GINFO_WINY)
でした
|
|
2020/4/16(Thu) 17:01:53|NO.90120
こんな感じでいいでしょうか?
; ウィンドウの作成
screen 0, 640, 480, SCREEN_NORMAL
; 初期処理
randomize
; 変数宣言
baseZoom = 3.0
dim ball, 100
foreach ball
ballX(cnt) = rnd(GINFO_sx)
ballY(cnt) = rnd(GINFO_sy)
loop
adj_x=0.0 //現在の倍率で、画面の左方向にどのくらいはみ出すか
adj_y=0.0 //現在の倍率で、画面の上方向にどのくらいはみ出すか
preZoom=1.0 //倍率変更前の倍率
nowZoom=1.0
flag=1 //倍率を変更したフラグ
_mousex=0.0 : _mousey=0.0
repeat
;
stick key, ( 256 + 512 )
; 倍率を上げる
if ( key == 256 )&(nowZoom<10.0) {
; 適用
preZoom=nowZoom
nowZoom += 0.1
; マウス座標
_mousex = double(mousex)
_mousey = double(mousey)
flag=1
}
; 倍率を下げる
if ( key == 512 )&(nowZoom>1.0) {
; 適用
preZoom=nowZoom
nowZoom -= 0.1
; マウス座標
_mousex = double(mousex)
_mousey = double(mousey)
flag=1
}
if flag {
; 描画開始
redraw 0
; 背景
color 255, 255, 255
boxf
; いろいろ
color 255, 0, 0
ballR = baseZoom*nowZoom
adj_x=(_mousex+adj_x)*nowZoom/preZoom-_mousex //新しい倍率に合わせてはみ出す範囲を修正
adj_y=(_mousey+adj_y)*nowZoom/preZoom-_mousey
foreach ball
bx = int((double(ballX(cnt)))*nowZoom-adj_x)
by = int((double(ballY(cnt)))*nowZoom-adj_y)
circle ( bx - ballR ), ( by - ballR ), ( bx + ballR ), ( by + ballR ), 1
loop
; 描画終了
redraw 1
; 情報
title strf( "拡大率: %.0f%%", ( 100.0 * nowZoom ) )
flag=0
}
; 時間
await 16
loop

| |
|
2020/4/16(Thu) 20:02:08|NO.90121
沢渡様、
私のわがままに付き合ってくれて本当にありがとうございました!
|
|
2020/4/16(Thu) 20:22:48|NO.90122
あ、でもすいません。
マウスを移動しながら拡大縮小を行うと座標がズレちゃいます。
|
|
2020/4/16(Thu) 22:10:40|NO.90123
「ズレちゃいます」とは上下左右に妙に広い空白ができてしまうことでしょうか?
とりあえず、adj_xとadj_yに上限と下限を設けて対処しましたが、これでどうでしょうか?
; ウィンドウの作成
screen 0, 640, 480, SCREEN_NORMAL
; 初期処理
randomize
; 変数宣言
baseZoom = 3.0
dim ball, 100
foreach ball
ballX(cnt) = rnd(GINFO_sx)
ballY(cnt) = rnd(GINFO_sy)
loop
adj_x=0.0 //現在の倍率で、画面の左方向にどのくらいはみ出すか
adj_y=0.0 //現在の倍率で、画面の上方向にどのくらいはみ出すか
preZoom=1.0 //倍率変更前の倍率
nowZoom=1.0
flag=1 //倍率を変更したフラグ
_mousex=0.0 : _mousey=0.0
repeat
;
stick key, ( 256 + 512 )
; 倍率を上げる
if ( key == 256 )&(nowZoom<10.0) {
; 適用
preZoom=nowZoom
nowZoom += 0.1
; マウス座標
_mousex = double(mousex)
_mousey = double(mousey)
flag=1
}
; 倍率を下げる
if ( key == 512 )&(nowZoom>1.0) {
; 適用
preZoom=nowZoom
nowZoom -= 0.1
; マウス座標
_mousex = double(mousex)
_mousey = double(mousey)
flag=1
}
if flag {
; 描画開始
redraw 0
; 背景
color 255, 255, 255
boxf
; いろいろ
color 255, 0, 0
ballR = baseZoom*nowZoom
adj_x=(_mousex+adj_x)*nowZoom/preZoom-_mousex //新しい倍率に合わせてはみ出す範囲を修正
adj_x=limitf(adj_x,0.0,640.0*(nowZoom-1.0))
adj_y=(_mousey+adj_y)*nowZoom/preZoom-_mousey
adj_y=limitf(adj_y,0.0,480.0*(nowZoom-1.0))
foreach ball
bx = int((double(ballX(cnt)))*nowZoom-adj_x)
by = int((double(ballY(cnt)))*nowZoom-adj_y)
circle ( bx - ballR ), ( by - ballR ), ( bx + ballR ), ( by + ballR ), 1
loop
; 描画終了
redraw 1
; 情報
title strf( "拡大率: %.0f%%", ( 100.0 * nowZoom ) )
flag=0
}
; 時間
await 16
loop

| |
|
2020/4/16(Thu) 23:56:14|NO.90124
横から失礼します。
double型は沢渡さんの手法ではときどき微妙な誤差が出て来るので
何度も拡大縮小していると
nowZoomの値が『1.0』ではなく『1.0000000000000009』になってしまう場合があり
誤判定されて縮小時に0.9倍になったり拡大時に10.1倍になることがあります。
なので元の名無しさんのやり方のように
>nowZoom = limitf( nowZoom, 1.0, 10.0 )
この行は残した方が良いかと思います。
それとズレに対応するソースですが、
右及び下だけだと1倍とそれ以外の倍率でいきなり座標が飛んでしまうので
左と上にも対応させて
adj_x=(_mousex+adj_x)*nowZoom/preZoom-_mousex //新しい倍率に合わせてはみ出す範囲を修正
adj_x=limitf(adj_x,-640.0*(nowZoom-1.0),640.0*(nowZoom-1.0))
adj_y=(_mousey+adj_y)*nowZoom/preZoom-_mousey
adj_y=limitf(adj_y,-480.0*(nowZoom-1.0),480.0*(nowZoom-1.0))
このように0ではなくマイナス方向も考慮した方が良いかと。
以上です。
横から揚げ足取りのような形となり失礼いたしました。
|
|
2020/4/17(Fri) 00:20:16|NO.90125
すみません確認ミスしました。
ズレが生じるのは誤差が出来てからでした。(0.9倍とそれ以外の時)
>nowZoom = limitf( nowZoom, 1.0, 10.0 )
この行を残しておけばズレる事はなさそうなので
先述の後半は無視してください。
たびたび失礼いたしました。
|
|
2020/4/17(Fri) 00:36:56|NO.90126
なるほど。実数は使い慣れてないもので、計算の繰り返しによる誤差の拡大を甘く見ていました。
申し訳ない。
|
|
2020/4/17(Fri) 10:33:51|NO.90127
あらや様、沢渡様、ありがとうございました
無事自分の望み通りになりました
|
|
2020/4/19(Sun) 09:31:52|NO.90134
横から失礼。NO.90117のソースもNO.90122で言っているようなことが起きていないか?
|
|