Is there a known and standard algorithm for calculating the time of impact between a circle and a box? The only information I can find are tests determining whether a circle and a box are already colliding. I can't find anything that would allow me to have the projected vector of a ball's movement be used to calculate if a collision will occur.
Is time of impact not used for anything except raycasting?
All entities velocities, orientations, and rotations are static in the particular context I am in.
After asking around, the best way to do this seems to be computing the Minkowski difference between the two objects, and then raycasting from the origin of the circle, and calculating the time of impact (if it exists) with the new shape.
This has been described pretty thoroughly here.
Related
Given a 3D distance field that contains the distance to points in a grid (e.g. an ESDF or TSDF), I want to efficiently check whether a cube at an arbitrary orientation contains a point.
A straightforward approach is to perform raytracing to identify which cells are contained inside of the cube and check if any of those cells have 0 distance. This solution is unsatisfying because it throws away the distance information and is tightly coupled to the underlying ESDF via raytracing. It seems like we should be able to solve this problem more generally using the distance information and the resolution parameter.
One could imagine a more sophisticated approach which first checks the distance from the center of the cube to a point - if the value is large enough we know the cube is empty, or if it is small enough we know there is a point inside the cube. If the value is somewhere in between, we could recursively check the ambiguous regions. Because the distance function is discretized this algorithm should eventually terminate if the bookkeeping is done properly during the search.
Of course the devil is in the details and that is why I'm asking this question. What is the most efficient method to identify if there is a point inside the cube? If this is a classical problem, what is it called?
The goal is to do simple vector image editing by dragging the mouse across the screen like a polygon-shaped paintbrush, creating the Minkowski sum of the brush and the path of the mouse. The new polygon would be subtracted from any previously existing polygons of a different color and merged with any existing polygons of the same color.
The plan is to take each mouse movement as a line segment from the mouse's previous position to its current position, calculate the Minkowski sum on that line segment, then do use the Weiler–Atherton clipping algorithm to update the existing polygons to include that Minkowski sum.
Since it seems likely that Weiler–Atherton would cause UI delays if run for every mouse movement, we plan to delay that step by putting it into another thread that can take its time catching up to the latest mouse movements, or alternatively save all Weiler–Atherton calculations until the drawing is finished, then do it as a bulk operation when saving. We worry that this may lead to the accumulation of a very large number of overlapping polygons, to the point that UI would be delayed by the time required to render them all.
The question is: Is the above plan the way that Inkscape and other serious vector graphics editing software would perform this operation? It seems like a mad plan, both in the trickiness of the algorithm and its computational complexity. What would an expert do?
Another option under consideration: Do the painting using simple raster operations and then convert the raster into a vector image as the final step. Conversion from raster to vectors seems no less tricky than Weiler–Atherton, and quality of the final output might suffer, but could it be the better option?
While the user is holding down the mouse button and drawing, you can remember all the mouse movement line segments, and simultaneously render the brush*line Minkowski sums to a screen resolution bitmap.
You can use the bitmap for painting the screen until the user releases the button. At that time you can calculate the union of all the line segment Minkowski sums and add the resulting shape to your drawing.
To calculate the union of so many shapes simultaneously, some kind of sweep-line algorithm would be best. You should be able to do the job in O(N log N) or linear time, which will not cause any noticeable delay.
IMO the bottleneck in Weiler-Atherton is the detection of the intersections, which requires O(N²) operations when applied by brute-force. the rest of the processing is a reorganization of the links between the vertices and intersections, which should be limited to O(N), or even O(NI), where NI denotes the number of intersections.
In this particular case, you can probably speed-up the search for intersections by means of gridding or a hierarchy of bounding boxes. (Note that gridding parallels the idea of Matt to use auxiliary bitmap rendering.)
Unless you really have billion edges, I wouldn't fear the running time.
If you want to do this like professional vector graphics softwares do with arbitrary brush shapes (including features such as the brush shape can react to speed or stylus pressure), it can be quite involved unfortunately.
I was experimenting with the method described in "Ahn, Kim, Lim - Approximate General Sweep Boundary of a 2D Curved Object". It seems to handle a lot of cases that I would expect from a professional drawing application —especially the details where the brush shape can be dynamic while sweeping; adaptively generate the boundary curve for the resolution you want; variable width offsetting of 2d curves; etc..
It seems you can simplify this method if you don't need a generalised method. But I would like to add it here as a reference.
PS: I was searching for a non-paywalled link to include here in the answer and then this came up – Looking for an efficient algorithm to find the boundary of a swept 2d shape. Looks very similar to what you're trying to do :).
I have a lot of points (hundreds of thousands) and I want to check which ones are inside a polygon. For a relatively small polygon (i.e., likely to contain only tens or hundreds of points) I can just use the bounding box of the polygon as an initial check, and then do a regular point-in-poly check for those points inside the box. But imagine a large (i.e., likely to contain thousands of my points), irregularly shaped polygon. Many points will pass the bounding box check, and furthermore the point-in-poly check will be more expensive because the larger polygon is made up of many more points. So I'd like to be able to filter most points in or out without having to do the full point-in-poly check.
So, I have a plan, and mainly I want to know if what I'm describing is a well-known algorithm, and if so what it's called and where I might find existing code for it. I don't believe what I'm describing is either a quad-tree or an r-tree, and I don't know how to search for it. I'm calling it a "rect tree" below.
The idea is, to handle these larger polygons:
Do a "rect tree" pre-process, where the depth of the rect tree varies by the size of the polygon (i.e., allow more depth for a larger polygon). The rect tree would divide the bounding box of the polygon into four quarters. It would check if each quarter-rect is fully inside the polygon, fully outside the polygon, or neither. In the case of neither it would recursively divide the subrects, continuing in this way until all rects were either fully inside or outside, or the max depth had been reached. So the idea is that (a) the pre-processing time to make this tree, even though it itself will do several point-in-polygon checks, is well worth it because that time is dwarfed by the number of points to be checked, and (b) the vast majority of points can be dealt with using simple bounding box checks (generally a few such checks as you descend the tree), and then a relatively small number would have to do the full point-in-polygon check (for when you reach a leaf node that is still "neither").
What's that algorithm called? And where is the code? It doesn't in fact seem so hard to write, but I figured I'd ask before jumping into coding.
I actually ended up using a related but different approach. I realized that essentially this tree structure I was building up was no more than the polygon drawn at a low resolution. For instance, if my tree went down to a depth of 8, really that was just like drawing my polygon on a bitmap with resolution 256x256 and then doing pixel hit tests against that polygon. So I extended that idea and used a fast graphics library (the CImg library). I draw the polygon on a black-and-white bitmap of size 4000x4000. Then I just check the points as pixels against that bitmap. The magic is that drawing that huge bitmap is really fast compared to the time it was taking me to construct the tree. So I get much higher resolution than I ever could have with my tree.
One issue is being able to detect points near the very edge of the polygon, which may be included or excluded incorrectly due to rounding/resolution issues, even at the 4000x4000 size. If you need to know precisely whether those points are in or out, you could draw a stroke around the polygon in another color, and if your pixel test hit that color, you'd do the full point in poly check. For my purposes the 4000x4000 resolution was good enough (I could tolerate incorrect inclusion/exclusion for some of my edge points).
So the fundamental trick of this solution is the idea that polygon drawing algorithms are just super fast compared to other ways you might "digitize" your polygon.
I'm working on a purely continuous physics engine, and I need to choose algorithms for broad and narrow phase collision detection. "Purely continuous" means I never do intersection tests, but instead want to find ways to catch every collision before it happens, and put each into "planned collisions" stack that is ordered by TOI.
Broad Phase
The only continuous broad-phase method I can think of is encasing each body in a circle and testing if each circle will ever overlap another. This seems horribly inefficient however, and lacks any culling.
I have no idea what continuous analogs might exist for today's discrete collision culling methods such as quad-trees either. How might I go about preventing inappropriate and pointless broad test's such as a discrete engine does?
Narrow Phase
I've managed to adapt the narrow SAT to a continuous check rather than discrete, but I'm sure there's other better algorithms out there in papers or sites you guys might have come across.
What various fast or accurate algorithm's do you suggest I use and what are the advantages / disatvantages of each?
Final Note:
I say techniques and not algorithms because I have not yet decided on how I will store different polygons which might be concave, convex, round, or even have holes. I plan to make a decision on this based on what the algorithm requires (for instance if I choose an algorithm that breaks down a polygon into triangles or convex shapes I will simply store the polygon data in this form).
You said circles, so I'm assuming you have 2D objects. You could extend your 2D object (or their bounding shapes) into 3D by adding a time dimension, and then you can use the normal techniques for checking for static collisions among a set of 3D objects.
For example, if you have a circle in (x, y) moving to the right (+x) with constant velocity, then, when you extend that with a time dimension, you have a diagonal cylinder in (x, y, t). By doing intersections between these 3D objects (just treat time as z), you can see if two objects will ever intersect. If point P is a point of intersection, then you know the time of that intersection simply by looking at P.t.
This generalizes into higher dimensions, too, though the math gets hard (for me anyway).
The collision detection might be tricky if objects have complex paths. For example, if your circle is influenced by gravity, then the extruded space-time object is a parabolic sphere sweep rather than a simple cylinder. You could pad the bounding objects a bit and use linear approximations over shorter periods of time and iterate, but I'm not sure if that violates what you mean by continuous.
I am going to assume you want things like gravity or other conservative forces in your simulation. If that's the case the trajectories of your objects are most likely not going to be lines, in which case, just like Adrian pointed out, the math will be somewhat harder. I can't think of a way to avoid checking all possible combinations of curves for collisions, but you can calculate the minimum distance between two curves rather easily, as long as both are solutions to linear systems (or, in general, if you have a closed form solution for the curves). If you know that x1(t) = f(t) and x2(t) = g(t) then what you'll want to
do is calculate the distance ||x1(t) - x2(t)|| and set its derivative to zero. This should be an expression that depends on f(t), g(t) and their derivatives and will give you a time tmin (or maybe a few possible ones) at which you then evaluate the distance and check to see if it is greater or smaller than r1+r2 --- the sum of the radii of the two bounding circles. If it is smaller, then you have a potential collision at that time so you run the narrow phase algorithm.
Imagine we have a 2D sky (10000x10000 coordinates). Anywhere on this sky we can have an aircraft, identified by its position (x, y). Any aircraft can start moving to another coordinates (in straight line).
There is a single component that manages all this positioning and movement. When a aircraft wants to move, it send it a message in the form of (start_pos, speed, end_pos). How can I tell in the component, when one aircraft will move in the line of sight of another (each aircraft has this as a property as radius of sight) in order to notify it. Note that many aircrafts can be moving at the same time. Also, this algorithm is good to be effective sa it can handle ~1000 planes.
If there is some constraint, that is limiting your solution - it can probably be removed. The problem is not fixed.
Use a line to represent the flight path.
Convert each line to a rectangle embracing it. The width of the rectangle is determined by your definition of "close" (The bigger the safety distance is, the wider the rectangle should be).
For each new flight plan:
Check if the new rectangle intersects with another rectangle.
If so, calculate when will each plane reach the collision point. If the time difference is too small (and you should define too small according to the scenario), refuse the new flight plan.
If you want to deal with the temporal aspect (i.e. dealing with the fact that the aircraft move), then I think a potentially simplification is lifting the problem by the time dimension (adding one more dimension - hence, the original problem, being 2D, becomes a 3D problem).
Then, the problem becomes a matter of finding the point where a line intersects a (tilted) cylinder. Finding all possible intersections would then be n^2; not too sure if that is efficient enough.
See Wikipedia:Quadtree for a data structure that will make it easy to find which airplanes are close to a given airplane. It will save you from doing O(N^2) tests for closeness.
You have good answers, I'll comment only on one aspect and probably not correctly
you say that you aircrafts move in form (start_pos, speed, end_pos)
if all aircrafts have such, let's call them, flightplans then you should be able to calculate directly when and where they will be within certain distance from each other, or when will they be at closest point from each other or if the will collide/get too near
So, if they indeed move according to the flightplans and do not deviate from them your problem is deterministic - it boils down to solving a set of equations, which for ~1000 planes is not such a big task.
If you do need to solve these equations faster you can employ the techniques described in other answers
using efficient structures that can speedup calculating distances (quadtree, octree, kd-trees),
splitting the problem to solve the equations only for some relevant future timeslice
prioritize solving equations for pairs for which the distance changes most rapidly
Of course converting time to a third dimension turns the aircrafts from points into lines and you end up searching for the closest points between two 3d lines (here's some math)
I actually found an answer to this question.
It is in the book Real-Time Collision Detection, p. 223. It's better named, as well: Intersecting Moving Sphere Against Sphere, where a 2D sphere is a circle. It's not so simple (and I may also violate some rights) to explain it here, but the basic idea is to fix one of the circles as a point, adding its radius to the radius of the moving one. The new direction for the moving one is the sum of the two original vectors.