I have two circles joined together like this:
And I have a point inside the shape, and I would like to cast a ray in a direction from that point onto the shape. In order to retrieve the casted position on the edge of the shape.
My first thought will be to raycast with the 2 segments joining the 2 circles. And if there is no success hit, I'll raycast with the 2 circles and take the farthest hit position. Is there a better solution? More efficient computation-wise?
Thank you for your answers
Is suppose that you have direction vector of ray D=(dx, dy) and source point is inside of capsule
If you have central axis, use it's direction vector A, otherwise get direction vector S, S of any segment.
At first decide what segment might be intersected: get cross product A x D or S x Dand look at it's sign. Positive sign denotes that you have to check only intersection with the "left" segment, negative one - intersection with the "right" segment.
Related
I'm having troubles figuring out an algorithm to solve the following problem:
I want the user to be able to snap the rectangle (Could be any type of polygon) to the 4 corners of the polygon such that it's as far inside the polygon as it can be.
What I'm trying so far:
Allow user to get the object.
Find the nearest vertice on the polygon to the rectangle.
Find the furthest vertice on the rectangle to the polygon's nearest vertice.
Use a plane to find the first intersection point with the furthest rectangle's point to the polygon's point.
Shift up or down using the corresponding x/y plane based on whether the furthest point is further in the x/y coordinate.
Keep repeating the steps above until everything is inside.
As long as the enclosing polygon is convex, you can write this as a linear programming problem and then apply https://en.wikipedia.org/wiki/Simplex_algorithm to find the answer. The smaller polygon you are putting inside can be as complicated as you want.
Your inequalities are all of the conditions to make sure that each vertex of the smaller polygon is inside of the larger. You don't have to be clever here, there is no cost to extra inequalities that don't come into play.
The function to optimize is constructed as follows. Look at the interior angle of the vertex you are trying to get close to. Draw a coordinate system at that point with one axis pointing directly into the polygon (call that axis y) and the other at right angles to the first (call that axis x). You want to minimize the y value of the nearest vertex on the polygon you are putting in. (Just put the polygon you are putting in in the middle, and search for the nearest vertex. Use that.
The solution that you find will be the one that puts the two vertices as close together as possible subject to the condition that the smaller polygon has to be inside of the larger.
What algorithm to use so that we can determine that if the red dot belongs to Area1 or Area2.
my original idea was to divide the polygons into triangles using consecutive points and then use a known algorithm to determine if a point belongs to one of these triangles however there is a problem shown in the figure.p4 p5 p6 are point in Area 1 but they make a triangle in area 2.
Continue inifite ray from red point to any direction. Count intesections of such ray with any polygon. Even count of intersections indicates that point lies outside of polygon
You can use the idea of the polygon filling algorithm for that. If you know the vertices of a polygon, you can lay a horizontal ray through the red point and count the vertices it intersects. If the count is even, it is outside, otherwise it is inside.
If you imagine coming from the far left along that ray, the first intersection is entering the polygon, the second is leaving it, the third is entering again... and so on. So if the number is odd (1,3,5,...) you are inside the polygon when you hit the point, otherwise you are outside.
Here is the idea -
Draw a horizontal line to the right of red point and extend it to infinity
Count the number of times the line intersects with polygon edges.
A point is inside the polygon if either count of intersections is odd or
point lies on an edge
See Check if a point lies inside or outside a polygon.
I have a list of coordinates (latitude, longitude) that define a polygon. Its edges are created by connecting two points with the arc that is the shortest path between those points.
My problem is to determine whether another point (let's call it U) lays in or out of the polygon. I've been searching web for hours looking for an algorithm that will be complete and won't have any flaws. Here's what I want my algorithm to support and what to accept (in terms of possible weaknesses):
The Earth may be treated as a perfect sphere (from what I've read it results in 0.3% precision loss that I'm fine with).
It must correctly handle polygons that cross International Date Line.
It must correctly handle polygons that span over the North Pole and South Pole.
I've decided to implement the following approach (as a modification of ray casting algorithm that works for 2D scenario).
I want to pick the point S (latitude, longitude) that is outside of the polygon.
For each pair of vertices that define a single edge, I want to calculate the great circle (let's call it G).
I want to calculate the great circle for pair of points S and U.
For each great circle defined in point 2, I want to calculate whether this great circle intersects with G. If so, I'll check if the intersection point lays on the edge of the polygon.
I will count how many intersections there are, and based on that (even/odd) I'll decide if point U is inside/outside of the polygon.
I know how to implement the calculations from points 2 to 5, but I don't have a clue how to pick a starting point S. It's not that obvious as on 2D plane, since I can't just pick a point that is to the left of the leftmost point.
Any ideas on how can I pick this point (S) and if my approach makes sense and is optimal?
Thanks for any input!
If your polygons are local, you can just take the plane tangent to the earth sphere at the point B, and then calculate the projection of the polygon vertices on that plane, so that the problem becomes reduced to a 2D one.
This method introduces a small error as you are approximating the spherical arcs with straight lines in the projection. If your polygons are small it would probably be insignificant, otherwise, you can add intermediate points along the arcs when doing the projection.
You should also take into account the polygons on the antipodes of B, but those could be discarded taking into account the polygons orientation, or checking the distance between B and some polygon vertex.
Finally, if you have to query too many points for that, you may like to pick some fixed projection planes (for instance, those forming an octahedron wrapping the sphere) and precalculate the projection of the polygons on then. You could even create some 2d indexing structure as a quadtree for every one in order to speed up the lookup.
The biggest issue is to define what we mean by 'inside the polygon'.
On a sphere, every polygon (as long as the lines are not intersecting) defines two regions of the sphere. Both regions are equally qualified to be called the inside of the polygon.
Consider a simple, 1-meter on a side, yellow square around the south pole.
You can think of the yellow area to be the inside of the square OR you can think of the square enclosing everything north of each line (the rest of the earth).
So, technically, any point on the sphere 'validly' inside the polygon.
The only way to disambiguate is to select which side of the polygon you want. For example, define the interior to always be the area to the right of each edge.
I'm struggling to find a rock solid solution to detecting collisions between a circle and a circle segment. Imagine a Field of View cone for a game enemy, with the circles representing objects of interest.
The diagram at the bottom is something I drew to try and work out some possible cases, but i'm sure there are more.
I understand how to quickly exlude extreme cases, I discard any targets that don't collide with the entire circle, and any cases where the center of the main circle is within the target circle are automatically true (E in the diagram).
I'm struggling to find a good way to check the rest of the cases. I've tried comparing distances between circle centers and the end points of the segments outer lines, and i've tried working out the angle of the center of the target circle from the center of the main circle and determining whether that is within the segment, but neither way seems to catch all cases.
Specifically it seems to go funky if the target circle is close to the center but not touching it (somewhere between E and B below), or if the segment is narrower than the target circle (so that the center is within the segment but both edges are outside it).
Is there a reliable method for doing this?
Extra info: The segment is described by position P, orientation O (whose magnitude is the circle radius), and a view size, S.
My most successful attempt to date involved determining the angles of the vectors ca1 and ca2, and checking if either of them lies between the angles of vectors a1 and a2. This works for some cases as explained above, but not situations where the target circle is larger than the segment.
Edit 2
After implementing the best suggestion from below, there is still a false positive which I am unsure how best to eliminate. See the pink diagram below. The circle in the lower right is reporting as colliding with the segment because it's bounds overlap both half spaces and the main circle.
Final Edit
After discovering another edge case (4th image), i've settled on an approach which combines the two top answers from below and seems to cover all bases. I'll describe it here for the sake of those who follow.
First exclude anything that fails a quick circle-to-circle test.
Then test for collision between the circle and the two outer lines of the segment. If it touches either, return true.
Finally, do a couple of point-to-halfspace tests using the center of the circle and the two outer lines (as described by Gareth below). If it passes both of those it's in, otherwise return false.
A. Check if it is intersecting the whole cirlce.
B. Check if it is intersecting either of the straight segment lines.
C. If not, check if the angle between the circle centres lies in the angular range of the segment (dot product is good for this).
Intersection requires A && (B || C)
A circular segment (with central angle less than 180°) is the intersection of three figures: a circle, and two half-planes:
So a figure intersects the circular segment only if it intersects all three of these figures. [That's only if but not if; see below.]
Circle/circle intersection is easy (compare the distance between their centres with the sum of their radii).
For circle/half-plane intersection, represent the half-plane in the form p · n ≤ k (where p is the point to be tested, n is a unit vector that's normal to the line defining the half-plane, and k is a constant). Then a circle with centre x and radius r intersects the half-plane if x · n ≤ k + r.
(If you need to handle a circular segment with central angle greater than 180°, split it into two segments with central angle less than 180°. If I understand your problem description correctly, you won't need to do this, since your field of view will always be less than 180°, but it's worth mentioning.)
Edited to add: as pointed out by beeglebug, a circle can intersect all three figures without intersecting their intersection. Oops. But I believe that this can only happen when the circle is behind the centre of the segment, as in the diagram below, and in this case we can apply the separating axis test for convex figures.
The separating axis theorem says that two convex figures fail to intersect if there exists a line such that one figure falls entirely on one side of the line, and the other figure on the other.
If any separating axis exists in this case, then the axis that's perpendicular to the line between the centre of the circle and the centre of the segment is a separating axis (as shown).
Let the centre of the segment be at the origin, let the circle have centre x and radius r, and let the two half-planes have (outward) normals n₁ and n₂. The circle is "behind" the segment if
x · n₁ > 0 and x · n₂ > 0
and the axis separates it from the segment if
|x| > r
given a 3D grid, a 3d point as sphere center and a radius, i'd like to quickly calculate all cells contained or intersected by the sphere.
Currently i take the the (gridaligned) boundingbox of the sphere and calculate the two cells for the min anx max point of this boundingbox. then, for each cell between those two cells, i do a box-sphere intersection test.
would be great if there was something more efficient
thanks!
There's a version of the Bresenham algorithm for drawing circles. Consider the two dimensional place at z=0 (assume the sphere is at 0,0,0 for now), and look at only the x-y plane of grid points. Starting at x= R, y=0, follow the Bresenham algorithm up to y = y_R, x=0, except instead of drawing, you just use the result to know that all grid points with lower x coordinates are inside the circle, down to x=x_center. Put those in a list, count them or otherwise make note of. When done with two dimensional problem, repeat with varying z and using a reduced radius R(z) = sqrt(R^2-z^2) in place of R, until z=R.
If the sphere center is indeed located on a grid point, you know that every grid point inside or outside the right half of the sphere has a mirror partner on the left side, and likewise top/bottom, so you can do half the counting/listing per dimension. You can also save time running Bresenham only to the 45 degree line, because any x,y point relative to the center has a partner y,x. If the sphere can be anywhere, you will have to compute results for each octant.
No matter how efficiently you calculate an individual cell being inside or outside the sphere, your algorithm will always be O(radius^3) because you have to mark that many cells. DarenW's suggestion of the midpoint (aka Bresenham) circle algorithm could give a constant factor speedup, as could simply testing for intersection using the squared radius to avoid the sqrt() call.
If you want better than O(r^3) performance, then you may be able to use an octree instead of a flat grid. Each node of the tree could be marked as being entirely inside, entirely outside, or partially inside the sphere. For partially inside nodes, you recurse down the tree until you get to the finest-grained cells. This will still require marking O(r^2 log r) nodes [O(r^2) nodes on the boundary, O(log r) steps through the tree to get to each of them], so it might not be worth the trouble in your application.