![](http://oshiete.xgoo.jp/images/v2/pc/qa/question_title.png?e8efa67b6d)
C#(.net framework 4.0)で現在業務に使用しているソフトで、地図画像に対して、ごく初歩的な図形(直線や矢印、円、四角形、文字程度)を挿入する事が必要になりそうでして、ドローソフト系のようなプログラミングを行いたいと思っています。(Excel上での図形挿入の様なイメージ)
Graphicsを使用して、線や塗りなどの描画はすぐにできると思うのですが、一度描画した線や四角を移動させたり大きさを調整したりするために、対象の図形をマウスでクリックして選択する方法がまるでうかびません。通常、この「図形を選択する」というのはどのように実現させているのでしょうか?思いつくものとしては、
図形をコントロールとして扱い、マウスイベントを直接受け取れるようにする?
(そもそもコントロールの使い方として間違っているような気がしますし、パフォーマンスにかなりの悪影響がありそう…)
別に座標マップを作り、どの図形がどのドットに対応しているかを記録する?
(線を引いた結果、どの座標がどの図形かをすべて計算する必要があると、かなりの計算とコード量になりそう…)
くらいです。基本的な、もしくは一般的な方法や考え方がありましたら是非教えてください。ペイント系ならそれなりにネット上に情報はあるような気もするのですが、ドロー系に関する情報はなかなか少ないようで困っています。ドロー系ソフト作成時に参考になるコードや情報や本などありましたら、そちらも教えていただけると助かります。よろしくお願いいたします。
P.S. 質問投稿時にさんざん迷ったのですが、C#(.Net Framework)のカテゴリーって、こちらの C・C++ でよろしかったんでしょうかw
No.3ベストアンサー
- 回答日時:
図形をコントロール(ウィンドウ)や、それを囲む矩形で判断すると、重なった部分に問題が出ます。
例えば、線分を描いたあとでその線分を囲むような円を描いた場合、円の方が(Z-orderで)上にある状態だと後ろにある線分を選択することができなくなります。
ソフトによっては、「前面に移動」、「背面に移動」といったコマンドを用意して回避している場合もあります。
クリックした点と図形の距離を計算し、範囲内で最も距離が近い図形を選択するようにしてはいかがでしょうか。
線分の場合の距離は、クリックした点から線分に垂線を引き、交点とクリックした点の距離を使います。ただし、交点が線分の延長線上になる場合は、クリックした点と線分の端点の距離のうち小さい方を使います。
円・円弧の場合は、中心点とクリックした点を通る直線を作り、その直線と円との交点を使用します。円弧の場合で交点が円弧の範囲外の場合は、線分と同様に円弧の端点を使用します。
矩形の場合は、矩形を4つの線分と考えて各線分との距離のうち小さいものを使用します。
すべて数学的な計算だけで済みます。ドットとの対応とかは使いません。
なるほど、交点とは思いつきませんでした。一次関数の嵐でなんとかなりそうですね。ただ、「数学的な計算だけ」とはいえ、そこが一番ネックになりそうです。複雑な計算は避けて通れそうにありませんね。ありがとうございます。もう少し楽して…というのは、無理でしょうか><
No.2
- 回答日時:
図形クラスを用意して、MouseMoveやMouseUp, Down毎にマウスポインタが図形と重なっているかどうかなどを検出して、選択や移動を行うのが一般的ではないでしょうか。
座標は正確に図形の形ではなくても図形全体を囲う矩形で通常は十分です。
描画も図形クラス自身に行わせます。
再描画ごとに登録している図形コレクションのすべてのDraw()メソッドを呼び出す感じです。
矩形で範囲が判断できれば確かにいうことはないのですが…、斜めの直線や四角形を回転させることもかなりの確率であり得ますのでなかなかどうしたものかと。
各図形のインスタンスのDrawメソッドで描画をすると便利なのは確かにその通りですね。参考にします。ありがとうございました。
No.1
- 回答日時:
ありがとうございます。「アルゴリズム入門 2章 CAD入門」内の「2.5.1 図形の選択処理 (1)内包処理」は、まさしく選択に関する記述でした。参考にさせていただきます。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・【あるあるbot連動企画】あるあるbotに投稿したけど採用されなかったあるある募集
- ・【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
- ・映画のエンドロール観る派?観ない派?
- ・海外旅行から帰ってきたら、まず何を食べる?
- ・誕生日にもらった意外なもの
- ・天使と悪魔選手権
- ・ちょっと先の未来クイズ第2問
- ・【大喜利】【投稿~9/7】 ロボットの住む世界で流行ってる罰ゲームとは?
- ・推しミネラルウォーターはありますか?
- ・都道府県穴埋めゲーム
- ・この人頭いいなと思ったエピソード
- ・準・究極の選択
- ・ゆるやかでぃべーと タイムマシンを破壊すべきか。
- ・「I love you」 をかっこよく翻訳してみてください
- ・歩いた自慢大会
- ・許せない心理テスト
- ・字面がカッコいい英単語
- ・昔のあなたへのアドバイス
- ・かっこよく答えてください!!
- ・あなたが好きな本屋さんを教えてください
- ・これ何て呼びますか Part2
- ・人生で一番思い出に残ってる靴
- ・ゆるやかでぃべーと すべての高校生はアルバイトをするべきだ。
- ・初めて自分の家と他人の家が違う、と意識した時
- ・単二電池
- ・チョコミントアイス
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
ListBoxで改行したい
-
C# DrawImage 物理サイズでな...
-
VB.NETでグラフィックを描くと...
-
Word:描画オブジェクト内の画...
-
ExtFloodFill を使った塗り潰し...
-
円の頂点の求め方を知りたいです。
-
VC++ ドラッグしながらの図の...
-
C#でPictureBox内での図形移動...
-
Excel VBA:コントロールボタン...
-
Word 描画オブジェクトを削除...
-
ビットマップに描画をしてピク...
-
for文の実行速度を遅くしたいの...
-
VB .net Form_Load時、または関...
-
リアルタイムで再描画
-
ボタンの更新速度について
-
PowerPoint の VBA
-
実行時エラー 438になった時の...
-
worksheetFunctionクラスのVloo...
-
VBA シートのボタン名を変更し...
-
パソコンへの「Dropbox...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
ListBoxで改行したい
-
for文の実行速度を遅くしたいの...
-
PowerPoint の VBA
-
給紙トレイをダイアログを使わ...
-
VB.NETでグラフィックを描くと...
-
ビットマップに描画をしてピク...
-
win32api複数のタイマーを同時...
-
Excel VBA:コントロールボタン...
-
画面に絵を出す方法
-
c言語 ちらつき
-
VC++ ドラッグしながらの図の...
-
Word 描画オブジェクトを削除...
-
N88BASICでシューティングゲー...
-
scilabでのグラフ描画時の軸設定
-
vb6のTEXTBOX
-
C#で壁の当たり判定と自キャラ...
-
図の削除直後の再描画
-
ボタンの更新速度について
-
C#(.net) ドロー系ソフト作成 ...
-
PictureBoxのダブルバッファリ...
おすすめ情報