-
Notifications
You must be signed in to change notification settings - Fork 15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
filter: Add FilterParaboloid #19
base: master
Are you sure you want to change the base?
Conversation
I am not really sure about this PR.
|
My use case for it is to check whether a given entity can hit a target with a projectile launched at a fixed speed in any direction. For this I need the volume that represents all points where it is possible to launch the projectile to, i.e., the envelope over all possible projectile trajectories. In 3D this is a paraboloid. There is a better explanation in the Wikipedia article.
It's fixed at the maximum speed the entity can launch the projectile at. If you want to maximize range and minimize time then the launch speed is always the maximum speed.
No there is no performance benchmark. This is to make the query possible in the first place. The alternative would be to approximate the paraboloid with either a cylinder, which would also have to be implemented, or an AABB, and then removing the points not in the paraboloid from the query results. |
Ah, I had misunderstood the purpose, I thought you were simulating the shape of a projectile, rather than the boundary shape of it's potential flight paths. Performance: The naive way to use the tree is to use a query bounding box (or a sphere, after your other contribution) and then filter all results with a is-inside-paraboloid check. Your PR adds a filter that moves the is-inside-paraboloid check into the PH-tree. The problem is that doing this check inside the PH-tree comes at a cost. If you filter externally (without this PR), you have to filter every entry that is inside a given box. It basically depends on two factors:
Maybe to understand why I am a bit reluctant (performance aside): if we accept such an PR then we have to maintain the code for basically as long as this project exists, which may be (hopefully) many years. Obviously maintaining code (fixing bugs, adapting to C++20/23/..., fix warnings with new compilers, improve documentation, ...) is not for free, so any additional code should provide a worthwhile benefit for users. So, despite having worked for ~10 years with spatial indexes, this is probably the first time I heard of this paraboloid problem being used in this context. It sounds like a sensible problem + solution, but I want to make sure that it really has a strong benefit for users. Unfortunately I am not convinced yet. I also haven't seen such a paraboloid i any other spatial index yet. |
/* | ||
* @param axis The axis along which the paraboloid is aligned. | ||
* @param vertex The vertex of the paraboloid. | ||
* @param scale_factor Scales the paraboloid along the axis. A positive scale factor |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you maybe give an example or explain what the scale factor does? The sign obviously affects the direction. But why is it a 'double'? Does it have any other effect or could it be a 'bool'?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's the scale factor in the quadratic term. This image shows two parabolas with scale factors 1 and 2. A negative value flips the parabola.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So basically for vertex=origin we get y=scale_factor * x^2
? Maybe you could add a sentence to the doc?
phtree/common/filter.h
Outdated
} | ||
|
||
KeyInternal closest_to_axis; | ||
for (size_t i = 0; i < prefix.size(); ++i) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: this could use 3
or maybe the DIM provided by the converter, instead of .size()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done. Note that FilterAABB
and FilterSphere
both use .size()
. Changing it for those does not make sense in this PR as it's not clear if it will be merged.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for pointing that out. I think FilterAABB
and FilterSphere
had inconsistent use of DIM vs size(), I fixed that.
phtree/common/filter.h
Outdated
|
||
// radius of paraboloid at axis offset of closest_to_axis | ||
ScalarExternal diff_axis = closest_point[axis_] - vertex_external_[axis_]; | ||
ScalarExternal radius = sqrt(diff_axis / scale_factor_); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure it makes a difference, but it may:
The sqrt could be avoided by comparing the squared radius. Division could be avoided by storing the inverse scale_factor_
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point, is updated.
Hi Til, sorry for the delay. I didn't really consider performance to that level, I mostly added the filter because it's generally applicable and thus makes the library easy to use. Without a parabola you need to choose a finitely sized box appropriate for the specific application and then filter the points with the code in
Given the circular shape of the parabola it can be quite a difference. Using the formula from this Quora question, the volume of a parabola is (π/2)hr², while the enclosing box has a volume of 4hr², so the box' volume is 8/π ≈ 2.5 times larger. Of course, how relevant this is depends heavily on how the points are distributed.
Comparing
Yes, I get your point. My assumption was that projectile range checks would be a relatively common use-case. But if Improbable does not have a need for it then maybe it's not as common as I expected. We can wait and see if someone else could make use of it. |
|
||
// radius of paraboloid at axis offset of closest_to_axis | ||
ScalarExternal diff_axis = closest_point[axis_] - vertex_external_[axis_]; | ||
ScalarExternal radius_sqr = sqrt(diff_axis / scale_factor_); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that sqrt
should also be removed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Didn't the tests report that?
I think there are two points here:
Anyway, thanks again for putting your time and effort into this.
@ALL Please like this if you want this to become part of the library. |
Changes
Add the
FilterParaboloid
filter than can filter points for an axis-aligned paraboloid given a vertex and a scale factor. Useful for range-checks on projectile with a fixed launch speed and arbitrary launch direction.Verification
Added a test case.