不等式「distance(p1、p2)<distance(p1、p3)」を簡略化できますか?


14

私はいくつかのベクトルロジックに取り組んでいるので、この不等式を単純化することでプロセッサ時間を節約できますか?

distance(vector1, vector2) < distance(vector1, vector3)

vector1どちらの場合も同じことが繰り返されます。


10
簡単なメモ:現在のメソッドは非常に読みやすく、その機能はすぐに理解できます。これらの回答のいくつかは、あなたが要求したタスクを達成するかもしれませんが、あまり明確ではありません。パフォーマンスが重要な場合はこれで問題ありませんが、明確さを失うことを考慮して適切にコメントしてください。
MikeS

3
@MikeSのコメントを続けるには、分析やプロファイリングをすでに行っており、この呼び出しをボトルネックとして特定している場合にのみ、このような場合にのみパフォーマンスが重要になります。305fpsと303fpsの違いについて言えば、保守性は生のパフォーマンスよりも優れています。
フォシ

回答:


24

はい、これを簡素化できます。まず、それらのベクターの呼び出しを停止します。それらはポイントです。それらを呼ぶことにしましょうABC

だから、あなたはこれが欲しい:

dist(A, B) < dist(A, C)

距離に置き換え距離は、の定義から(その後、ドットの製品で、乗ユークリッド長さ交換してください。ACAB + BC、今、これらは実数ベクトルです)(、要因を、展開が簡素化されます。:

dist(A, B < dist(A, C
dot(AB, AB) < dot(AC, AC)
dot(AB, AB) < dot(AB + BC, AB + BC)
dot(AB, AB) < dot(AB, AB) + dot(BC, BC) + 2 dot(AB, BC)
0 < dot(BC, BC) + 2 dot(AB, BC)
0 < dot(BC + 2 AB, BC)

そこにあります:

dot(AB + AC, BC) > 0

ベクトル表記で:

dot(v2 - v1 + v3 - v1, v3 - v2) > 0

これは、以前の2つのドット積の代わりにいくつかの追加と1つのドット積です。


a a + b b = a a + c cをドット製品バージョンに置き換える方法を説明できますか?
TravisG

2
@TravisGあなたが何を求めているのかわかりません。あなたの質問がなぜdist(A, B)²と同じであるならdot(AB, AB)、それはユークリッド長のまさに定義から来ます。
サムホセバー

2
明らかに、これは数式を数学的に単純化しますが、OPの「プロセッサ時間を節約する」とは限りません。元の距離方程式から単に平方根を削除するよりも複雑で計算が多くなります。
マイケルハウス

1
私が間違っているが、2つの内積が内積ごとに5つの操作と合計16の操作である2つのvec3減算である場合、私を修正してください。 17.作る
ルイス・W

2
興味深いことに、結果は平行四辺形の2つの対角線の内積です。しかし、それは無関係です。私が言いたかったのは、この完全な単純化から得られるほどの量はないということです。他の人が言及したように、それはあなたが実際に計算しようとしているものを難読化または複雑にするのにかなりの量をします。ただし、必ず最初のステップを使用してください。不要な平方根を避けることは常に価値があります。距離は、複素平面であっても正定であるため、距離の2乗を比較するだけで同じです。
TASagent

16

はい。あなたの仮定distance関数が平方根を使用平方根を削除することでこれを簡素化できます。

距離の大きい(または小さい)を見つけようとしてx^2 > y^2も、に当てはまりますx > y

しかし、方程式を数学的に単純化するさらなる試みは無意味である可能性があります。間の距離vector1とは、vector2間の距離と同じではないvector1vector3Samの答えが示すように、この方程式は数学的に単純化できますが、現在使用されている形式は、プロセッサ使用率の観点から得られるのと同じくらい簡単です。


私は十分な担当者がいませんが、基本的に間違っているため、「この不平等を単純化することでプロセッサ時間を節約できますか」と考えています。答えはイエスです。
混乱した

距離方程式が平方根を使用している場合のみ、答えはイエスです。私が言及します。
マイケルハウス

有効なポイント、私は私の声明を撤回します。しかし、ユーザーがユークリッド距離はsqrt(合計(寸法差の二乗))を意味することを、99%を保証されている
ので、混乱イム

@imsoconfused結構です。答えの順序を変更して、最も可能性の高い(99%)シナリオを最初に述べました。
マイケルハウス

2
はい、私の経験では、DistanceSquared関数が非常に便利なこの種のものを扱っています。同様に明確であり、高価なsqrt操作を回避します。
ローレンペクテル

0

いくつかの数学が役立ちます。

あなたがやろうとしているのは:

<v1, v2> < <v1, v3> =>
sqrt((y2-y1)^2+(x2-x1)^2) < sqrt((y3-y1)^2+(x3-x1)^2) =>
y2^2 - 2*y2y1 + y1^2 + x2^2 - 2*x2x1 + x1^2 < y3^2 - 2*y3y1 + y1^2 + x3^2 - 2*x3x1 + x1^2

繰り返し変数を削除し、他のいくつかをグループ化できるものから。確認する必要がある操作は次のとおりです。

y3^2 - y2^2 - 2*y1(y3-y2) + x3^2 - x2^2 - 2*x1(x3-x2) > 0

それが役に立てば幸い。


-1

本当の問題は、最も近いオブジェクトを決定するための計算をどのように削減するかです。

これを最適化することは、多くの場合ゲームで行われますが、すべての最適化ではプロファイルに基づく必要があり、多くの場合、物事を単純化しません。

不必要な距離計算を回避して最も近いもの、または特定の範囲内のすべてのものを決定する方法は、空間インデックス、たとえばoctreeを使用することです。

これは、多数のオブジェクトがある場合にのみ効果があります。オブジェクトが3つだけの場合、成果が得られる可能性は低く、確かにコードは単純化されません。


4
実際の質問はかなり簡単だと思いますが、この答えはそれを解決していません。OPのより深く、明言されていない質問について推測したい場合、質問に実際に答えるつもりがない場合にコメントとして実際に行う必要があります。

早期最適化の可能性を呼び出すことは、明示的な最適化が読みやすさ、コードの保守性を損なうことも、曖昧な慣行を助長することもないという問題に対する答えではないので、私はこれを支持しています。シンプルで最適化されたコードを実際に作成できる場合、それを実行してみませんか?たとえあなたがより高いレベルの計画を持っているとしても、それをすることは確かに害はありません(ゲーム開発者はフレームごとに、特にコンソールで余分なマイクロ秒を拒否することはありません)。
テオドロン

@teodron:「実際にシンプルで最適化されたコードを書くことができたら、それをしてみませんか?」-OP (そして今、私たち)無視できない時間を費やして、何の利益ももたらさないかもしれない何かを最適化しているからです。
BlueRaja-ダニーPflughoeft

@ BlueRaja-DannyPflughoeft私はこれがマイナーであることに同意します(フレームごとに数百回の呼び出しに使用する場合、取るに足らない最適化ですが、大きさの係数が数千に増加すると、状況は確実に変化します)。ただし、実行可能でないと判断したものに回答/最適化しようとする時間を無駄にしないように、私たちは皆自由です。OPは1つのことを求めました。人々は、OPがより高いレベルの戦略とプロファイリングの慣行を認識していないと思いました。私は個人的に、答えではなくコメントでそのような発言をすることを好みます。非常に冗長でごめんなさい:(
。–テオドロン

-3

それは、distance(v1、v2)の出力が何であるかに依存します

ベクトル上の小数(浮動小数点または倍精度)の場合、distancesquaredの方がはるかに高速になる可能性があります


5
私はそれが何と関係があるのか​​わかりませんfloat
マイケルハウス

私は別のベクトル上のフロートを意味していませんでした(そして、あなたはそれを知っていたと思います)
RoughPlace

5
私は意図的に誤解していませんでした。私はあなたが何を意味するのかまだわかりません。距離関数がベクトルを返す理由がわかりません。
マイケルハウス
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.