2009-08-06 8 views
14

私はC#(Windowsフォーム)でピクチャボックス上にいくつかの長方形を描画するプログラムを持っています。それらはある角度(回転)で描画することもできます。ポイントが回転した矩形内にあるかどうかをチェックする(C#)

各矩形の始点(左上隅)、そのサイズ(幅+高さ)、およびその角度を知っています。回転のために、開始点は必ずしも左上隅ではありませんが、ここでは関係ありません。 次にピクチャボックスをクリックすると、クリックした矩形(もしあれば)をチェックする必要があります。

だから、ある点が矩形内にあるかどうかを調べる方法が必要ですが、各矩形の回転も考慮する必要があります。 誰かがC#でこれを行う方法を知っていますか?

+0

矩形は、原点、左上隅、または他の任意の点について回転していますか? – outis

答えて

18

矩形に適用された同じ回転を逆の点に適用できますか?

たとえば、矩形Aを原点(左上隅)から時計回りに45度回転させた場合、同じ原点を中心に45度回転させて時計回りに45度回転させ、次にA矩形内に入るかどうかを確認します-rotation

+0

これは確かに行く方法ですが、私はこの瞬間に自分の数学を得ることができません。ありがとうございました。 – Ove

+0

私は理想的なソリューションは、あなたのアプリケーションで設定したフレームワークに依存すると思います。いくつかのケースでは、私はOutisのzバッファの考えがより理想的だと思います。彼のソリューションは、GPUが3Dでオブジェクトをレンダリングするのと同じ方法であることに留意してください。 –

+1

公正であるためには、 "z-"をバッファリングの考えに持ってきました。 – outis

5

一意に色付けされた四角形の複製を描画する場合は、2番目の非表示のイメージを保持できます。ユーザがピクチャボックスをクリックすると、2番目の画像内の対応するピクセルの色が見つけられ、どの矩形がクリックされたかが識別されます。

+1

これはメモリの無駄であり、遅くなるでしょう。 – Ove

+1

Outisの解決策は機能しません。私は今CFプロジェクトでこれを使って、特に複雑なヒットテストを行っています。しかし、またチェックアウト:http://msdn.microsoft.com/en-us/library/system.drawing.rectangle.contains(VS.80).aspx Rectangleクラスには、ポイントをテストするために使用できるContainsメソッドがあります封じ込め。 –

+0

+1数学以外の解答の場合 – JeffH

1

矩形を重複させることはできますか? もしそうなら、ポイント内のすべての矩形、または最上位レイヤーの矩形だけが必要ですか?

2

私はこれが既に答えられていることを知っていますが、私はずっと前に同様のことをしなければなりませんでした。私はニールが提案正確に何を助けたSystem.Windows.Pointクラスの拡張メソッドを作成しました:

public static double GetAngle(this Point pt) 
    { 
     return Math.Atan2(pt.X, -pt.Y) * 180/Math.PI; 
    } 

    public static Point SetAngle(this Point pt, double angle) 
    { 
     var rads = angle * (Math.PI/180); 
     var dist = Math.Sqrt(pt.X * pt.X + pt.Y * pt.Y); 
     pt.X = Math.Sin(rads) * dist; 
     pt.Y = -(Math.Cos(rads) * dist); 
     return pt; 
    } 

これは私が0の周りの点の角度で作業できるようになり、0ですから、センターを知っていれば(例えば:pt.X - = 32; pt.Y - = 32)次に、長方形の負の回転を適用します(提案されているように〜によってNeil:pt.SetAngle(-45);)...

今ポイントが64以内にある場合、64あなたは長方形を打つことを知っています。具体的には、回転した画像のピクセルをチェックして、特定の色のピクセルにヒットしていることを確認していました。

0

私は今、しばらくの間、これをいじってきたし、実際に働いた人はいません。ここでOPと同じように動作するC#関数があります.OP以外であれば、他の人が私のようにグーグルになります。

これを理解するのは頭痛でした。典型的な推測の多く。

bool PointIsInRotatedRectangle(Vector2 P, Rectangle rect, float rotation) 
    { 
     Matrix rotMat = Matrix.CreateRotationZ(-rotation); 
     Vector2 Localpoint = P - (rect.Location).ToVector2(); 
     Localpoint = Vector2.Transform(Localpoint, rotMat); 
     Localpoint += (rect.Location).ToVector2(); 

     if (rect.Contains(Localpoint)) { return true; } 
     return false; 
    } 

ここでは1行のコードです。おそらくより速く使用する。

bool PointIsInRotatedRectangle(Vector2 P, Rectangle rect, float rotation) 
    { 
     if (
      rect.Contains(Vector2.Transform(P - (rect.Location).ToVector2(), Matrix.CreateRotationZ(-rotation)) + (rect.Location).ToVector2()) 
      ) { return true; } 
     return false; 
    } 
関連する問題