“Mesafe (p1, p2) <mesafe (p1, p3) eşitsizliğini basitleştirebilir miyim?


14

Bazı vektör mantığı üzerinde çalışıyorum, bu yüzden soruyorum: bu eşitsizliği basitleştirerek işlemci zamanından tasarruf edebilir miyim:

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

Bunun vector1her iki durumda da tekrarlandığını görüyorum .


10
Sadece hızlı bir not: mevcut yönteminiz çok okunabilir ve işlevi anında anlaşılabilir. Bu cevaplardan bazıları, talep ettiğiniz görevi yerine getirebilir, ancak çok daha az açıktır. Performans önemliyse bu iyidir, ancak netlik kaybını açıklamak için doğru şekilde yorumladığınızdan emin olun.
MikeS

3
@ MikeS'nin yorumuna devam edebilmek için, performansın sadece böyle bir durumda analiz veya profil oluşturduysanız ve bu çağrıyı bir darboğaz olarak tanımladıysanız böyle bir durumda olması gerekir. 305fps ve 303fps arasındaki farktan bahsediyorsak, sürdürülebilirlik ham performansı yener.
Phoshi

Yanıtlar:


24

Evet , basitleştirebilirsiniz. İlk olarak, onlara vektör demeyi bırakın. Onlar puan. Onları diyelim A, Bve C.

Yani, bunu istiyorsun:

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

Mesafeler ile değiştirin mesafeler tanımından (o nokta ürünleriyle, kare Öklit uzunluğu değiştirin. ACİle AB + BCartık bu gerçek vektörler vardır) (, faktör, Expand basitleştirmek.:

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)

İşte buradasın:

dot(AB + AC, BC) > 0

Vektör gösterimi ile:

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

Bu, önceki iki nokta ürünü yerine birkaç ekleme ve bir nokta ürünü.


Can you explain how you can replace aa + bb = aa + cc with the dot product version?
TravisG

2
@TravisG I am not sure of what you are asking. If your question is why dist(A, B)² is the same as dot(AB, AB), it comes from the very definition of the Euclidean length.
sam hocevar

2
Clearly this does (somewhat) simplify the equation mathematically, but wouldn't necessarily "save processor time" for the OP. It results in more complexity and more calculations than just removing the square root from the original distance equations.
MichaelHouse

1
Correct me if i´m wrong but the two dot-products are 5 operations per dot-product plus the two vec3 substractions which is a total of 16 operations, your way has 3 vec3 substractions plus an Addition which makes 12 operations plus the dot product makes 17.
Luis W

2
Interestingly enough, the result is the dot-product of the two opposite diagonals of a parallelogram. But that is irrelevant. What I wanted to say is that there isn't a tremendous amount to be gained from this full simplification; as others have mentioned it does a decent amount to obfuscate or complicate what you're actually trying to calculate. However, you definitely want to use the first step. Avoiding an unnecessary square root is always worth it. Just comparing the Squares of the distances is the same, as distance is positive definite, even in the complex plane.
TASagent

16

Yes. Assuming your distance function uses a square root, you can simplify this by removing the square root.

When trying to find the larger (or smaller) of a distance, x^2 > y^2 still holds true for x > y.

However, further attempts to simplify the equation mathematically are likely pointless. The distance between vector1 and vector2 is not the same as the distance between vector1 and vector3. While the equation can be simplified mathematically as Sam's answer shows, the form it's currently in is likely as simple as you'll get from the processor usage perspective.


I don't have enough rep, but I would as it is fundamentally incorrect, I believe: "can I save processor time by simplifying this inequality?" The answer is yes.
im so confused

The answer is only yes if the distance equation is using a square root. Which I mention.
MichaelHouse

Valid point, I'd retract my statement. However, it is 99% guaranteed that the user means euclidean distance sqrt(sum(dimensional differences squared))
im so confused

@imsoconfused Fair enough, I've changed the order of my answer to state the most likely (99%) scenario first.
MichaelHouse

2
Yes, my experience is when you're dealing with this sort of stuff a DistanceSquared function is very useful. It's just as clear and avoids the expensive sqrt operation.
Loren Pechtel

0

Some maths could help.

What you are trying to do is:

<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

From what you can remove repeated variables and group some others. The operation that you have to check is:

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

Hope it helps.


-1

The real question seems to be how to reduce computation for determining the nearest object?

Optimising this is often done in games, although with all optimisations it should be profile-guided and, often, doesn't simplify things.

The way to avoid unnecessary distance computations to determine the nearest thing - or all things within a certain range - is to use a spatial index e.g. an octree.

This only pays off if there are a large number of objects. For just three objects, it is unlikely to pay off and certainly doesn't simplify the code.


4
I think the actual question is fairly straightforward, and this answer doesn't address that. If you wanted to speculate as to the OP's deeper, unstated questions that should really be done as a comment if you aren't going to actually answer the asked question.

I am downvoting this because invoking a possible premature optimization is not an answer to a problem where explicit optimization does not hurt either readability, code maintainability, nor does it encourage obscure practices. When you can actually write simple and optimized code, why not do it? It certainly does not hurt to do it, even if you have a higher level plan (no game developer will ever refuse some extra microseconds per frame, esp. on consoles).
teodron

@teodron: "When you can actually write simple and optimized code, why not do it?" - Because OP (and now, us) has now spent a non-negligable amount of time optimizing something which may give him no benefit whatsoever.
BlueRaja - Danny Pflughoeft

@BlueRaja-DannyPflughoeft I agree with this to be a minor (hence insignificant optimization if used for a few hundred calls per frame, but if the factor of magnitude increases to thousands, things surely change). However, we are all free not to waste time trying to answer/optimize something we deem as not viable. The OP asked for one thing, people assumed the OP was not aware of higher level strategies and profiling practices. I personally prefer to make such remarks in comments, not in answers. Sorry for being so verbose :(.
teodron

-3

it depends on what the output of distance(v1,v2) is

if it is a decimal (float or double) over a vector it is likely that distancesquared would be a lot quicker


5
I don't see what it being a float has to do with anything.
MichaelHouse

i meant a float over another vector just not explained particularly well (and i think you knew that)
RoughPlace

5
I wasn't intentionally misunderstanding. I'm still not sure what you mean. I don't know why a distance function would return a vector.
MichaelHouse
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.