Prevent shapes from clipping into each other - collision

I just started to port my game to slick2d and I want mine entities to collide with each other.
I know that shapeA.intersects(shapeB) checks if two shapes intersect but I want them to collide so that they aren't able to overlap each other.
I would be easy if the shapes were only rectangles but that's not the case.
So is there any way to perform this in an efficent way?

Hopefully i got your question right.
To do this you need to implement collision to your game. An approach to accomplish this would be to assume your shape is for instance x coordinates a head of its current position.
This would mean you always have to check whether two shapes are intersecting with each other when they are moving, if they would intersect on the next movement they are not allowed to move a head, otherwise they would obviously intersect or collide. You can adapt this approach completly to your needs, for example you could let them collide and then set them back so that they are not getting stuck into each other.
There are a lot of tutorials regarding this topic and different approaches, you should check them out.

Related

Find intersections in GPS tracks

I’m embarking on a personal project (planning on starting in Python if it becomes relevant), and I’m looking for some algorithms advice.
One part of my project will entail finding intersections between GPS tracks. Not like identifying road intersections, but identifying places where two different tracks cross.
I can’t think of a way to do it that isn’t heinously computationally intensive, but I feel like this is a problem that has probably been studied/solved in the past. Is there a name for this type of problem? Or are there algorithms that I should look in to?
No "clever" algorithm there. You use all positions of a given mobile object to make the track (really, it's more the "history of movement" rather than a track), you obtain a polyline.
To check intersections between two mobile elements, you'll have to find where the two polylines intersects. You simply check each segment of the first track with each segment of the second track.
You can optimize a lot by using a bounding rectangle around the polylines: if the two bounding rectangles do not intersect, no need to check, there is no intersections. Otherwise, get the intersection, and you can directly ignore all segments that are outside this intersection area.
Once an intersection is found, you can then compare the plot timestamp in order to see if the two mobile objects did really meet, or if they simply crossed the other one's path at a different time.
If needed, once you found an intersection on projected polyline, you can also check the altitude, too, because the polyline is indeed in 3D and not only in 2D - GPS give altitude, too.

2d geometry push algorithm

I have a rectangle board and in it, there are some disjoint 2D shapes such as rectangles, polygons, and more complex geometries, such as simple shapes with arc/line edges.
Usually they are compact, but for some shapes, we may be able to rotate or translate them.
If we move one geometry according a given direction, the adjacent geometry should also be moved or rotated. It looks like the first geometry pushes the second geometry. The second geometry might push the other two geometries. Finally, we may achieve another stable state, or there is no room to push.
Is there any existing investigation on this?
Let's first focus on simple polygons, convex and non-convex.
Push might be any direction.
example image
I'm doing some investigation but could not find existing papers about this topic.
Can we simulate it through mechanics or dynamics? Or pure geometry algorithm?
Just some keywords for paper search is also very useful.
It's similar with EDA's auto push concept. User can move one element (pin/wire) of a circuit, then the software automatically pushes adjacent elements so that the topology is kept and meet design rules.
I think I can use some concepts in mechanics, to compute moving direction at least:
If the connected part of polygon A and polygon B is a point, then pushing A by one direction then generates a force to B along the normal direction. But the force may not generate a move. We need loop all the parts or reach the boundary to check how much it can move.
Let's ignore rotation first.
I post an answer because I don't have enough reputation for a comment. If I don't misunderstand the problem, geometrically this sounds as a collision detection problem. You have to apply a transformation (translation, rotation) to your geometry, and check if this new position overlaps with another geometry. If this is the case you have to apply another transformation to the second. Collision detection is a big topic in games and simulation.

How can I create an internal spiral for a polygon?

For any shape how can I create a spiral inside it of a similar shape. This would be a similar idea to bounding (using Minkowski sum). Rather than creating the same shape inside the shape though it would be a spiral of same shape.
I found this - http://www.cis.upenn.edu/~cis110/13su/lectures/Spiral.java
It creates a spiral based on the parameters passed so it can be for any regular shape.
I want the above for all shapes i.e. irregular polygons too.
I am not hugely familiar with geometric terminology but I have looked up Involutes and an Internal Spiral Search Algorithm too but haven't been useful to me.
Does anyone have any idea where I'd find an algorithm such as this or at least ideas of how I'd come up with one?
this task is extremly hard to do.
need to have the boundary polygon you want to fill with spiral
I think you have it already
create new smaller polygon by shifting all lines inwards by the step.
It is similar to create stroke line around polygon. Step is the screw width so at start of polygon it is 0 and on the end it is d
remove invalid lines from the newly generated screw
Some lines on corners and curvatures will intersect. This is very hard to detect/repair reliably see
this for basics
repeat (do next screw) ... until no space for screw found
But now after the first screw the step is always d this will not necessarily fill the whole shape. For example if you have some thinner spot on shape it will be filled much more faster then the rest so there can still be some holes left.
You should detect them and handle as you see fit see
Finding holes in 2d point sets
Be aware detection if the area is filled is also not trivial
This is how this approach looks like:
[Notes]
If you forget about the spiral and want fill the interior with a zig zag or similar pattern then this is not that hard.
Spiral filling makes a lot of hard geometric problems and if you are not skilled in geometry and vector math this task could be a too big challenge for beginner or even medium skilled programmer in this field to make it work properly. That is at least my opinion (as I done this before) so handle it as such.
I worked on something like this using offsets from the polgyon based on medial axis of Voronoi diagram. It's not simple. I can't share the code as it belongs to the company I worked for and it may not exactly fit your needs.
But here are some similar things I found by other people:
http://www.me.berkeley.edu/~mcmains/pubs/DAC05OffsetPolygon.pdf
http://www.cosy.sbg.ac.at/~held/teaching/seminar/seminar_2010-11/hsm.pdf

Which is the best way to solve this kind of game?

This evening I tried to solve a wood puzzle so I wondered which is the best way to find a solution to this kind of problem programmaticaly.
The aim is to combine a set of solids (like tetris pieces in three dimensions) together to form a shape in a feasable way that takes into account the fact that pieces can be attached or slided into the structure only if they fit the kind of movement (ignore rotations, only 90° turns).
Check this picture out to understand what I mean.
In my latest CS class we made a generic puzzle solver that worked by having states represented as objects in C++. Each object had a method to compare the state it represented to another state. This was used for memoization, to determine if states had already been seen. Each state also had a method to generate states directly reachable from that state (i.e. rotating a block, placing a block, shifting a block). The solver worked by maintaining a queue of states, popping a state off the front of the queue, checking to see if it was the desired state (i.e. puzzle solved). If not, the memoization (we used a hashed set) was checked to see if the state had already been seen. If not, the states reachable from the current state were generated and appended to the rear of the queue. An empty queue signaled an unsolvable puzzle.
Conceptualizing something like that for 3D would be hard, but that is the basic approach to computerized puzzle solving.
Seems like an easier subset of a three-dimensional polyomino packing problem. There are various scholarly papers on that subject.
As it is a more or less small problem because for a computer there is a small number of combinations possible I would try a simple search algorithm.
I mean an algorithm that checks every possible configuration and goes on from the result of this configuration until it ends up in a end configuration, in your case the cube.
The problem seams to be writing a program that is able to do all the state checks and transformations from one state to another. Because you have to see if the configuration is physically possible.
If the puzzle you want to handle is that one in the photo you have linked, then it's probably feasible to just search through a tree of possible solutions until you find your way to the bottom.
If each puzzle piece is a number of cubes attached at their faces, and I am to solve the puzzle by fitting each piece into a larger cube, 4 times on each edge as the composing cubes, then I'd proceed as follows.
Declare an arbitrary cube of each piece as its origin. Observe that there are 24 possible rotations for each puzzle piece, one orientation for each possible face of the origin cube facing upwards, times 4 possible rotations about the vertical axis in that position.
Attempt to cull the search space by looking for possible orientations that produce the same final piece, if a given rotation, followed by a translation of the origin cube to any of the other cubes of the piece results in exactly the same occupied volume as a previously considered rotation, cull that rotation from future consideration.
Pull a piece out of the bag. If there are no pieces in the bag, then this is a solution. Loop through each cell of the solution volume, and each rotation of the pulled piece for each cell. If the piece is completely inside the search volume, and does not overlap with any other piece, recurse into this paragraph. Otherwise, proceed to the next rotation, or if there are no more rotations, proceed to the next cell, or if there are no more cells, return without a solution.
If the last paragraph returns without a solution, then the puzzle was unsolvable.

Is a closed polygonal mesh flipped?

I have a 3d modeling application. Right now I'm drawing the meshes double-sided, but I'd like to switch to single sided when the object is closed.
If the polygonal mesh is closed (no boundary edges/completely periodic), it seems like I should always be able to determine if the object is currently flipped, and automatically correct.
Being flipped means that my normals point into the object instead of out of the object. Being flipped is a result of a mismatch between my winding rules and the current frontface setting, but I compute the normals directly from the geometry, so looking at the normals is a simple way to detect it.
One thing I was thinking was to take the bounding box, find the highest point, and see if its normal points up or down - if it's down, then the object is flipped.
But it seems like this solution might be prone to errors with degenerate geometry, or floating point error, as I'd only be looking at a single point. I guess I could get all 6 axis-aligned extents, but that seems like a slightly better kludge, and not a proper solution.
Is there a robust, simple way to do this? Robust and hard would also work.. :)
This is a robust, but slow way to get there:
Take a corner of a bounding box offset from the centroid (force it to be guaranteed outside your closed polygonal mesh), then create a line segment from that to the center point of any triangle on your mesh.
Measure the angle between that line segment and the normal of the triangle.
Intersect that line segment with each triangle face of your mesh (including the tri you used to generate the segment).
If there are an odd number of intersections, the angle between the normal and the line segment should be <180. If there are an even number, it should be >180.
If there are an even number of intersections, the numbers should be reversed.
This should work for very complex surfaces, but they must be closed, or it breaks down.
"I'm drawing the meshes double-sided"
Why are you doing that? If you're using OpenGL then there is a much better way to go and save yourself all the work. use:
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 1);
With this, all the polygons are always two sided.
The only reason why you would want to use one-sided lighting is if you have an open or partially inverted mesh and you want to somehow indicate what part belong to the inside by having them unlighted.
Generally, the problem you're posing is an open problem in geometry processing and AFAIK there is no sure-fire general way that can always determine the orientation. As you suggest, there are heuristics that work almost always.
Another approach is reminiscent of a famous point-in-polygon algorithm: choose a vertex on the mesh and shoot a ray from it in the direction of the normal. If the ray hits an even number of faces then the normal is pointed to the outside, if it is odd then the normal is towards to inside. notice not to count the point of origin as an intersection. This approach will work only if the mesh is a closed manifold and it can reach some edge cases if the ray happens to pass exactly between two polygons so you might want to do it a number of times and take the leading vote.

Resources