I'm working in python but this is really more of an algorithmic question. Imagine I have four particles connected by springs to form a soft-bodied polygon. I want to figure out when and where a fifth particle collides with this object so I can have them bounce off of each other. What is the best way to detect if a particle has entered a region?
Given that your polygon is always formed by 4 points, you don't need to use a general case point/polygon intersection algorithm, you can just split your parallelogram in two triangles and do the point inside triangle test with the 5th point. If the point is inside one of the triangles, then the particle has entered the region.
Related
Given two 2D polygons, how do I calculate the shortest translation that brings the first inside the second?
Assume there is a solution (i.e. the first does in fact fit inside the second)
Prefer a simple algorithm over completeness of solution. For example if the algorithm is simplified by making assumptions about the shapes having a certain number of sides, being concave, etc. then make those assumptions.
I can imagine a brute force solution, where I first calculate which are the offending vertices that lie outside the initial polygon. I'd then iterate through these external vertices and find the closest edge to each. Then I'm stuck. Each distance from an external vertex to an edge creates a constraint (a "need to move"). I then need to solve this system of constraints to find the movement that fulfills them all without creating any new violations.
I'm not sure if this can be a general solution, but here is at least a point to start with:
We want to move the green polygon into the red polygon. We use several translations. Each translation is defined by a start point and an end point.
Step 1: Start point is the mid-point between the left-most vertex and the right-most vertex in green polygon. End point, same criterion with the red polygon:
Step 2: Start point is the mid-point between the top-most vertex and the low-most vertex. End point, same criterion with the red polygon:
Notice that setps 1 & 2 are kind of centering. This method with mid points is similar to use the bounding boxes. Other way would be using circumcircles, but they are hard to get.
Step 3: Find the vertex in red polygon closest to an edge in the green polygon. You will need to iterate over all of them. Find the line perpendicular to that edge:
Well, this is not perfect. Depending on the given polygons it's better to proceed the other way: closest vertex in green to edges in red. Choose the smallest distance.
Finally, move the green polygon along that line:
If this method doesn't work (I'm sure there are cases where it fails), then you can also move the inner polygon along a line (a red edge or a perpendicular) that solves the issue. And continue moving until no issues are found.
I have a set of polyhedra that make up a game level, and I'd like to partition the floor. Basically, I need a generic way to divide up areas where players can be into labelled zones. Are there any algorithms or an established set of procedures for doing this?
Assuming there isn't anything standard, I'd appreciate some guidance on how to go about this since I'm not very familiar with the domain. I've seen some partitioning algorithms for polygons in CGAL which I like, so my intuition is to generate polygons from the floor and then use those algorithms.
Here's my plan:
Find all upward-facing faces of floor polyhedra: Start at an initial point on a known floor polyhedron where players can be and traverse connected polyhedra that intersect at a smooth enough angle (i.e. are not walls). Pick a point in the sky and iterate through all the faces of floor polyhedra for which that point is on the positive side (I have orientation data for the faces).
Find planes to separate overlapping floor areas along the z-axis. I have some ideas of how to go about this, but I suspect there's an algorithm that will do it.
Use the first two coordinates of now-divided floors to make polygons and run the partition algorithm on each of them.
Example:
Suppose I have 3D shape data of an office building with two floors and a staircase connecting the floors. Everything is in 3D so a floor is represented by a polyhedron with thickness as are the walls and staircase. I want to partition the upward face of each floor in order to plan out cubicle locations. I really don't care about the cubicles on one floor in relation to cubicles on the other floor. Rather than having one 3D space that's partitioned, it makes sense to me to break this up into two 2D spaces to partition individually.
Note: This example isn't perfect because in the example I don't care about partitioning the staircase, but in my game world I do. So I can't just remove the staircase and have my two separated floors, but I could, for instance, slice it and separate the floors with a plane.
I'm building a 2D game where player can only see things that are not blocked by other objects. Consider this example on how it looks now:
I've implemented raytracing algorithm for this and it seems to work just fine (I've reduced the boundaries for demo to make all edges visible).
As you can see, lighter area is built with a bunch of triangles, each of them having common point in the position of player. Each two neighbours have two common points.
However I'm willing to calculate bounds for external the part of the polygon to fill it with black-colored triangles "hiding" what player cannot see.
One way to do it is to "mask" the black rectangle with current polygon, but I'm afraid it's very ineffective.
Any ideas about an effective algorithm to achieve this?
Thanks!
A non-analytical, rough solution.
Cast rays with gradually increasing polar angle
Record when a ray first hits an object (and the point where it hits)
Keep going until it no longer hits the same object (and record where it previously hits)
Using the two recorded points, construct a trapezoid that extends to infinity (or wherever)
Caveats:
Doesn't work too well with concavities - need to include all points in-between as well. May need Delaunay triangulation etc... messy!
May need extra states to account for objects tucked in behind each other.
I have given the coordinates of 1000 triangles on a plane (triangle number (T0001-T1000) and its coordinates (x1,y1) (x2,y2),(x3,y3)). Now, for a given point P(x,y), I need to find a triangle which contains the point P.
One option might be to check all the triangles and find the triangle that contain P. But, I am looking for efficient solution for this problem.
You are going to have to check every triangle at some point during the execution of your program. That's obvious right? If you want to maximize the efficiency of this calculation then you are going to create some kind of cache data structure. The details of the data structure depend on your application. For example: How often do the triangles change? How often do you need to calculate where a point is?
One way to make the cache would be this: Divide your plane in to a finite grid of boxes. For each box in the grid, store a list of the triangles that might intersect with the box.
Then when you need to find out which triangles your point is inside of, you would first figure out which box it is in (this would be O(1) time because you just look at the coordinates) and then look at the triangles in the triangle list for that box.
Several different ways you could search through your triangles. I would start by eliminating impossibilities.
Find a lowest left corner for each triangle and eliminate any that lie above and/or to the right of your point. continue search with the other triangles and you should eliminate the vast majority of the original triangles.
Take what you have left and use the polar coordinate system to gather the rest of the needed information based on angles between the corners and the point (java does have some tools for this, I do not know about other languages).
Some things to look at would be convex hull (different but somewhat helpful), Bernoullies triangles, and some methods for sorting would probably be helpful.
I need to create a (large) set of spatial polygons for test purposes. Is there an algorithm that will create a randomly shaped polygon staying within a bounding envelope? I'm using OGC Simple stuff so a routine to create the well known text is the most useful, Language of choice is C# but it's not that important.
Here you can find two examples of how to generate random convex polygons. They both are in Java, but should be easy to rewrite them to C#:
Generate Polygon example from Sun
from JTS mailing list, post Minimum Area bounding box by Michael Bedward
Another possible approach based on generating set of random points and employ Delaunay tessellation.
Generally, problem of generating proper random polygons is not trivial.
Do they really need to be random, or would some real WKT do? Because if it will, just go to http://koordinates.com/ and download a few layers.
What shape is your bounding envelope ? If it's a rectangle, then generate your random polygon as a list of points within [0,1]x[0,1] and scale to the size of your rectangle.
If the envelope is not a rectangle things get a little more tricky. In this case you might get best performance simply by generating points inside the unit square and rejecting any which lie in the part of the unit square which does not scale to the bounding envelope of your choice.
HTH
Mark
Supplement
If you wanted only convex polygons you'd use one of the convex hull algorithms. Since you don't seem to want only convex polygons your suggestion of a circular sweep would work.
But you might find it simpler to sweep along a line parallel to either the x- or y-axis. Assume the x-axis.
Sort the points into x-order.
Select the leftmost (ie first) point. At the y-coordinate of this point draw an imaginary horizontal line across the unit square. Prepare to create a list of points along the boundary of the polygon above the imaginary line, and another list along the boundary below it.
Select the next point. Add it to the upper or lower boundary list as determined by it's y-coordinate.
Continue until you're out of points.
This will generate convex and non-convex polygons, but the non-convexity will be of a fairly limited form. No inlets or twists and turns.
Another Thought
To avoid edge crossings and to avoid a circular sweep after generating your random points inside the unit square you could:
Generate random points inside the unit circle in polar coordinates, ie (r, theta).
Sort the points in theta order.
Transform to cartesian coordinates.
Scale the unit circle to a bounding ellipse of your choice.
Off the top of my head, that seems to work OK