Culling interior triangles - language-agnostic

I have an array of thousands of quads; 4-sided 3D polygons. All I know are the coordinates of the quad corners.
A subset of these quads define the closed outer shell of a 3D shape. The remaining quads are on the inside of this closed solid.
How do I figure out which quads are part of the shell and which quads are part of the interior? This is not performance critical code.
Edit: Further constraints on the shape of the shell
There are no holes inside the shape, it is a single surface.
It contains both convex and concave portions.
I have a few points which are known to be on the inside of the shell.

This might be hard to implement if your shape self intersects, but if you can find one quad that you know is on the surface (possibly one furthest away from the centroid) then map out concentric circles of quads around it. Then find a continuous ring of quads outside that and so on, until you end up at the "opposite" side. If your quads intersect, or are internally connected, then that's more difficult. I'd try breaking apart those which intersect, then find all the possible smooth surfaces, and pick the one with the greatest internal volume.

How about this?
Calculate the normal vector of a quad (call this the 'current' quad).
Do an intersection test with that vector and all the remaining quads.
If it intersects another quad in the positive portion of the vector you know the current quad is an internal quad. Repeat for all the remaining quads.
This assumes the quads 'face' outward.

Consider that all of the quads live inside a large sealed box. Pick one quad. Do raytracing; treat that quad as a light source, and treat all other quads as reflective and fuzzy, where a hit to a quad will send light in all directions from that surface, but not around corners.
If no light rays hit the external box after all nodes have had a chance to be hit, treat that quad as internal.
If it's convex, or internal quads didn't share edges with external quads, there are easier ways.

It can be done quite easily if the shape is convex. When the shape is concave it is much harder.
In the convex case find the centroid by computing the average of all of the points. This gives a point that is in the interior for which the following property holds:
If you project four rays from the
centroid to each corner of a quad you
define a pyramid cut into two parts,
one part contains space interior to
the shape and the other part defines
space that might be exterior to the
shape.
These two volumes give you a decision process to check if a quad is on the boundary or not. If any point from another quad occurs in the outside volume then the quad is not on the boundary and can be discarded as an interior quad.
Edit: Just seen your clarification above. In the harder case that the shape is concave then you need one of two things;
A description (parameterisation) of the shape that you can use to choose quads with, or
Some other property such as all of the boundary quads being contiguous
Further edit: Just realised that what you are describing would be a concave hull for the points. Try looking at some of the results in this search page.

You may be able to make your problem easier by reducing the number of quads that you have to deal with.
You know that some of the quads form a closed shell. Therefore, those quads are connected at their edges. If three mutually adjacent edges of a quad (that is, the edges form a closed loop) overlap the edge of another quad, then these quads might be part of the shell (these mutually adjacent edges serve as the boundary of a 2D region; let's call that region the "connected face" of the quad). Make a list of these "shell candidates". Now, look through this list and throw out any candidate who has an edge that does not overlap with another candidate (that is, the edge overlaps an edge of a quad that is not in the list). Repeat this culling process until you are no longer able to remove any quads. What you have left should be your shell. Create a "non-shell quads" list containing all of the quads not in the "shell" list.
Draw a bounding box (or sphere, ellipse, etc) around this shell. Now, look through your list of non-shell quads, and throw out any quads that lie outside of the bounding region. These are definitely not in the interior.
Take the remaining non-shell quads. These may or may not be in the interior of the shape. For each of these quads, draw lines perpendicular to the quad from the center of each face that end on the surface of the bounding shape. Trace each line and count how many times the line crosses through the "connected face" of a quad in your shell list. If this number is odd, then that vertex lies in the interior of the shape. If it is even, the vertex is on the exterior. You can determine whether a quad is inside or outside based on whether its vertices are inside or outside.

Related

DCEL data structure edge refinement algorithm (edge cases)

I'm trying to connect two polygons that are described as DCEL data structure and find it hard to do so at some edge cases where, for example, edges intersect with each other at their interior or overlap each other.
Here's the definition of the problem:
The polygons are of rectangular shape with straight edges (edges at vertices make straight angles)
There are no more than 8 edges that meet at the vertex. The only case where it's possible is that all 4 polygons meet at single vertex (aka 4 rectangles)
It's impossible to have more than 2 edges intersecting in their interior
It's impossible that polygons intersect not on segments. All intersections are done on edges and all of them are mix of overlapping cases or interior intersections
There are no holes in polygons
Dissolving internal faces is not allowed here. Edge in between still must be present
If this helps the polygons are representing imaginary regions enclosed under the imaginary country that's why they meet at edges only.
Here are some examples of polygons:
Case 1:
Overlapping edges
Case 2:
One edge contains another
PS: Right now I'm reading Bergs 'Computational Geometry' and trying to practice in DCEL implementation
PSS: In addition I've read a lot of info across the Internet regarding handling subdivision overlapping, but haven't seen the explanation about how to handle such cases. What I think here is that I need to handle edge removal while Berg does not tell this in his book.
Also extra source: same Berg, but with more fancy images
https://cw.fel.cvut.cz/b201/_media/courses/cg/lectures/09-intersect-split.pdf (p. 26/96)
So after tons of trials and errors I found the solution to my problem. It's not ideal because I still don't know the 'correct' answer on how to split edges when they are neighboring to each other for arbitrary polygon, but have a solution to my problem that I was trying to solve.
According to the algorithm that Berg described in his book edges must be refined using sweep line algorithm. Previous and next edge must be selected in the CCW or CW order (CCW = counter clockwise, CW = clockwise) depending in what direction edge is pointing, but it's hard to do so when you have overlapping edges. Additional complexity here will be that the edge consists of two half edges and it's a nightmare to refine both of them according to simplified algorithm described above. Instead, what we can do here is to forget about two half edges and use only one. It will always have incident face but no twin. In this case overlapping is detected perfectly using sweep line algorithm and polygon stitching becomes straightforward: the overlapping edges become twins to each other when edge refinement is done (splitting edge at the event point in case if edge contains it in the interior). When edge is split the other edge that belongs to another polygon becomes its twin
It looks a bit messy without thorough explanation, but I'll attach image that will show what I mean by that
On the image you can see edges like a2 that gets split into two new edges - a2' and a2'' plus old shrunk a2. Refinement of a2 was done at two points - v5 and v8. Each point is a beginning of the new half edge and the end of previous one. When we have two edges that are ending at a point (it's impossible to have more than 2 edges in my problem) we mark them as twins (b4 and a2'). Resolving next and previous here is really easy.
To bypass the contour of stitched polygon (black lines) you can use info about the twin of next edge. If it has a twin then switch to the twins next edge at next step (next_edge = a2'.twin.next is the same as next_edge = b4.next)
PS: it will not work for case when you have multiple polygons overlapping at the same edge. It's hard to make twins in such case, but it's a question whether the correct solution exists or not?

Detect coordinates within a shape

Theres 2 parts to my problem and they are related. I have a weird shape on my interface illustrated below, I am trying to randomly spawn MovieClips within its' boundaries but I am having some trouble finding a good way to do it.
Question 1: I can run an If condition to check with bitMapData.hitTest to see if the MovieClip has randomly spawn within this shape, if it doesn't simply retry with a new set of random coordinates. However, is there a better way? Like a way to only take into account coordinates within the shape? There will be plenty of MC spawned at one go so I am hoping to lessen the load, or at least find an efficient way to do this calculation.
Question 2: The MovieClips spawned within this shape will eventually have collision detection mechanics that will repel itself when interacted with. Is there a way to contain them within this shape via some kind of boundary detection?
If it was a square, we could easily have contained them with a quick check on all 4 edges, but not with this shape. Currently I am thinking of using bitMapData.hitTest again to detect for out-of-bounds after being repelled, but how do I know which Point() is the nearest 'edge' of this shape to return the MC to?
For question 1: I'm going to go on an assumption that you have some geometry data about the shape.
One method you can use to check if a point is within a shape is to take that point, then draw a line from that point to infinity (the edge of the screen) in one direction. Then count how many times that line intersects an edge of the shape. If it's odd, the point is within the shape (or on the edge) and if it's even, than that point is outside of the shape.
First link in google: https://www.geeksforgeeks.org/how-to-check-if-a-given-point-lies-inside-a-polygon/
Or can also try a more simple method (at the cost of doing more work): if the above shape is generated with all squares and rectangles and you know the point and size of all of those: can just do a check for the point vs all the squares and rectangles that make up the shape.
For question 2: As Organis mentioned, I'd go with a library like Box2D to do this. You'll most likely spend tons of time (that you may not want to) if you try to implement this alone.
The big issue is how much cpu or gpu the code uses. You're trying to avoid using any collision detection. Collision detection is having code do calculations to determine the edges of an object. It should be the last option.
Most of the time you know there's no need for collision detection. You know where everything is and how big it is. Everything has a centerpoint and comparing simple number coordinates is the lightweight way to check if there's a need to check further.
When things get near each other, you only need to do a collision detection on the immediate area around an object. See how your shape fits in a box that is easy to check for collisions? That box should get a collision check before the actual jagged shape inside it.
Yes that collision detection box has to be drawn or mapped but it's done when the object is defined, not when the game is playing. If you are using sprite sheets, keep an xml of the boxes or circles around the shapes.

I want to collition with an attack of sword or club of enemy

I am making a 2D platform game using cocos2dx and box2d.
And I am just now making of a player collitions with an attack of enemy.
An attack of enemy is such as a sword or a club, so I want to collition when a player is contacted with an edge of sword(or club) of enemy.
So far I made of a player collitions with a bullet using box2d, but I don't know that how to make the bounding box to an edge of sword(or club) of enemy like the following picture.
How are you making like this collision?
I believe that what you want isn't a bounding box but a collection of bodies, fixtures, and shapes to make a realistic enough simulation of the enemy and player interacting with each other.
To do that, you'll need to partition the pink lined shape (the enemy and its weapons) into a set of convex polygons — just like you'd need to do for the player.
Note that mathematically speaking, any concave shape can be expressed as a combination of convex polygons. From Wikipedia's entry for Concave polygon:
It is always possible to partition a concave polygon into a set of convex polygons.
If there's few enough entities you need to deal with this for, I'd just manually do the partitioning.
For one thing, it looks like you'd need to partition things manually anyway just in order to partition the ideally immutable parts from each other. Parts like the mace (or club), the forearm, the upper arm, etc where structures like metal, wood, or bone make a part rigid enough for the detail of the simulation you want to achieve.
Then you'll need to partition these rigid parts again to match the level of detail of the simulation that you want. So the mace's head, might be represented using something close to a pentagon shaped polygon. The mace's shaft, by just a rectangular polygon. Attach those two convex shapes to a single body for the mace. And so on.
You can use algorithms (or use implementations of those algorithms) to compute the sets of convex polygons that make up concave parts if you'd prefer. Unless you're going to do this for arbitrary shapes however, I'm not sure it's worth it.

How to create arcs on boundary points of voronoi?

I am writing some 2D graphic software. And in my project i used Voronoi algorithm. And result is correct as I expected (Pic 1). Then i want to add some feature on boundary points just like (Pic 2). So i think i need to implement Concave hull on boundary points and then create arcs on it.
Pic 1.
But my concave hull is not working correct because of concavity parameter. What is the best way and best algorithm to transform my software result into Pic 2.
Pic 2.
You can create a b/w bitmap with the concave hull and compare it with every point of the voronoi diagram. I used a php function imagefilledpolygon in my php implementation contour plot:https://cntm.codeplex.com/.
You can also try this answer and reconstruct voronoi edges at the border, usually infinity edges:Colorize Voronoi Diagram.
You should be able to do a walk around the voronoi looking for vertices with only a single adjacent edge (not a bad idea to start with a vertex that has just one adjacent edge). Find the first one, walk to the next one, then connect the edges with an arc, repeat until your back at the first edge. The algorithm should be rather efficient O(N) if the voronoi is structured as a graph.
The walk:
The walk is done by angle-sorting the edges and taking the next clockwise edge to the one you started on.
For example:
If the angles (in degrees) are 40, 50, 60, 70, and the previus edge was in the direction of the 50, then you would follow the 60 or 40 edge (depending on if you've decided to go clockwise or counterclockwise) but you wouldn't follow the 70 regardless as that leads inside rather than sticking to the outside.

AS3 - drawPath() & winding overlaps producing strange behavior

I'm trying to draw multiple shapes in the same Sprite.graphics scope, and can't seem to find any reasonable solution to my problem.
Please keep in minde that I've been using the drawPath() method for a performance problem : I could use multiple shapes with blendmodes, but I'd like to avoid that and keep performances cost to the minimum.
I've been experimenting with the winding parameter of the drawPath() method, but one thing that I cannot understand, is how the winding direction is defined by Flash, so here is a first question before actually coming to the real problem :
Are points coordinates taken in account ? Or is it the angle between the produces lines that define the direction ?
That being said, here is my actual problem :
I want to draw a shape that is a projection from a rectangle on a line - think of a window and the light that passes through it that goes hit the floor.
To achieve that, I must take into account that the lightsource position can vary and have that kind of results :
Here on that second picture you can already see the problem I'm facing.
To draw my shape, I've been separately "drawing" (understand : placing the numbers in my coordinates vector) the different parts of my figure : the actual rectangle I want to project, the light projected from its left side, the light projected from its bottom side, and the light projected from its right side.
I've been trying to carefully keep the winding direction the same in every section, beginning from the top-left corner, but it seems something is wrong in my reasoning, since every time the center part overlaps with any side part, the shape is emptied there, and every time the two sides parts overlaps, the same happens.
As I'm writing that here, some revelation suddenly strike me, and now I guess that maybe ALL my points in my coordinates vector must be sorted in the same winding direction for my shape to work ?... (and not only the small parts I'm separately drawing in my mind ^^)
If I'm right (please correct me if I'm not, or if I've understood anything wrong ?...), that means I must either :
sort my points to be placed in the correct winding direction (thing that might be complicated and could result in some strange drawed shape once provided to the drawing API ?...)
only draw the shape from the most external points, depending on the shape's actual shape (thing that might be more complicated that I currently expect).
Could anyone here confirm or infirm my last suppositions, and give me a clue on what could be going on here and how to solve it ?...
Thanks a lot :-)
You want to have one shape composed out of three projector lines? Okay, you have determined the positions of two lower points, and you have 4 points of your window. You then construct a list like so:
Two topmost points are always in the list, as you write that your light will always fall down out of the window. So, put 0 in command, window's upper left point coordinates into path, 1 into command (lineTo), window's upper right point into path.
Now, if both of your floor points have X less than lower right angle of the window, you add the window's point into the path!
Then you add rightmost floor point, then leftmost.
Then, if both of your floor points have X greater than lower LEFT corner of the window, you add it to the list.
You're done. And you will no longer need 3 projections, you calculate only the bottommost one (it'll give you both points on the floor), and make your list. Should do. Please comment.