|
|
2024/2/15(Thu) 15:10:17|NO.101227
こんにちは、直線上の先に文字列が表示される方法を、いろいろと試してみましたが、
上手くいきません教えて下さい。
#define CX 400
#define CY 400
screen 0,800,800
*mainloop
color 000,000,000 : boxf
kaku = rnd(30)
repeat 12
x = CX+200.0*cos(deg2rad(cnt*30+kaku))
y = CY+200.0*sin(deg2rad(cnt*30+kaku))
color 255,255,255
line CX,CY,x,y
pos x,y
color 255,000,000
mes "ABC"
loop
wait 100
goto *mainloop
以上のような、観覧車?っぽいプログラムを書きました。
それぞれの棒の先に重ならないよう、そのグラフの名前(ABC)が表示するようにしたいです。
これを実行すると、右下はこれで問題無いかと思いますが、左上は、希望するよりも
やや下に文字が下がってしまっており、左下は今よりも左に、左上に関しては
線と文字が重なってしまっており、みにくくなってしまっております。
こういった場合、線の延長上に文字の真ん中が来ればいいのではないかとおもうのですが
ginfo_mesx等使ってみましたがうまく作ることが出来ませんでした。
なにかよい改善策、アイディアあれば是非とも教えて頂けないでしょうか?
よろしくお願い致します。
|
|
2024/2/15(Thu) 15:42:12|NO.101228
どもども。
#define CX 400
#define CY 400
screen 0,800,800
mes "ABC" ;←まず1回mesしてサイズを取得
mx=ginfo_mesx
my=ginfo_mesy
*mainloop
redraw 0 ;←余計なお世話
color 000,000,000 : boxf
;kaku = rnd(30)
kaku++ ;←滑らかにしたかった余計なお世話
repeat 12
x = CX+200.0*cos(deg2rad(cnt*30+kaku))
y = CY+200.0*sin(deg2rad(cnt*30+kaku))
color 255,255,255
line CX,CY,x,y
pos x-mx/2,y-my/2 ;←mesサイズずらす
color 255,000,000
mes "ABC"
loop
redraw 1 ;←余計なお世話
await 1000/60 ;←余計なお世話 60fps
goto *mainloop
|
|
2024/2/15(Thu) 15:50:29|NO.101229
ぶた さま
さっそくの返信ありがとうございます。
プログラムのほう確認させて頂きました。
これでも素晴らしいのですが、もう少し中心から離して、線の先端に重ならないように
回収することできますでしょうか?先端がどの位置に来るかはっきりわかる為に
ズラしておきたいのです。
厚かましいお願いですみませんが、よろしくお願い致します。
|
|
2024/2/15(Thu) 16:01:28|NO.101230
このような形でやってみましたがどうでしょうか。
今回は文字列の長さが短いのでよいのですが、文字列が長くなると、
線の角度によっては線と文字列の間に異様に間隔が空いてしまうのが欠点ですが。
#include "gdi32.as" //GetTextExtentPoint32のために必要
#define CX 400
#define CY 400
screen 0,800,800
dim size,2 //GetTextExtentPoint32で使う配列
s="ABC"
GetTextExtentPoint32 hdc,varptr(s),strlen(s),varptr(size) //このようにすると文字列の横と縦のサイズがsize(0)とsize(1)に入る
x_off=size(0)/2 : y_off=size(1)/2 //文字列の中心から左上までのオフセット
span=sqrt(x_off*x_off+y_off*y_off) //これだけ間隔を開けておけば線と文字列は重ならない
*mainloop
color 000,000,000 : boxf
kaku = rnd(30)
repeat 12
tmp=cos(deg2rad(cnt*30+kaku))
x = CX+200.0*tmp
mesx = CX+(200.0+span)*tmp-x_off //文字列表示部分の中心点を求めたあと、xオフセットを引く
tmp=sin(deg2rad(cnt*30+kaku))
y = CY+200.0*tmp
mesy = CY+(200.0+span)*tmp-y_off //文字列表示部分の中心点を求めたあと、yオフセットを引く
color 255,255,255
line CX,CY,x,y
pos mesx,mesy
color 255,000,000
mes s
loop
wait 100
goto *mainloop
|
|
2024/2/15(Thu) 16:36:40|NO.101231
ぶた さま
ありがとうございます、
自分で考え、以下のように記述してみました。
ありがとうございます。
#define CX 400
#define CY 400
screen 0,800,800
mes "ABC\nDEF" ;←まず1回mesしてサイズを取得
mx=ginfo_mesx
my=ginfo_mesy
*mainloop
redraw 0 ;←余計なお世話
color 000,000,000 : boxf
// kaku = rnd(30)
kaku ++ ;←滑らかにしたかった余計なお世話
repeat 12
x = CX+200.0*cos(deg2rad(cnt*30+kaku))
y = CY+200.0*sin(deg2rad(cnt*30+kaku))
_x = CX+230.0*cos(deg2rad(cnt*30+kaku))
_y = CY+230.0*sin(deg2rad(cnt*30+kaku))
color 255,255,255
line CX,CY,x,y
pos _x-mx/2,_y-my/2 ;←mesサイズずらす
color 255,000,000
mes "ABC\nDEF"
loop
redraw 1 ;←余計なお世話
await 1000/60 ;←余計なお世話 60fps
goto *mainloop
沢渡 さま
ありがとうございます。
提示されたプログラム、動くことを確認致しました、しかしながら、
質問する上で内容を簡素化する為に文字列をABCとしましたが、実際には改行を含む
文字列となっております。
ですので、"ABC"を"ABC\nDEF"と変更すると
予期せぬ表示となってしまっております。
これは、GetTextExtentPoint32の仕様によるものでしょうか?
ご確認よろしくお願い致します。
|
|
2024/2/15(Thu) 19:09:46|NO.101235
ぶた さま より提示して頂きましたプログラムをベースとして、
自分で改造したものですが、
#define CX 400
#define CY 400
screen 0,800,800
mes "ABC\nDEF" ;←まず1回mesしてサイズを取得
mx=ginfo_mesx
my=ginfo_mesy
*mainloop
redraw 0 ;←余計なお世話
color 000,000,000 : boxf
// kaku = rnd(30)
kaku ++ ;←滑らかにしたかった余計なお世話
repeat 12
x = CX+200.0*cos(deg2rad(cnt*30+kaku))
y = CY+200.0*sin(deg2rad(cnt*30+kaku))
_x = CX+230.0*cos(deg2rad(cnt*30+kaku))
_y = CY+230.0*sin(deg2rad(cnt*30+kaku))
color 255,255,255
line CX,CY,x,y
pos _x-mx/2,_y-my/2 ;←mesサイズずらす
color 255,000,000
mes "ABC\nDEF"
loop
redraw 1 ;←余計なお世話
await 1000/60 ;←余計なお世話 60fps
//goto *mainloop
上記により、確認しますと、棒線の先端より、文字列までの距離がバラバラとなって
しまっております。
これを、ほぼ同一とするのは難しいでしょうか?
何度も質問してしまい申し訳ございませんが、
ご確認よろしくお願い致します。
|
|
2024/2/15(Thu) 19:53:03|NO.101236
>>Area39さん
下記のとおり、複数行の場合には、最後の行のサイズが入るので、
記載のスクリプトでは、1行目のmesのサイズ分が考慮されず、ズレてしまうということです。
mes一行ずつサイズを保存していく等、複数行の場合を考慮する必要があると思います。
それか、Yだけなら行数かけたら計算できますね。Xは文字数変わるので、サイズも変わっちゃいますね。
最も文字数の多い行をXサイズとするとか工夫が必要かもしれません
--------------------------------------------------------------
ginfo_mesxのHELPより抜粋
解説
最後にmes, print命令により出力されたメッセージのXサイズが代入されています。
・・・中略・・・
『また、複数行ある文字列を出力した場合は、最後の行にあたるサイズが取得されます』
|
|
2024/2/15(Thu) 20:07:06|NO.101237
ぶたさんのコードのmxやmyは実際の文字列を元に測定しているのに、
それとは無関係に「線を30伸ばした位置」を中心点に設定しているのだから、
ズレるのは当然じゃないかと。
>ですので、"ABC"を"ABC\nDEF"と変更すると
>予期せぬ表示となってしまっております。
>これは、GetTextExtentPoint32の仕様によるものでしょうか?
GetTextExtentPoint32は改行コードを含む文字列には対応していないので、
代わりにDrawTextを使います。
これでどうですか?
#include "user32.as" //DrawTextを使うのに必要
#define CX 400
#define CY 400
screen 0,800,800
dim rect,4
s="ABC\nDEF"
DrawText hdc,varptr(s),-1,varptr(rect),0x400 //DT_CALCRECT=0x400 これを実行することでrectに左上のx・y座標と右下のx・y座標が入る
x_off=(rect(2)-rect(0))/2 : y_off=(rect(3)-rect(1))/2 //文字列の中心から左上までのオフセット
span=sqrt(x_off*x_off+y_off*y_off) //これだけ間隔を開けておけば線と文字列は重ならない
*mainloop
color 000,000,000 : boxf
kaku = rnd(30)
repeat 12
tmp=cos(deg2rad(cnt*30+kaku))
x = CX+200.0*tmp
mesx = CX+(200.0+span)*tmp-x_off //文字列表示部分の中心点を求めたあと、xオフセットを引く
tmp=sin(deg2rad(cnt*30+kaku))
y = CY+200.0*tmp
mesy = CY+(200.0+span)*tmp-y_off //文字列表示部分の中心点を求めたあと、yオフセットを引く
color 255,255,255
line CX,CY,x,y
pos mesx,mesy
color 255,000,000
mes s
loop
wait 100
goto *mainloop
|
|
2024/2/15(Thu) 20:09:20|NO.101238
あっと、弄ってる間にぶたさんの書き込みが。
どうもginfo_mesxについて誤解している部分があったかもしれないので、
もし変なこと行ってたら申し訳ありません。
|
|
2024/2/15(Thu) 20:31:23|NO.101239
>>沢渡さん
ぶたの理解では、ginfo_mesxは、描画した文字列のxドット数が取得されると理解しております。
したがって、pos指定位置からginfo_mesx÷2をマイナスした位置にmesすると、センタリングされると理解しています。
複数行だと、めんどうですね。
gdi系は詳しくないので、勉強になります。
|
|
2024/2/15(Thu) 21:43:07|NO.101240
#define CX 400
#define CY 400
screen 0,800,800
mes "ABC\nDEF" ;←まず1回mesしてサイズを取得
mx=ginfo_mesx
my=ginfo_mesy
*mainloop
redraw 0 ;←余計なお世話
color 000,000,000 : boxf
// kaku = rnd(30)
kaku ++ ;←滑らかにしたかった余計なお世話
repeat 12
x = CX+200.0*cos(deg2rad(cnt*30+kaku))
y = CY+200.0*sin(deg2rad(cnt*30+kaku))
_x = CX+220.0*cos(deg2rad(cnt*30+kaku))
_y = CY+220.0*sin(deg2rad(cnt*30+kaku))
color 255,255,255
line CX,CY,x,y
xx=mx/2 : yy=my;/2
pos _x-xx,_y-yy ;←mesサイズずらす
;pos _x,_y
color 255,000,000
mes "ABC\nDEF"
loop
redraw 1 ;←余計なお世話
await 1000/60 ;←余計なお世話 60fps
goto *mainloop
こんなかんじ?
|
|
2024/2/15(Thu) 22:16:49|NO.101241
#define CX 400
#define CY 400
screen 0,800,800
txt="ABC\nDEF\nEFG"
notesel a
noteadd txt
mes ""+txt
mx=ginfo_mesx
my=ginfo_mesy
my2=notemax*my;/2
*mainloop
redraw 0 ;←余計なお世話
color 000,000,000 : boxf
color 255,255,255
pos 0,0 : mes ""+mx+","+my+","+my2
// kaku = rnd(30)
kaku ++ ;←滑らかにしたかった余計なお世話
repeat 12
x = CX+200.0*cos(deg2rad(cnt*30+kaku))
y = CY+200.0*sin(deg2rad(cnt*30+kaku))
_x = CX+230.0*cos(deg2rad(cnt*30+kaku))
_y = CY+230.0*sin(deg2rad(cnt*30+kaku))
color 255,255,255
line CX,CY,x,y
xx=mx/2 : yy=my2/2
;pos _x-xx,_y-yy ;←mesサイズずらす
pos _x-xx,_y-yy
color 255,000,000
mes ""+txt
loop
redraw 1 ;←余計なお世話
await 1000/60 ;←余計なお世話 60fps
goto *mainloop
改良版
|
|
2024/2/16(Fri) 01:11:11|NO.101242
ぶた さま
沢渡 さま
きせん さま
返信ありがとうございます。
教えて頂いた内容、理解することが出来ました。
最終的に、棒の長さが変わったりすると、+30の意味合いがあいまいとなり、合わなく
なってしまうため、沢渡 さまのスクリプトを採用させて頂きました。
皆様、教えて下さり、ありがとうございました。
また、機会ありましたら是非ともよろしくお願い致します。
|
|
2024/2/18(Sun) 11:25:23|NO.101254
参考にどうぞ。
#define CX 400.0
#define CY 400.0
#define edgenum 12
#define bmax 4
#define sxpadding 8
#define sypadding 4
#module
;文字列の描写範囲を求める(複数行対応)
#deffunc alignarea var allw,var allh,str string
cx=ginfo_cx:cy=ginfo_cy:tcx=cx:tcy=cy
tstr=string
dim strlist
split tstr,"\n",strlist
dim linew
lineh=0
allw=0
allh=0
repeat length(strlist)
pos 0,ginfo_dispy
mes strlist(cnt)
linew(cnt)=ginfo_mesx
if allw<ginfo_mesx{
allw=ginfo_mesx
lineh=ginfo_mesy
}
allh+=ginfo_mesy
loop
cy-=allh/2
repeat length(strlist)
pos cx-linew(cnt)/2,cy
mes""+strlist(cnt)
cy+lineh
loop
pos tcx,tcy+allh
return
#global
randomize
screen 0,800,800
sdim s,,edgenum
dim sarea,2,edgenum
dim blockdt,4,bmax
;各文字列生成
repeat edgenum:edgect=cnt
setid=0
repeat rnd(9)+4
setkey=rnd(27)+64
if setkey=64{
poke s(edgect),setid,13
setid++
poke s(edgect),setid,10
}else{
poke s(edgect),setid,setkey
}
setid++
loop
poke s(cnt),setid,0
alignarea sarea(0,cnt),sarea(1,cnt),s(cnt)
sarea(0,cnt)+=sxpadding*2
sarea(1,cnt)+=sypadding*2
loop
*mainloop
color 000,000,000 : boxf
kaku=rnd(30)
repeat edgenum
tmpx=cos(deg2rad(cnt*30+kaku))
tmpy=sin(deg2rad(cnt*30+kaku))
x=CX+200.0*tmpx
y=CY+200.0*tmpy
lndt=CX,CY,x,y
w=sarea(0,cnt)
h=sarea(1,cnt)
blockdt(0,0)=x+w/2,y-h/2,x-w/2,y-h/2
blockdt(0,1)=x+w/2,y+h/2,blockdt(0,0),blockdt(1,0)
blockdt(0,2)=x-w/2,y+h/2,blockdt(0,1),blockdt(1,1)
blockdt(0,3)=blockdt(2,0),blockdt(3,0),blockdt(0,2),blockdt(1,2)
;交点を求める
repeat bmax
cnt1=(cnt+1)\bmax
x1=0.0+blockdt(0,cnt):y1=0.0+blockdt(1,cnt)
x2=0.0+blockdt(0,cnt1):y2=0.0+blockdt(1,cnt1)
x3=0.0+lndt(0):y3=0.0+lndt(1)
x4=0.0+lndt(2):y4=0.0+lndt(3)
d=(x2-x1)*(y4-y3)-(y2-y1)*(x4-x3)
if d!=0{
u=((x3-x1)*(y4-y3)-(y3-y1)*(x4-x3))/d
v=((x3-x1)*(y2-y1)-(y3-y1)*(x2-x1))/d
if (u>=0&u<=1)&(v>=0&v<=1){
crossx=x1+u*(x2-x1)
crossy=y1+u*(y2-y1)
break
}
}
loop
;三平方の定理で中心点〜交点の長さを求める
len=sqrt(powf(x-crossx,2)+powf(y-crossy,2))
;文字列の位置を調整
mesx = CX+(200.0+len)*tmpx-w/2+sxpadding
mesy = CY+(200.0+len)*tmpy-h/2+sypadding
;描写
color 255,255,255
line CX,CY,x,y
pos mesx,mesy
color 255,000,000
mes s(cnt)
loop
wait 100
goto *mainloop
| |
|
2024/2/19(Mon) 11:59:54|NO.101257
ま、負けねーw
#include "user32.as"
#const DT_CALCRECT 0x400
#define ctype deg2rad2(%1) deg2rad((%1)\360 + ((%1)<0)*360) //返り値の範囲が0以上2Π未満になるdeg2rad
#define CX 400
#define CY 400
#define x_mar 4
#define y_mar 2
screen 0,800,800
dim rect,4
//文字列のプロパティ
sdim text,64,12
text(0)="あいう\nえお","かき\nくけこ","さしすせそ","たちつて\nと","な\nにぬ\nねの"
text(5)="はひふ\nへほ","まみ\nむめも","やゐゆゑよ","らりるれ\nろ","わ\nを\nん"
text(10)="ABC\nDEFG","HI\nJK\nLMN"
ddim wid,12 : ddim hei,12 //文字列の横幅と縦幅
ddim angle,12,4 //文字列を囲む長方形の対角線の角度、および処理を変える閾値
repeat 12
DrawText hdc,varptr(text(cnt)),-1,varptr(rect),DT_CALCRECT
wid(cnt)=double(rect(2)-rect(0)+x_mar*2) : hei(cnt)=double(rect(3)-rect(1)+y_mar*2)
angle(cnt,0)=atan(hei(cnt),wid(cnt)) //heiもwidも自然数なので、この角度は0を超えM_PI/2未満になる筈。
angle(cnt,1)=M_PI-angle(cnt,0) //よって、この4つの角度が0やM_PI/2やM_PIやM_PI*3/2になることはない。
angle(cnt,2)=M_PI+angle(cnt,0)
angle(cnt,3)=M_PI*2-angle(cnt,0)
loop
//本編
randomize
kaku=0
*mainloop
redraw 0
color 000,000,000 : boxf
kaku++ : if kaku>=360 : kaku-=360
repeat 12
rad=deg2rad2(cnt*30+kaku)
co=cos(rad)
x = CX+200.0*co
si=sin(rad)
y = CY+200.0*si
if rad<angle(cnt,0) | rad>=angle(cnt,3) { //線が「文字列を囲む長方形」の左から進入するケース
mesx=x + x_mar
mesy=y + wid(cnt)/2*si/co - hei(cnt)/2 + y_mar
} else {
if rad<angle(cnt,1) { //線が長方形の上から進入するケース
mesx=x + hei(cnt)/2*co/si - wid(cnt)/2 + x_mar
mesy=y + y_mar
} else {
if rad<angle(cnt,2) { //線が長方形の右から進入するケース
mesx=x - wid(cnt) + x_mar
mesy=y - wid(cnt)/2*si/co - hei(cnt)/2 + y_mar
} else { //線が長方形の下から進入するケース
mesx=x - hei(cnt)/2*co/si - wid(cnt)/2 + x_mar
mesy=y - hei(cnt) + y_mar
}
}
}
color 255,255,255
line CX,CY,x,y
pos mesx,mesy
color 255,000,000
mes text(cnt)
loop
redraw 1
await 33
goto *mainloop
| |
|
2024/2/19(Mon) 20:21:17|NO.101259
>>NO.101257
大したものです。
|
|