Intersect polygon with rectangle and create lines (section cut) - java

I need an algorithm to intersect a (potentially non-convex) polygon with a rectangle. The rectangle will be parallel to the xy-plane, but the polygon could be any orientation.
Furthermore, I don't just need a true/false result, but also the exact points where the polygon intersects the rectangle, so that I can draw lines where the polygon overlaps the rectangle. For non-convex polygons, this could result in two or more lines of intersection.
This would be for a section-cut module that can slice a set of polygons and create a 2D "cut" where the shapes intersect the "plane," specified by a z-value.
I'm developing in Java, so if Java3(2)D has any built-in methods to help, that would be ideal.
Any help/pointers in the right direction would be greatly appreciated!
Here's a picture... I want the red line as a result of the intersection:

This should find all the intersecting segments, for any arbitrary polygon.
Consider the polygon as an ordered collection of edges AB,BC,CD,etc, where the 'direction' from each edge's first point to its second point is 'clockwise'. That is, if we're looking at point A, point B is the next point when moving clockwise.
The method is to find an edge of the polygon that crosses the plane and then find the next segment, moving clockwise, that crosses back to the original side of the plane. The two points where these segments intersect the plane form the endpoints for an intersecting segment. This is repeated until all the polygon's edges have been checked.
Be advised not all segments are necessarily within the polygon if it is concave.
let P be any point on the polygon.
TOP:
while (P has not been checked)
mark P as having been checked.
let f be the point following P, clockwise.
if (P and f are on opposite sides of the plane) then
Continuing from f clockwise, find the next point Y that is on
the same side of the plane as P.
Let z be the point counter-clockwise from Y.
(note - Sometimes z and f are the same point.)
let S1 be the point where P,f intersects the plane
let S2 be the point where Y,z intersects the plane
if (segment (S1,S2) is inside the polygon)
add (S1,S2) to a 'valid' list.
let P = Y
else
let P = f
endif
else
let P = f
endif
endwhile
This algorithm is worth what you paid for it. :-)

Related

Draw padding for convex hull java

I already got the set of points that define that convex hull. How can I add a kind of padding to them, so that all the points is inside? I am trying to draw the red line
What I'd try to create an outline offsetted from a polygon by distance d:
Consider a straight line segment between each pair of consecutive points (the original convex hull).
Offset each segment by d along its perpendicular to the outside. The offsetted segments have gaps between ends.
For each pair of consecutive offsetted line segments, add a segment of a circle such that it both segments are its tangents; its radius should be d. It's easy to do: draw perpendiculars at the ends of both segments; their intersection is the center of the circle.
Now you have a sequence of interspersed straight lines and arcs. It should be the outline you're seeking.
To work comfortably, you'd need these functions:
Find the equation of the straight line by two points (store it as an object with 3 float fields);
Find an equation of a perpendicular line by a line equation and a point;
Find the point of intersection of two lines, given their equations.

How to find the corresponding subtriangle of a position inside a rectangle

I have a dynamic rectangle in which 4 subtriangles (t0-t3) are created (by adding the diagonals from the vertices). When given a certain x|y coordinate what is the fastest way to find the corresponding triangle?. The rectangle has a specific position and dimension. I only need the right "id" so not the vertices of the triangle, so for example in the graphic when p1 is given as position 0 should be returned, 3 at p2 and 2 at p3, ...
One possible solution of course would be to create the triangles and query if the point is contained in one of them, but it feels like a very complicated solution for something that simple.
I also thought about creating a vector from the center and measuring the angle but it also seems complicated in a rectangle with varying dimensions.
Example Rectangle
Consider the following:
Let the bottom left corner of the rectangle be (0,0) and the top right corner be (1,1). Now, the two lines that form the triangles are defined as:
y = x and y = 1-x
For every point except (.5,.5) we have a ternary conditional for a given x or y. For example, given that x = .2, we know that:
if y < .2, we're in the bottom triangle (t2),
elif .2 < y < .8, we're in the left triangle (t3),
else, we're in the top triangle (t0).
Hopefully this helps without explicitly giving you the code.

Java: plot points based on distances

I need to plot a group of points based on distances. I have three unknown points X, Y, and Z. I then get another unknown point (A) and its distances from the originals (AX, AY, AZ). I will continue getting points and distances (B, BX, BY, BZ; C, CX, CY, CZ) etc.
My question is whether its possible to plot all of the points. If so, how many points would I need for an exact plot map? What about an approximate map?
This is similar to this question but I get a different set of distances and am not limited to the original number of points.
Also, if it would help I could add more points to the X, Y, Z group which would give me more distances for A, B, etc.What I don't know until it's been somehow calculated are any of the Distances XY, XZ, YZ, AB, AC, etc.
I am not sure exactly what you mean by exact plot map or approximate plot map. I think I might know but I am not sure. But plotting all points in this case, to me is not possible if the user can continue to "add more points to the XYZ group", which is dynamic. It would sound like you need to know what the user is going to plot before he does. Now if all this is static, it is possible
I assume you use 2D space
If it is 1D then 2 points are enough (not identical !!!).
If 2D then 3 distances is enough but the points used must not lay on the same line !!!
position/orientation of the plot
for relative plot are above conditions enough if you want also the exact orientation and position then you need to know exact position of first 3 points otherwise your plot will look the same but can be offseted,rotated and mirrored to original geometry.
knowing 1 point eliminates offset
knowing 2 point eliminates rotation
knowing 3 point eliminates mirroring
[notes]
you need n+1 points for n-D coordinate system
[edit1] equations
original question text did not contain any equations need but comments requires it so here are some:
You will need intersection point between two hyperspheres (in 2D circles, in 3D spheres,...) so look here:
circle-circle intersection
Cast circle from each point as center with radius equal to the distance from that point. Find out intersection point that is the same between all combinations of circles (0,1),(0,2),(1,2)
Yellow intersection is the same in all 3 combinations so that is the next point or for 2D just solve this system:
(x-x0)^2+(y-y0)^2=l0^2
(x-x1)^2+(y-y1)^2=l1^2
(x-x2)^2+(y-y2)^2=l2^2
where x,y is the intersection point, xi,yi are center of circle and li is distance from that point.
The first option should be simpler and more accurate if done right but need some knowledge on vector and trigonometry math. You will need to add rotation or compute on vectors and use perpendicular vector feature in 2D
V(x,y) -> V0(+y,-x),V1(-y,+x)
where V0,V1 are perpendicular to V

Collision Handling... Confused where to go

So, I'm working on a 2D physics engine, and I have an issue. I'm having a hard time conceptualizing how you would calculate this:
Take two squares:They move, collide, and at some vector based off of the velocity of the two + the shape of them.
I have two vector lists(2D double lists) that represent these two shapes, how does one get the normal vector?
The hit vector is just (s1 is the first shape, s2 the second) s2 - s1 in terms of the position of the center of mass.
Now, I know a normal vector is one perpendicular to an edge, and I know that you can get the perpendicular vector of a line by 90 degrees, but what edge?
I read in several places, it is the edge a corner collided on. How do you determine this?
It just makes no sense to me, how you would mathematically or programmatically determine what edge.
Can anyone point out what I'm doing wrong in my understanding? Sorry for providing no code to explain this, as I'm having an issue writing the code for it in the first place.
Figure1: In 2D the normal vector is perpendicular to the tangent line:
Figure2: In 3D the normal vector is perpindicular to the tangent plane
Figure3: For a square the normal vector is easy if you are not at a corner; It is just perpendicular to the side of the square (in the image above, n = 1 i + 0 j, for any point along the right side of the square).
However, at a corner it becomes a little more difficult because the tangent is not well-defined (in terms of derivatives, the tangent is discontinuous at the corner, so perpendicular is ambiguous).
Even though the normal vector is not defined at a corner, it is defined directly to the left and right of it. Therefore, you can use the average of those two normals (n1 and n2) as the normal at a corner.
To be less technical, the normal vector will be in the direction from the center of the square to the corner of the collision.
EDIT: To answer the OP's further questions in the chat below: "How do you calculate the normal vector for a generic collision between two polygons s1 and s2 by only knowing the intersecting vertices."
In general, you can calculate the norm like this (N is total verts, m is verts inside collision):
vcenter = (∑N vi) / N
vcollision = (∑m vi) / m
n = vcollision - vcenter
Fig. 1 - vcollision is only a single vertex.
Fig. 2 - vcollision is avg of two verts.
Fig. 3 - vcollision for generic polygon intersection.

Using a QuadTree to get all points within a bounding circle

I have a set of 100 to 200 points (x,y). I have to check which ones fall within a particular distance of the others. The particular distance is fixed for the entire program, say 50. Say point 1 falls within the range of points 5,7,25,90,96,105...etc. Similarly point 2 falls within range of 23,45, etc...
Storing objects for locating by x,y coordinates
Here QuadTree is suggested, but it can be used to get all the points within a bounding rectangle. But how to get all points within a bounding circle? there is a method which returns a point closest to a lat/long within a maximum distance, but how to get all the points within the distance?
http://openmap.bbn.com/doc/api/com/bbn/openmap/util/quadtree/QuadTree.html#QuadTree(float, float, float, float, int)
one way maybe to remove each point from the tree as I get it, then query for the closest point again, until i get null. is that the only way?
Suppose that you have a circle centered at (x, y) with radius r and want to find all points in a quadtree that are in the circle. One idea is as follows:
Construct the bounding box inscribing the circle. This is the smallest rectangle containing the circle, which has upper-left corner (x - r, y - r) and lower-right corner (x + r, y + r). Any point in the circle must also be in the square, but not the other way around.
Query the quadtree for the set of points lying in that rectangle. Let these points be P.
For each point in P which is known to be in the rectangle, see if it is also in the circle. You can do this by checking whether the distance from that point to (x, y) is no greater than r. In other words, given a point (x0, y0), you would compute (x - x0)2 + (y - y0)2, and if this value is less than or equal to r2, then the point is contained in the circle.
Although this may seem inefficient, it's actually quite fast. The ratio of the area of the square to the area of the circle is 4 / π &approx; 1.27. In other words, assuming that your points are distributed somewhat evenly, you'll only find about 27% more points than you need to.

Categories

Resources