From: Masato Ishimoto Date: 2006-06-04T17:56:14+09:00 Subject: [ruby-list:42357] Re: TkCanvasの座標 こんにちは、いしもとです。 永井さん、アドバイスありがとうございます。  1につきましては、とてもよく分かりました。勘違い(というか大ボ ケ)し ている部分や知らなかった部分が多々ありました。もっと勉強せねば ^^;  2につきましては、アドバイスいただいたコードでも状況は変わりま せんで した。  具体的には、提示いただいたコードによって、 ・x座標の表示は改善され、左端の縦線も表示されるようになっ た。 ・しかし、y座標は相変わらずずれたまま。y座標を 0に設定すると線が表示されない。 ・y座標の値を1にすると線が表示される。これにカーソル を乗せると、y座標は0。 という状況です。これは一体・・・? 以下、コード抜粋です。(ラインの変数名を変更してあります) canvas=TkCanvas.new(root, 'height'=>201, 'width'=>201, 'scrollregion'=>[0,0,200,200], 'cursor'=>'tcross' ).pack('side'=>'top') x_line=TkcLine.new(canvas,0,0,200,0) #これでは表示されない                  # 座標を(0, 1, 200, 1)とすれば表示される。 y_line=TkcLine.new(canvas,0,0,0,200) #これは表示されるようになった canvas.bind('Motion', proc{|x, y| enx.text=xp=canvas.canvasx(x) eny.text=yp=canvas.canvasy(y) },'%x %y' ) 以上、よろしくお願いいたします。 いしもと On Jun 4, 2006, at 1:47 AM, Hidetoshi NAGAI wrote: > 永井@知能.九工大です. > > From: Masato Ishimoto > Subject: [ruby-list:42355] TkCanvasの座標 > Date: Sat, 3 Jun 2006 02:24:26 +0900 > Message-ID: <384C309E-92F4-430B-B2A9-0ECEA5DBE629@coo.net> >> MacOSX10.4+Ruby1.8.2環境下で、マウスカーソル(tcross)で >> キャンバスのX、Y座標を取得するプログラムを作って >> いま >> す。 >> 2点ほど気になりましたので質問させてください。 > > 確かに分かりづらい部分かもしれません. > ご承知のことかもしれませんが,説明するに当り,まずは確認事項で > す. > キャンバスウィジェットが管理する領域の大きさは > メモリが許す限り広大なものにできます. > 画面の表示は,その広大な領域の一部を覗き見ていると考えてくださ > い. > ここではその部分を「窓」と読んでおきます. > >> 1.キャンバスの大きさ(と表示範囲)が指定したものと違う。 >> >>  プログラムでは200x200のキャンバスを生成し、その >> 4辺 >> ギリギリにそれぞれ一本ずつと、各辺を2等分する線を引いて >> います。(6本の線で4つの正方形ができている状態) >>  ・・・はずなのですが、まず、キャンバスのサイズが206x206 >> になっています。さらに、表示範囲(?)がずれているのか、左 >> と上にあるはずの線が表示されません。これは、こういうものなの >> でしょうか?それとも私が何か勘違いしているだけでしょうか? > > キャンバスの窓サイズは 200x200 になっています. > canvas.width, canvas.height が返すのは,この窓サイズです. > > ですが,キャンバスウィジェット自体のサイズは, > 窓サイズに加えて borderwidth, highlightthickness, > selectborderwidth といった要素が加わって決定されています. > これらまで含めて,現在,画面上で表示されているキャンバスウィ > ジェットの > 大きさは canvas.winfo_width, canvas.winfo_height で得ら > れます. > いしもとさんの現状では,多分,この値が 206x206 になって > いるのでしょう. > > 線が表示されない件については,座標 (0,0) から (200, > 200) の場合, > 幅と高さは 201x201 である点が理由の一つです. > キャンバスの scrollregion (窓を動かす範囲) が設定 > されていませんから > 最後に描画されたアイテムの終点側の (200, 200) が優先されて > 窓位置が選ばれたのかもしれません (この点については確信が > ありません). > 多分,窓位置は (1, 1) -- (200, 200) になっているのでしょ > う. > こうして考えてみますと, > > canvas.width = 201 > canvas.height = 201 > canvas.scrollregion = [0, 0, 200, 200] > > と設定すべきであろうということになります. > > さて,キャンバスと窓との関係を考えると, > 次の問題も原因が想像できるかもしれません. > >> 2.生成したline同士の交点とそれを指したカーソルの座標 >> が違 >> う。 >> >>  キャンバスで交差している点にカーソルを合わせると、Y座 >> 標が >> 1小さい値が表示される気がします。例えば、下記プログラムで >> はキャンバス中央の交点は100,100だと思うのですが、カーソ >> ルで >> は100,99となります。これは何故なのでしょうか?カーソル >> の問題 >> ?キャンバスの問題?それとも私の問題? > > いしもとさんが表示していたのはキャンバス上の座標ではありません. > > イベント情報として得られる %x, %y は, > ウィジェットの左上角を (0,0) としたときの座標であることに > 注意してください. > この場合,relief 部分 (borderwidth に依存) > も含まれます. > つまりは,%x, %y はキャンバス上の座標を直接には示してい > ません. > これは,キャンバスと窓との関係を考えていただければ分かるでしょ > う. > > キャンバス上の座標は,%x, %y の情報から求めてやる必要が > あります. > x, y で %x, %y の情報を受け取っているなら,キャンバス上 > の座標は > > canvas.canvasx(x) > canvas.canvasy(y) > > で得られます (実数値が返されます). > > というわけで,修正したコード(部分)はこんな感じでしょうか? > ------------------------------------------ > : > : > canvas = TkCanvas.new(root, > 'bg' => 'pink', > 'height' => 201, > 'width' => 201, > 'scrollregion' => [0,0,200,200], > 'cursor' => 'tcross' > ).pack('side' => 'top') > : > : > canvas.bind('Motion', > proc{|x, y| enx.text=xp=canvas.canvasx(x) > eny.text=xp=canvas.canvasy(y) > },'%x %y' ) > : > : > ------------------------------------------ > >>  気になって夜も眠れません。アドバイスいただければ幸いです。 > > これでゆっくりとお休みすることができましたら幸いです.(^_^) > -- > 永井 秀利 > (九工大 知能情報) > nagai@ai.kyutech.ac.jp