HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2024
0215
Area39直線上の先に文字列が表示される方法15解決


Area39

リンク

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



Area39

リンク

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



Area39

リンク

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の仕様によるものでしょうか?

ご確認よろしくお願い致します。



Area39

リンク

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
改良版



Area39

リンク

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
大したものです。



記事削除

記事NO.パスワード
(質問が解決したスレッドは他の利用者に活用してもらうため、削除しないようお願いします)

NO.101227への返信

マスコット

好きなマスコットを選んでください。

名前

e-mail
HOME
  1. 初めて利用する方は、HSP3掲示板の使い方をお読みください。
  2. 不要部分の多い長いスクリプトの投稿は ご遠慮ください。
  3. 書き込みは自動改行されません。適度に改行を入れてください。
  4. スクリプトは小文字の<pre>〜</pre>で囲むと見やすく表示できます。

削除用パスワード

解決したら質問者本人がここをチェックしてください。

エラー発生時、再送信すると二重送信になることがあります。
回答が得られたら、お礼書き込み時に[解決]チェックしてください。
SPAM防止のためURLから始まる文章は投稿できません。
SPAM防止のため英文字のみの本文を投稿することはできません。

ONION software Copyright 1997-2023(c) All rights reserved.