2点で長方形を定義する背後にある考え方は何ですか?[閉まっている]


14

これが意味をなさないということではありませんが、99%の時間でうまくいきません。

多くの場合、2Dグラフィックスでは、長方形はポイントのペアとして初期化、保存、および操作されます。特定の言語ではなく、

class Rect:
   p1, p2: point

次のように、長方形を2つのx値と2つのy値として定義する方が理にかなっています。

class Rect
   xleft, xright: int
   ytop, ybottom: int

2つのポイントで、ソースコードのどこかでトップのy値を使用したい場合は、rect.p1.y(hmmm、stop and think、p1またはp2)を言う必要がありますが、 4つの値をプレーンデータメンバーとして、明確かつ直接的なものにします。rect.ytop(思考は不要です!)2つのポイントを使用することは、垂直を扱う際に水平を絡ませる必要があることを意味します。独立した要素間には無関係な関係があります。

この2点のアイデアはどのようにして生まれたのですか?裸のx座標とy座標よりも利点がありますか?

追記:この質問は、ウィンドウマネージャーやGUIツールキットなどのXYに配置された四角形のコンテキストに関するものであり、描画および描画アプリの任意の図形のコンテキストではありません。


8
Rectsを使用してかなりの量のコードを記述しましたか?

6
長方形は2つのポイントで定義されるため、それらを2つのポイントとして表すのは理にかなっています。
アダムクロスランド

2
長方形は、x値の範囲とy値の範囲としてより自然に定義されます。
DarenW

2
いい質問です!私は自分でそれについて考えたことがありませんが、あなたは興味深い議論をしています!FWIW、Windowsはあなたが説明するようにRECTも持っています(上、左、下、右)
ディーン・ハーディング

3
2つのポイントを持つ長方形をどのように定義しますか?回転がないと想定されていますか?
ニックT

回答:


8

エラーが発生しにくいと考えましたか?

(Point1、Point2)を使用すると、指定する内容が非常に明確になります。2つのポイントを指定した場合、唯一のエラーは、ポイントの順序は関係ないので、ユーザーがポイントを構築するときにxとyを混同したことです。

4つの整数を指定した場合、誰かが注意を払っていない場合、必要なときに(x1、y2、x1、y2)(x1、y1、x2、y2)を指定できます。また、WCFのRect構造などの一部のAPI は、長方形を(x、y、width、height)として定義します。これにより、(1、2、3、4)の意味が混乱する可能性があります。それは(x、y、w、h)または(x1、y1、x2、y2)または(x1、x2、y1、y2)ですか?

全体として、(Point1、Point2)は私にとって少し安全なようです。


3
Rect(xrange(x1、x2)、yrange(y1、y2))のようなものはどうですか?これは、API使用の安全性と優雅さの究極のようです。
DarenW

9

私は常に、長方形をポイント+幅と高さとして定義するのが好きでした。ここで、ポイントは長方形の左上隅です。

class Rect {
  float x, y;
  float width, height;
}

そして、他のメトリックを取得するために必要なメソッドを追加します。Javaバージョンと同様


4
上のy + height、y-height、またはyだけですか?
キャメロンマクファーランド

2
@Cameron MacFarland:それは、アプリケーションの座標系に依存します。これは、低い長方形の心配はありません。
ジョンパーディ

2
@マーティンウィックマン:2点を使用することの利点は何ですか?
Kramii

@Kramii:1つの利点は、四角形全体を移動する場合に1つのポイントだけを変換する必要があることです。ところで、必要な場合はいつでも「ミッシングポイント」を計算できます(CPUとメモリのトレードオフ)。
マーティンウィックマン

これも実生活で見られます。私が長方形で行う最も一般的なことの1つは、ポイントがその中に含まれているかどうかをテストすることです。描画も一般的です。どちらの場合でも、追加を実行する必要があり、これは私のような高性能クロックサイクルカウンターを悩ませます。
DarenW

7

実際、リクタ​​グルは2点で定義されていません。長方形は、軸に平行な場合にのみ2点で定義できます。

軸に平行な長方形を表す方法はいくつかあります。

  1. 対角線上にある2つのポイント
  2. 1つのコーナーポイント、高さと幅
  3. 中心点、半分の高さと幅(一般的ではないが、時には役立つ)。
  4. 2つのX座標と2つのY座標として

(1)の場合、多くのライブラリーは規則を使用して、使用される2つのポイント(topLeftとbottomRightなど)を判別します。

表現の選択は、長方形の定義の本来の目的によって決まるかもしれませんが、私はそれがしばしばarbitrary意的であることを想像します。表現は、それらが運ぶ情報において同等です。ただし、長方形のプロパティの計算のしやすさと、四角形で操作を実行できる利便性が異なります。

定義(1)の利点には、次のものが含まれます。

  • APIと他のポリゴン、ラインなどとの一貫性
  • topLeft、bottomRightは、ポイントを受け入れる任意のメソッドに渡すことができます
  • Pointクラスのメソッドは、topLeft、bottomRightで呼び出すことができます
  • ほとんどのプロパティは簡単に導出できます。bottomLeft、topRight、幅、高さ、中央、斜めの長さなど

6

まあp1: Pointp2: Pointそれぞれ持ってしようとしている2点のint座標をとにかく彼らには、ので、あなたのクラスの量は同じものにしないのですか?

そして、これらの2つのポイントをファーストクラスのPointオブジェクトとして保存すると、それらからもう少しユーティリティが得られませんか?私が知っているほとんどのグラフィカル座標系では、オブジェクトの階層を作成するために、この方法でポイントがサブクラス化さpoint -> circle -> ellipseれます。

したがって、Pointクラスを使用しないオブジェクトを作成する場合、そのオブジェクトをクラス階層の残りの部分から離婚します。


1
OPの表現の利点は、長方形の低いy値を知りたい場合、「ybottom」であることがわかります。p1/ p2と同様に、どちらが低いかを把握する必要があります。とにかく、p1がより低い値になることを保証しない限り、これはそうです。
ジェイソンヴィアーズ

1
2つの異なる構造体が両方とも4つの座標に沸騰するのは事実ですが、2ポイントバージョンでは、1つのxと1つのyを収集する無関係なレベルが導入されます。長年のグラフィックプログラミングの後、この余分なレベルがユーティリティを提供するとは考えていません。
-DarenW

1
@ジェイソン:良い点。ytop/のybottomアプローチは、しかし、また、保証どこかがあるように必要があるだろうybottom、実際に以下の通りですytop
ワイリー博士の見習い

または、 'em y1およびy2を呼び出して、min(y1、y2)およびmax(y1、y2)を使用します。もちろん、2つのポイントp1、p2を介してアクセスするよりも扱いにくいでしょう。
DarenW

特別にコーディングしない限り、bottomx <topxを妨げるものは何もないので、top / bottomの命名は何も買いません。混乱を招くだけだと思います。
lkg

5

これがDelphiが好きな理由TRectです。TopLeftおよびBottomRightポイント、またはTop、Left、Bottom、Rightのいずれかの整数として解釈できるバリアントレコード(C言語のユニオン構造体)として定義されています。


1
そう、とても便利な機能。
10

4

長方形を次のように定義する場合:

class Rect
{
    Point bottomLeft;
    Point topRight;
}

すると、どのポイントがどのポイントであるかがすぐにわかります。

さらに良いのは、アプリケーションに必要な任意の方法で長方形を操作できる特別なプロパティを追加することです。これらは、基礎となるデータ構造を更新するだけです。

図形に変形を追加することにより、長方形を好きな方向に向けることができます。迅速な受け入れ/拒否チェックのために、軸に沿った境界ボックスが必要です:)

ただし、モデルが変換を適用せずに任意の方向の長方形を許可する場合、「左下」と「右上」には意味がなく、「p1」と「p2」(または同等のもの)に戻ります。


では、長方形を90度回転するとどうなりますか?当初とは異なる2つのポイントを追跡していますか、それとも「topRight」は「bottomLeft」の左側にありますか?
イナイマティ

@Inaimathi-変換行列を追加すると、長方形を軸に向けたままにできます。ただし、アプリケーションによって異なります。
ChrisF

2

長方形をxおよびyの範囲と点で表す方が理にかなっていると思います。回転に依存しないように、位置を長方形の中心にすることもできます

しかし、おそらく2つのポイントとしてコーディングするのが最も簡単でした!


2つのポイントとしてコーディングする方が簡単でしょうか?
DarenW

@DaremW:典型的な矩形描画ライブラリ関数は、左上と右下のポイントを引数として取ります
スティーブンA.ロウ

しかし、なぜそれらのAPIはそのように設計されているのでしょうか?それは、以前のライブラリを無意識に模倣することに加えて、つまり。
DarenW

@DarenW:私の推測では、ライブラリは、入力として2点を取り、非常に効率的であるブレゼンハムライン描画ルーチン、使用していることだろう
スティーブンA. Loweの

2

基本的に任意の回転を可能にする潜在的な自由度を捨てているため、私はそれが好きではありません。一般的な2D長方形には、5つの未知数(自由度)があります。それらを、点の座標、この点と頂点を形成する2つの辺の長さ、および最初の線の水平からの角度(もう一方は90度より大きいと想定されます)として指定できます。他の無限の可能性も使用できますが、5つの独立した数量を指定する必要があります。いくつかの選択は、それらで何が行われるかに応じて、他のものよりも簡単な代数を導きます。


5
「標準の」長方形構造は厳密に定義された数学的長方形ではなく、X軸とY軸に常に平行な単純化されたバージョンであることに注意することが重要です。 (ほぼ)常にX軸とY軸に平行なウィンドウマネージャーの場合。
メイソンウィーラー

+1、左/右/上/下の構造が事前にソートされているため、情報が少なくなります
ハビエル

良い点は、xyで整列した長方形についてです。私は、3Dモデリングで使用される範囲、およびその他のことも念頭に置いていましたが、すべてのxy(おそらく-z)が揃っています。
DarenW

1

それは2ポイントとまったく同じことではないですか?これはいかがですか?ほとんどの描画ルーチンには、個別のx / yコンポーネントではなく、ポイントが必要です。


1

四角形をポイントペアとして定義すると、ポイントを別の形状の頂点として再利用できます。ちょっとした考え...


しかし、2つのポイントだけを保持して4角形を定義するのは、半分のデッキで遊ぶようです。たまたま左上、クールが必要な場合でも、右上が必要な場合は、比較的言えば、手の込んだデータを取得する必要があります。
DarenW

ポイントAX、ポイントBY、ポイントBXポイントAYとして定義されたアクセサーがある場合、メモリ/ディスク上で軽くなります。半分の頂点を格納し、それらを指すだけです(最大グリッドサイズに応じて)。私はあなたがあなたの範囲の思考でどこに行くのかを得ますが、あなたはデッキの半分で遊んでいない、あなたはただ重複したデータを保存していません...そして作られるべき他のポイントはメモリの制約です 相互接続されたすべてのコードの四角形を再構築する再実装の意味は何ですか。
RobotHumans

また、最初の2つの頂点をメモリから取り出すために「作業」を行う必要がないため、おそらくより高速になります
-RobotHumans

1

主に、すべての形状プリミティブ間の均一性を確立することだと思います。

さまざまな方法で長方形を定義できますが、三角形、星、または円を同様のデータ構造を使用できる方法でどのように定義しますか?

すべてのポリゴンは、ポイントで何をすべきかを決定するための短いロジックで、ポイントによって定義できます。

グラフィックスライブラリは主に頂点とエッジに関してこれらのポリゴンで動作するため、ポイントとそれらの間のライン、すべての計算はこれら2つの機能で動作しますが、それとファセットですが、それ自体はエッジの関数です。


1

2次元では、特定のコーナーと幅と高さを定義するよりも長方形を2点として保存する方が明確です。負の幅または高さ、または各オプションを他のオプションから決定するために必要な計算を検討してください。

また、ポイントで定義された長方形の回転の実行は、ポイントに幅と高さを加えて定義された長方形よりもはるかに簡単です。

カプセル化により、この差別化がクラスのユーザーとして重要でなくなることが期待されます。

長方形は、3次元で適切に定義される3つのポイントとして定義する必要があります。4次元以上の長方形を定義するための要件が​​完全にはわかりません。


1

それは完全に任意です。長方形を描くには4つの情報が必要です。ライブラリデザイナーは、2つのポイント(それぞれxy座標)で表現することにしましたが、x / y / w / hまたはtop / bottom / left / rightで簡単に表現できました。

OPの本当の質問は、なぜこの特定の選択が行われたのでしょうか?


1

パラメーターの選択は、低レベルのデザイナー/コーダーにとってのみ重要です。

上級ユーザーは、次のことだけを考える必要があります。

  • IsPointInRect
  • 範囲
  • 交差点(またはクリッピング)
  • HasOverlap(Intersection.Area> 0と同じ)
  • Union(長方形のリストになります)
  • 減算(四角形A内にあるが四角形Bにはない同じポイントセットを表す四角形のリスト)
  • 変換する
    • XおよびYのシフト
    • 回転(0、90、180、270)
    • XおよびYのスケーリング(注を参照)
  • ユーザーがパラメーターの正確な選択を知る必要がないように、プロパティXmin、Xmax、Ymin、Ymax、Width、Heightの単純な構文。

注:スケーリング変換中の精度の損失を最小限に抑えるために、浮動小数点座標を使用する2番目のRectクラスを実装して、中間結果を変換シーケンスに正確に格納し、最後のステップ。


0

@Stevenが言うように、1つの(x、y)ポイントと(w、h)サイズのベクトルの点であると思います。それはあいまいさに陥りやすいからです。ポイント(0,0)から始まる次の塗りつぶされた長方形があるとします。

  012
0 XXX
1 XXX
2 XXX

明らかに幅、高さは(3,3)ですが、2番目のポイントは何ですか?(2,2)または(3,3)ですか?

このあいまいさは、あらゆる種類の問題を引き起こす可能性があります。

何年も前に、グラフィック座標をピクセルが存在する線ではなく、ピクセルの線として考える方が良いことを私は学びました。そのようにあいまいさはありません。


2
Macの元のQuickDrawルーチン(1980年代のもの)は、ポイントが無限に小さい数学モデルを使用していました。画面上の点はピクセルの間にあります。そのため、(3,5)から(10,5)に描かれた線の長さは7で、7ピクセルを占めていました。今日の座標では、その行は8の長さを持っているでしょう
バリー・ブラウン

@Barry:それは理にかなっています。XORを頻繁に使用するためです。また、行をつなぎ合わせている場合は、それらが出会う場所でピクセルが欠落することなく接続することを望みます。実際に、両方の座標系を考慮して、ポリゴンの塗りつぶしに関するシググラフペーパーを公開しました。
マイクダンラベイ

0
Pa(x,y)*-----------------------------------*Pb(x,y)
       |                                   |
       |                                   |
       |                                   |
       |                                   |
       |                                   |
       |                                   |
Pc(x,y)*-----------------------------------*Pd(x,y)

したがって、PbとPcの両方を定義できます。

Pb(Pd(x)、Pa(y))

そして

Pc(Pa(x)、Pd(y))

したがって、対称性のために4つすべてのポイントを定義する必要はありません

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.