Sphere-Sphere Intersection, choosing right theta - java

I am working on a C++ problem where I'm trying to make a utility function that takes as input two line segments starting points in 3d space [(x,y,z) and radius r]. If the segments can be oriented such that they end at the same point, the function should return true and print out that point. If there are multiple orientations that would produce a common endpoint, the function should choose the one that is furthest in the direction indicated by hint_direction.
The function receives these values:
bool func(
point3d position_0, // origin of first line segment.
float length_0, // length of first line segment.
point3d position_1, // origin of second line segment.
float length_1, // length of second line segment.
vector3d hint_direction, // in the event there are multiple solutions, return the one furthest in this direction.
point3d *out_common_end_position) // if result is true, point where both line segments can be oriented to end. otherwise uninitialized.
I have been following some guides online which lay out how to do this such as this: https://gamedev.stackexchange.com/questions/75756/sphere-sphere-intersection-and-circle-sphere-intersection.
I was able to successfully get all the intersecting points, but I cannot figure out how to get a point that is furthest in the hint direction.
I thought I might be able to use the intersection point between circle and hint_direction and get a angle of that point, but I cannot figure out how to do so.

As Spektre correctly pointed out I missed the 3D portion of your question, so the 4 options are the following:
no intersection (or one sphere completely lies within the other)
a single point (spheres touch from inside or outside)
a normal intersection forming a circle
both spheres overlap completely, i.e. they have the same origin and the same radius
Since the normal intersection would form a circle you'd want to project the direction hint onto that circle and calculate the intersection between the circle and the projected vector to get the farthest intersection point.

Related

Collision between a moving circle and a stationary circle

So what I'm trying to make is a function where I input the location of a moving circle and its target location, the location of a stationary circle and both of their radiuses, and I want to return the point at which they intersected if they did and the target location if they didn't.
The starting position of both circles, their radiuses and the end position of the moving circle are all known.
In this example I want to in a single frame move circle A from point Start to point End, if A collides with B I want to return the point where they touch closest to Start. In between Start and End there is a vector that can be calculated through End-Start which I'll call V and use in my attempt at solving this.
I will to refer the point Start as S and the position of B as P, the radius of A as Ra and the radius of B as Rb as seen in this image: variables.
So this is how far I've got:
When the two circles are just about touching the distance between them should be their radiuses combined like in this image: radiuses combined.
Therefore Ra+Rb = length of P-C which becomes (Ra+Rb)² = (P.x-C.x)² + (P.y-C.y)² according to Pythagoras (I squared both sides to remove the square root)
C can be described as the point S plus the vector V scaled by some constant t, C = S + tV so for example the point half way between Start and End could be described as S + 0.5V.
So the equation would then become (Ra+Rb)² = (P.x-(S.x+tV.x))² + (P.y-(S.y+tV.y))²
I have not gotten further than that since I cant isolate t which I need to find C
Any help is greatly appreciated! Sorry if I made any mistakes, its my first time posting.
(If anyone has code in Java for this that would be amazing)
You would probably have received a better answer for your question over at math.stackexchange.com, since this really seems to be a question about the maths related to your program.
But anyhow, this problem can be solved in a few steps:
1. Projection of a point onto a line:
Let Q be a projected point on V. Is the distance P-Q larger than the sum of Ra and Rb? If so, there is no collision, else proceed:
2. Pythagoras:
You now know the distance P-Q, and as you noted yourself, the circles will intersect at a distance Ra+Rb - if they collide. So, now if we find the distance Q-C, we can find where C is, since we already know where Q is from the projection onto V.
So, what is the distance Q-C: Sqrt((B-Q)^2 - (B-C)^2)
3. Find C by translating Q by distance Q-C
Now, you just need to make sure that you translate Q in the right direction: toward S.
As for the coding part of your problem, there was never a question asked, so there's nothing to respond to...
[Edit: fixed #3 Translate->Find]

Polygon Z Ordering

I am currently trying to write a 2D only 3D "renderer" that uses polygons only.
Before rendering, I order the polygons by calculating one Z value as following:
double z = (v1.getZ()+v2.getZ()+v3.getZ());
My polygons consist of each three vectors (X,Y,Z)
Then I sort the polygons so I then can use the painters algorithm approach:
int i = 0;
for (Poly polygon : polyZSort) {
if(polygon.getRealZ()>z) {
break;
}
i++;
}
polyZSort.add(i, polygon);
The rendering then is as simple as:
for (Poly poly : polyZSort) {
OVector v1 = poly.getV1();
v1 = form.doTransform(v1);
OVector v2 = poly.getV2();
v2 = form.doTransform(v2);
OVector v3 = poly.getV3();
v3 = form.doTransform(v3);
g2d.setColor(poly.getColor());
Polygon pl = new Polygon();
pl.addPoint(getX(v1.getX()),getY(v1.getY()));
pl.addPoint(getX(v2.getX()),getY(v2.getY()));
pl.addPoint(getX(v3.getX()),getY(v3.getY()));
g2d.fillPolygon(pl);
// black border line
g2d.setColor(Color.BLACK);
g2d.drawLine(
getX(v1.getX()),
getY(v1.getY()),
getX(v2.getX()),
getY(v2.getY())
);
g2d.drawLine(
getX(v2.getX()),
getY(v2.getY()),
getX(v3.getX()),
getY(v3.getY())
);
g2d.drawLine(
getX(v3.getX()),
getY(v3.getY()),
getX(v1.getX()),
getY(v1.getY())
);
}
This works, even with multiple cubes (but only most of the time):
However in certain positions, the ordering seems to be wrong:
Does anybody know where the problem may be?
Here a video of the "glitch" https://vimeo.com/552355610
You are missing important steps ... This is how it should be done:
input is list of 3D triangles, output is list of 3D triangles
The output list is empty at start
"2D" screen project each processed triangle and leave it with original z values
so its still 3D , but x,y are screen positions and z is "original" z value in camera coordinate system.
check each processed triangle after projection if it intersects any triangle already in output list.
If no intersection occurs then simply add this triangle to output list as is.
if it does intersect you need to re-triangulate all intersected and new triangle so no intersections occur. And add these new triangle(s) to output list (while removing the original intersecting triangles from output list).
Here exampel of 2 overlaping triangles:
as you can see it can create quite a lot of new triangles and usually new triangle intersects more than just one triangle so you need to do this recursively for each triangle of the overlapped parts or create a list of all intersecting triangles first and retriangulate them at once ...
after whole scene is processed Z sort the output list by mid point z value
this step you already got.
render the sorted output list using 2D triangle rendering
this step you already got.
As you can see you need a buffer of size depending on number of triangles in scene and overlaps. Also this method is very complicated (and not very good choice for rookie programmers) and usable only for very simple scenes. For more complex ones is much easier and faster to use Z buffer. However that one require along with the buffer itself also 3D rendering of triangle (so one more interpolation and per pixel condition). As you can see its O(1) instead of the O(n.log(n)) for z sort.

How can I get the intersection of a line and a polygon?

So I have a list of points here.
private List<Point> points;
and the points class just has x,y,z values but only x,y are used in this case. So I store all the polygon points in there
and then I have this method here.
public Point getIntersection(Crossable aLine) {
}
And aLine is just two points so it has 4 values total for x1,x2,y1,y2 etc.
I want to get the intersection of the Line and the polygon, I have no understanding of how to get the intersection since there are a lot of variables involved and special cases. Any ideas?
Consider every two adjacent points of the polygon as a line and check to see if it intersects with your line. You need a loop to go through them all.

Detect click on a line

I would like to find a way to know if I click on a line. I have a standard 2D plan with square for example and a line between both. I would like to detect when I click on the line.
The line can be horizontal, vertical or with an angle.
I have those information on the line :
-Starting coordinate (x,y)
-Ending coordinate (x,y)
-The mouse click position (x,y)
I might be able to get the angle with tan().
I found this solution but i can't add mouse event: How to select a line
Thanks you.
Let S and E be the segment endpoints and M the mouse.
The vector that joins M to a point along SE is given by MS+t.SE, where 0<t<1.
Square this vector to get its (squared) length: d²=SE²t²+2(SE.MS)t+MS²,
and find the position of the minimum, t=-(SE.MS)/SE².
If t<=0, the shortest distance is to S, hence d²=MS².
If t>=1, the shortest distance is to E, hence d²=ME².
Else, the shortest distance is to a point on the segment, and d²=MS²-(SE.MS)²/SE².
There is no need to take the square root, because d<Tolerance is equivalent to d²<Tolerance².
Have a look at this answer:
Shortest distance between a point and a line segment
They calculate the shortest distance from a point to a segment.
Having calculated this value, you can accept or reject the mouse click event:
if ( distanceToSegment(...) < threshold && mouseClicked()) {
// insert code here
}
The threshold will depend on how precise you want the user to be.

determine whether line is entirely within path2d shape (in java)

I'm looking for the easiest/fastest (computationally) way to determine whether a shape, more specifically a GeneralPath object, contains any given line segment (of type Line2D.Double).
GeneralPath has methods to determine whether a point or a rectangle is contained, but not a line (that I can find). The line can be at a slant, so I can't just model a really thin rectangle. One point in the line will definitely be inside the shape, but I need to check the rest of the line segment. So potentially, I could also check to see if the line intersects any of the boundary edges, but I'm not sure how that would look just given the shape and the line.
Does your GeneralPath contain straight line segments or quadratic or bezier segments? This matters a lot. The algorithm for the straight line is the most straightforward:
Iterate over all points in the path. If two consecutive points are on opposite sides of the line, you have a potential crossing. Then you need to check if the line segment end point is inside or outside the shape relative to the potential crossing, which you get by solving for the intersection of two points (the line and the line formed by the two consecutive points) and seeing if the result is contained in your line segment.
Unfortunately, the curved paths can have two consecutive points with a parenthesis shape between them ")", which your line can pass through while still keeping the iterable points on the same side. If you can get the format with two end points and a single (double) control point(s) that form a bounding triangle (quadrilateral), you can get easy simple solutions (since the curve is guaranteed to fit inside the triangle/quad formed by the three/four points, as long as the line doesn't intersect the triangle/quad, you are good). Unfortunately, this has an ugly part as well--if the line does intersect the triangle/quad, you aren't guaranteed anything and have to check closer. As a double unfortunate, I don't know a technique other than normalizing the coordinate system and solving for the zeroes. And that's something I'd look up in a book that I can't seem to find (or wait until another nice SO poster comes along).
... actually, since the curvature properties of the shapes are invariant under rotation, for the closer inspection part you can just rotate the curve points (whether 3 or 4) to be axis aligned. Then do your skinny rectangle trick. That's probably not the cleanest, but it's the most obvious trick.
Come to think of it, why not do the rotation of all the points in the first place? The whole intersection problem is rotation invariant. That would save a lot of code. Just axis-align the line, apply the transformation to the shape, and do your cheeky rectangle trick.
Unless I am missing something, why can't you check if the the path contains x1,y1 and x2,y2 and AND the two as follows:
generalPath.contains(line.getX1(),line.getY1()) &&
generalPath.contains(line.getX2(),line.getY2())

Categories

Resources