So, I'd like to figure out a function that allows you to determine if two cubes of arbitrary rotation and size intersect.
If the cubes are not arbitrary in their rotation (but locked to a particular axis) the intersection is simple; you check if they intersect in all three dimensions by checking their bounds to see if they cross or are within one another in all three dimensions. If they cross or are within in only two, they do not intersect. This method can be used to determine if the arbitrary cubes are even candidates for intersection, using their highest/lowest x, y, and z to create an outer bounds.
That's the first step. In theory, from that information we can tell which 'side' they are on from each other, which means we can eliminate some of the quads (sides) from our intersection. However, I can't assume that we have that information, since the rotation of the cubes may make it difficult to determine simply.
My thought is to take each pair of quads, find the intersection of their planes, then determine if that line intersects with at least one edge of each of the pairs of sides. If any pair of sides has a line of intersection that intersects with any of their edges, the quads intersect. If none intersect, the two cubes do not intersect.
We can then determine the depth of the intersection on the second cube by where the plane-intersection line intersects with its edge(s).
This is simply speculative, however. Is there a better, more efficient way to determine the intersection of these two cubes? I can think of a number of different ways to do this, and I can also tell that they could be very different in terms of amount of computation required.
I'm working in Java at the moment, but C/C++ solutions are cool too (I can port them); even psuedocode since it is perhaps a big question.
To find the intersection (contact) points of two arbitrary cubes in three dimensions, you have to do it in two phases:
Detect collisions. This is usually two phases itself, but for simplicity, let's just call it "collision detection".
The algorithm will be either SAT (Separating axis theorem), or some variant of polytope expansion/reduction. Again, for simplicity, let's assume you will be using SAT.
I won't explain in detail, as others have already done so many times, and better than I could. The "take-home" from this, is that collision detection is not designed to tell you where a collision has taken place; only that it has taken place.
Upon detection of an intersection, you need to compute the contact points. This is done via a polygon clipping algorithm. In this case, let's use https://en.wikipedia.org/wiki/Sutherland%E2%80%93Hodgman_algorithm
There are easier, and better ways to do this, but SAT is easy to grasp in 3d, and SH clipping is also easy to get your head around, so is a good starting point for you.
You should take a look at the field of computer graphics. They have many means. E.g. Weiler–Atherton clipping algorithm. There are also many datastructures that could ease up the process for you. To mention AABBs (Axis-aligned bounding boxes).
Try using the separating axis theorem. it should apply in 3d as it does in 2d.
If you create polygons from the sides of the cubes then another approach is to use Constructive Space Geometry (CSG) operations on them. By building a Binary Space Partitioning (BSP) tree of each cube you can perform an intersection on them. The result of the intersection is a set of polygons representing the intersection. In your case if the number of polygons is zero then the cubes don't intersect.
I would add that this approach is probably not a good real time solution, but you didn't indicate if this needed to happen in frame refresh time or not.
Since porting is an option you can look at the Javascript library that does CSG located at
http://evanw.github.io/csg.js/docs/
I've ported this library to C# at
https://github.com/johnmott59/CGSinCSharp
Related
my program includes increasing number of objects "n", each object has a custom-shape and coordinates .
To detect collision for each object i check the distance between it and all other objects to check if its close enough for collision.
however this would make complexity too high n^(n-1).
What would be a better algorithm for collision detection for :
-simple 2D objects like circles and triangles ?
-costume object made by vertices and PShape ?
Short answer: split your world space up into spaces, then only check objects that are in the same space. Think about it this way: if you have an object that's in the upper-left corner, you don't have to check that against objects in the lower-right corner. Just other objects in the upper-left corner.
There are many ways to implement this. One of the most common approaches is a data structure called a quadtree.
Another approach would be to use a physics library that does all of the collision detection for you.
The above two approaches might be overkill if you're just doing something simple though, so it's entirely up to you.
I'm attempting to render a hemisphere in java. However, I'm wanting to render the slice that is defined by 2 angles - Azimuth and Elevation. Since I'm defining a slice, I cannot (to my knowledge) use any built in primitives. If the azimuth range is defined 0-360 and the elevation range is defined as 0-70, this will be a hemisphere with an upside-down cone-shaped hole in the top.
When rendering this inside "cone", I have chosen to do it as triangles in 5 degree increments. This means that with a 360 degree cone, there are 73 different vertices (if I did the math correctly: 360/5degree slices with the origin or tip of the cone being shared with all sides, and all other vertices shared by adjacent triangle slices)
My question:
Is it more efficient to render these as a single polygon with with many vertices, or many triangles with only 3 vertices each. If I do a single polygon, will I still have to include all three points for each triangle, or if it is a shared vertex, would I only include it once? Sorry, my graphics rendering knowledge is limited. Also sorry for being so verbose; I'm hoping someone may spot something erroneous in my thought process which may clear things up either way.
First - Use Google to find an algorithm to create a sphere that is not a primitive.
Second - Somewhere down the chain - triangles will be used. Most likely by the underlying library. But for you - it depends upon whether or not you plan to chop up the created region. If you are not going to subdivide the region further I would just make it one polygon. Actually, after thinking about it for a second - you can always divide up the polygon afterwards too. So just make it one polygon.
I thought about it some more and decided to amend this answer. There are two ways you can create a polygon in openGL. You can either create it as a triangular mesh or as an outline polygon. So if you were asking "Should I use a triangular mesh or an outline polygon" I would say use the triangular mesh. It is a lot easier to break up the triangular mesh than a polygon outline since, to break the mesh, all you have to do is to just stop at one of the points, include the last two points in the new object, and continue on down the triangular mesh. An outline polygon requires you to go both left and right around the polygon to locate the two points where the break occurs. If that is clear. If not say so.
Update: 12:05pm
When making a polygon you can use a triangular mesh or a polygon outline. The outline is mainly good for 2D whereas the triangular mesh works in both 2D and 3D systems. If you have any kind of a polygon at all bigger than just three points then it is a good idea to put them all into an array. This allows you to use the built-in routines that take an array and simply go through it to build your polygon. By putting everything into an array you also make it easier on yourself to add new points or remove points or adjust points. All you do is to change the array entry and then call the same routine to draw everything again. (Which should be just a single call to a function.)
I'm making a program that needs to detect the collision between 2 non-axis aligned boxes. My program only needs an indication if 2 non-axis aligned boxes are colliding. I would like to have the most simple and efficient algorithm possible.
Here I visualized the problem.
So as you can see squares 1,2 and 3 would return true because they collided with the green squares.
4 would return false because it isn't colliding.
I do have all the boxes of both colors in separate array lists.
Does anybody know a library or algorithm for this problem? Thanks in advance.
Check out the Area class in the java.awt.geom package.
http://docs.oracle.com/javase/6/docs/api/java/awt/geom/Area.html
I don't know how "easy" your game really is, how many shapes you'd have to check for (I'm thinking efficiency here), but if you have your different color shapes in different lists, a kind of brute force iteration may work for you. Not a clue if it would be efficient enough for you. I use box2D to tell me the collisions, but sounds like that may be overkill for you.
The brute force method I'm thinking of would be to utilize libgdx's Intersector class (check out the API, it has lots of methods). Iterate through your rectangles comparing to the others. Something like IntersectRectangles() gives you a boolean if two rectangles overlap (ie: collide).
This may be too inefficient/hacky, and a physics library may be too much. So one of the other answers provided may be the sweet spot.
A commonly-used approach involves quadtrees. There's a good write-up and tutorial here, which explains how to use quadtrees to perform collision detection in 2D space.
The general idea is that your game area will keep being partitioned by four as your add objects. Each partition is called a node and each node will maintain a reference to objects that exist in the corresponding partition. Objects are placed into nodes based on where they are in the 2D space. If a node does not fit cleanly into a partition, it is inserted into the parent node. Using this method, you don't have to perform an expensive check against every other object in your 2D space, because you can be sure that objects in different nodes (at the same level; i.e., sibling nodes) will not collide. So you only have to perform your collision detection on a small subset of objects.
Note that this just tells you which objects are occupying a certain area; it's a more efficient way to hone in on objects that are likely to be colliding. After that you have to check if the objects are actually colliding. There is another write-up here that goes over various techniques to accomplish this.
There are two algorithms/data-structures you need to consider for this problem:
A spatial data-structure to store your rotated quads, to efficiently determine which pairs of quads need to be tested against each other. Other answers have already addressed this. If the number of quads is small enough then you can just test all the red quads against all the green quads, which is O(m * n).
An algorithm to perform the actual test of one rotated quad against another. One of the simplest is the Separating Axis Theorem.
The basic idea behind the SAT is that if you can find at least one line where all the points of one convex object are on one side of it, and all the points of the other are on the other side, then the two are not colliding. The potential lines that you need to test are just the edges of both of the objects.
To implement it you need to implement a point-line test to tell you which side of an edge a point is on. This is done by calculating the normal to the edge, and then calculating the dot product of the edge normal and a vector from a point on the edge to the point you are testing. The sign of the dot product tells you which side the point is on (positive means the outside the edge, for an outward pointing normal). Whether you count zero (on the line) as outside or inside depends on whether you want objects that are just touching but not penetrating to count as a collision, if you do then the dot product must be greater than zero to count as outside.
For example if the points on objects are in clockwise order, and edgeA and edgeB are the two points of an edge on one object, and pointC is a point on the other object, the test is done like this (not using function calls, to show the math):
boolean isOutsideEdge(PointF edgeA, PointF edgeB, PointF pointC)
{
float normalX = edgeA.Y - edgeB.y;
float normalY = edgeB.X - edgeA.x;
float vectorX = pointC.x - edgeA.x;
float vectorY = pointC.y - edgeA.y;
return (normalX * vectorX) + (normalY * vectorY) > 0.0f;
}
Then the algorithm is:
For each edge on quad A, if all the corner points on quad B are on the outward facing side of the edge, then A and B are not colliding, stop processing and return false.
For each edge on quad B, if all the corner points on quad A are on the outward facing side of the edge, then A and B are not colliding, stop processing and return false.
If all those tests have been performed and none have returned false, then A and B are colliding, so return true.
The SAT can be generalized to arbitrary convex polygons.
So I decided to go with box2d in the end. This was the best solution because of the diffrent mask-qualifiers, the objects didn't collide but it could be easily checked wether they should be colliding.
I had to make my own contactlistener that overrides the default contactlistener. Here I could do anything if any 2 objects collided.
Thanks everyone for the help.
I tried to find out thousands of point in million polygon via web services .At first i implemented the algorithm(Point in polygon) in java ,but it take a long time .And then i split the table in mysql and tried to using the multiple thread to solve it ,but still inefficiently. Is there any faster algorithm or implementation for solve this?
Plus description about the polygon. 2D ,static,complex polygon(also with hole).
Any Suggestion will be appreciate.
Testing a point against a million polygons is going to take a lot of time, no matter how efficient your point in polygon function is.
You need to narrow down the search list. Start by making a bounding box for each polygon and only selecting the polygons when the point is within the bounding box.
If the polygons are unchanging you could convert each polygon to a set of triangles. Testing to see if a point is in a triangle should be much faster than testing to see if it's in an arbitrary polygon. Even though the number of triangles will be much larger than the number of polygons, it might be faster overall.
If the collection of polygons is static it may be helpful to first register them onto a spatial data structure - an R-tree might be a good choice, assuming that the polygons do not overlap each other too much.
To test a point against the polygon collection the enclosing leaf in the tree would first be found (an O(log(n)) style operation) and then it would only be necessary to perform the full point-in-polygon test for the polygons that are associated with the enclosing leaf.
This approach should greatly speed up each point test, but requires an additional setup phase to build the R-tree.
Hope this helps.
If you deal with millions of polygons, you need some kind of space partitioning, or it's gonna be slow, no matter how optimized your hit-test function is or how many threads work on solving your query.
What kind of space partitioning ? it depends:
2D? 3D?
Is your polygon set static? If not, do it changes frequently?
What kind of request are you doing on this set?
What kind of polygon is it? Triangle? Convex? Concave? Complex? With holes?
We need more information to help you.
EDIT
Here is a simple space partitioning scheme.
Suppose there is a Cartesian grid over your 2D space with a given step.
When you add a polygon:
Compute its bounding box
Find all the grid cells that intersect with the bounding box
For each cell, add a line in a special table.
The table looks like this: cell_x, cell_y, polygon_id. Add the proper indexes (at least cell_x and cell_y)
Of course, you want to choose your grid step so most of the polygons lay in less than 10 cells, or else your cell table will quickly becomes huge.
It's now easy to find the polygons at a given point:
Compute in which cell your point belongs
Get all polygons associated to this cell
For each polygon, use your hit-test function
This solution is far from optimal, but easy to implements.
I thik here is the case where divide and conquer would do, you could try making subpolyons or simplifying some of the poonts, maybe try an heuristic approach, there are my 5 cents.
I have two geo-spatial simple convex polygon areas, in latitudes and longitudes (decimal degrees) that I want to compute using Javas Polygon class. I basically want to see if these two lat,long polygons intersect, and to calculate the areas (in sq meters) of both.
Now java.awt.Polygon class only uses x,y co-ordinate system, but I need to use lats,longs.
How can I do this, and/or is there any other classes/libraries available?
Why not use Polygon class multiplying coordinates for 10^n making them integers? Polygon accepts arrays of int as points.
Just an Idea
All you need to do is convert from spherical to rectangular coordinates if you think that really matters.
I'm not sure that it does, because the java.awt.Polygon is merely a data structure holding for pairs of values. If you read the javadocs, they say
The Polygon class encapsulates a description of a closed, two-dimensional region within a coordinate space. This region is bounded by an arbitrary number of line segments, each of which is one side of the polygon. Internally, a polygon comprises of a list of (x,y) coordinate pairs, where each pair defines a vertex of the polygon, and two successive pairs are the endpoints of a line that is a side of the polygon. The first and final pairs of (x,y) points are joined by a line segment that closes the polygon.
They happen to label those points as x and y, which makes all of us think rectangular coordinates, but they need not be from your point of view. A bug on the service of your sphere would view it as a 2D space. Your radius is large and constant. You just can't count on using any of Polygon's methods (e.g., contains(), getBounds2D(), etc.)
In this case, the important thing is your area calculation. You can use a Polygon for your area calculation, storing lats and longs, as long as you view Polygon as a data structure.
You might also thing of abandoning this idea and writing your own. It's not too hard to create your own Point and Polygon for spherical coordinates and doing it all with that coordinate system in mind from the start. Better abstraction, less guessing for clients. Your attempt to reuse java.awt.Polygon is admirable, but not necessary.
You can perform the area calculation easily by converting it to a contour integral and using Gaussian quadrature to integrate along each straight line boundary segment. You can even include the curvature of each segment at each integration point, since you know the formula.
Going off my intuition here.
If the polygons are small in ratio to the size of the planet you can treat them as flat polygons. The steps involved would be converting the lat/long into absolute x/y/z, taking any three of the points and finding the normal of the plane the polygons lie on and then using this to project the points into two dimensions. Once you have the 2D points it's easy to calculate the area or if they intersect.
Probably not the best answer but hopefully it will motivate some people to make better ones because it's a good question.
Maybe you could use GeoTools for this. It allows you to create Geometry objects, and check wether they intersect (see: Geometry Relationships)
Here is a solution that works like a charm:
Class PolygonArea from net.sf.geographiclib
Refer link below with sample code:
https://geographiclib.sourceforge.io/html/java/net/sf/geographiclib/PolygonArea.html
gradle dependency:
compile group: 'net.sf.geographiclib', name: 'GeographicLib-Java', version: '1.42'