Circle Corner Collision Behavior - collision

I am working on a project where I have a rolling marble in 2D. I can detect when the marble hits the corner of a box but I can't figure out what behavior it should have when it hits the corner. I need to figure out how to reposition the ball so it doesn't overlap the box. With a box to box collision it is as easy as setting the boxes right next to each other but for a circle and box I don't know where to move the marble to so it looks realistic.
I am not asking how it bounces off. I do have a good understanding of trig. As you move the marble towards the box it will, at some point, come to overlap with the box. I need to know how to make it so they don't overlap anymore but so it still looks realistic. It does not need to bounce off (like assuming infinite mass on part of marble).

Take a good look at this article on Wikipedia: Elastic Collision.
You will need to create surface normals for your 2D objects at any given surface point, which will be problematic if your boxes are perfectly square, as sharp edges don't have normals. You will have to give the corner cases (no pun intended) special treatment and give them surface normals that are the average of the normals of the two lines that join at the corner.
Basically, use vectors.

Related

Avoiding collision when placing a circle near other circles

I have a Main circle, and Other nearby circles.
All circles are always the same size.
No two circles may ever overlap.
I'd like to find out where Potential circles could be placed near the Main circle (more detail below).
Ideally, I'd like to do this fast (I know, everyone says so - but trust me I really do!).
I'd like the answer as a general high level description of the algorithm to use.
This might be a duplicate of Placing a circle so that it does not collide with any other circles, which I find unimpressive. Both the question and the answers.
Here's an approximate image, explanation below:
Red circle is the Main circle.
Black circles are the Other circles placed nearby.
The centre of each Potential circle should be on the yellow band. It is a relatively narrow range, slightly less wide than the radius of the circle, I'm not interested in any circles whose centre lies outside of this range.
Gray are the Potential circles I'd like the algorithm to find:
The one in the upper slightly right, is as close to the Main circle as can be. If any of the three Other circles around it moved any closer to its centre, there would be no Potential circle here.
Lower right, as far from the Main circle as allowed. If the two Other circles next to it were any closer to each other, there would be no Potential circle here.
Four Potential circles drawn on the left. There could be a multitude of these, it'd be fine if the algorithm returned just any one of these.
The teal circle is a bounding box, if a circle's centre lies outside, it has no impact on placing the circles on the yellow band.
Algorithm input: the Main and Other circles.
Desired algorithm output for the image above: three or four Potential circles. One upper slightly right, one lower right, and one or two on the left side (I don't mind too much which it is).
What have I tried? Googling! Looking at Stack Overflow. Thinking.
I'm thinking probably the first thing the algorithm should do is to convert the Other circles from (X, Y) coordinates to (angle, distance) from Main and order by angle. Then split the yellow band into some segments, and for each segment, get all the circles that could influence it.
Here I get lost a bit.
Next step, do some math to try to position the circle. For two circles, I can place a circle so that it just touches them. Perhaps when there are N circles, I just do this bit for each of the pairs and see if I'm left with anything? Or just each of the N with the centre? Can I save this as a draft so it ain't all gone while I think about it some more?
[Edit]: I guess a better approach would be to start with like 12 Potential circles around the Main circle, see which ones are illegal and which Other circles are getting in the way, then try nudging the Potential circles so they get out of the Other stones way. We should know exactly how far we need to move the Potential stone and in which direction, based on which Other stone it's overlapping with. Repeat, hopefully avoiding infinite loops but that I can do I think.
This is a nice problem. Let’s focus on one word: potential.
Think about force directed graph layouts, like this one:
https://observablehq.com/#d3/temporal-force-directed-graph
Eventually, the layout converges on a minimum energy solution, where the spring lengths are minimal.
Let’s bring that to your problem. We will define a potential field. The main and other circles provide repulsive forces. The yellow ring provides an attractive force.
Choose a random point on the plane. Determine if it is feasible, and reject it if not, for example, it overlaps with main or other circle. Now we are left with a circle in a feasible, but non-optimal location. We will move this circle to new candidate positions over several time steps. Sum up the attractive and repulsive forces operating on it, and move it a small amount in the indicated direction. At some point, it is likely that it will try to go to an infeasible position, perhaps overlapping with the main circle. At that point we are done, and we output its position as a good result.

Fitting a mesh and a drawing together

Suppose you're trying to render a user's freehand drawings using a 2D triangular mesh. Start with a plain regular mesh of triangles and color their edges to match the drawing as closely as possible. To improve the results, you can move the vertices of the mesh slightly, but keep them within a certain distance of where they would be in a regular mesh so the mesh doesn't become a mess. Let's say that 1/4 of the length of an edge is a fair distance, giving the vertices room to move while keeping them out of each other's personal space.
Here is a hand-made representation of roughly what we're trying to do. Since the drawing is coming freehand from the user, it's a series of line segments taken from mouse movements.
The regular mesh is slightly distorted to allow the user's drawing to be better represented by the edges of the mesh. Unfortunately the end result looks quite bad, but perhaps we could have somehow distorted the drawing to better fit the mesh, and the combination of the two distortions would have created something far more recognizable as the original drawing.
The important thing is to preserve angles, so if the user draws a 90-degree corner it ends up looking close to a 90-degree corner, and if the user draws a straight line it doesn't end up looking like a zigzag. Aside from that, there's no reason why we shouldn't change the drawing in other ways, like translating it, scaling it and so on, because we don't need to exactly preserve distances.
One tricky test case is a perfectly vertical line. The triangular mesh in the image above can easily handle horizontal lines, but a naive approach would turn a vertical line into a jagged mess. The best technique seems to be to horizontally translate the line until it passes through each horizontal edge alternating between 1/4 and 3/4 of the way along the edge. That way we can nudge the vertices to the left or right by 1/4 and get a perfect vertical line. That's obvious to a person, but how can an algorithm be made to see that? It involves moving the line further away from vertices, which is the opposite of what we usually want.
Is there some trick to doing this? Does anyone know of a simple algorithm that gives excellent results?

Closest distance to border of shape

I have a shape (in black below) and a point inside the shape (red below). What's the algorithm to find the closest distance between my red point and the border of the shape (which is the green point on the graph) ?
The shape border is not a series of lines but a randomly drawn shape.
Thanks.
So your shape is defined as bitmap and you can access the pixels.
You could scan ever growing squares around your point for border pixels. First, check the pixel itself. Then check a square of width 2 that covers the point's eight adjacent pixels. Next, width 4 for the next 16 pixels and so on. When you find a border pixel, record its distance and check against the minimum distance found. You can stop searching when half the width of the square is greater than the current minimum distance.
An alternative is to draw Bresenham circles of growing radius around the point. The method is similar to the square method, but you can stop immediately when you have a hit, because all points are supposed to have the same distance to your point. The drawback is that this method is somewhat inaccurate, because the circle is only an approximation. You will also miss some pixels along the disgonals, because Bresenham circles have artefacts.
(Both methods are still quite brute-force and in the worst case of a fully black bitmap will visit every node.)
You need a criterion for a pixel on the border. Your shape is antialiassed, so that pixels on the border are smoothed by making them a shade of grey. If your criterion is a pixel that isn't black, you will chose a point a bit inside the shape. If you cose pure white, you'll land a bit outside. Perhaps it's best to chose a pixel with a grey value greater than 0.5 as border.
If you have to find the closest border point to many points for the same shape, you can preprocess the data and use other methods of [nearest-neighbour serach].
As always, it depends on the data, in this case, what your shapes are like and any useful information about your starting point (will it often be close to a border, will it often be near the center of mass, etc).
If they are similar to what you show, I'd probably test the border points individually against the start. Now the problem is how you find the border without having to edge detect the entire shape.
The problem is it appears you can have sharply concave borders (think of a circle with a tiny spike-like sliver jutting into it). In this case you just need to edge detect the shape and test every point.
I think these will work, but don't hold me to it. Computational geometry seems to be very well understood, so you can probably find a pro at this somewhere:
Method One
If the shape is well behaved or you don't mind being wrong try this:
1- Draw 4 lines (diving the shape into four quandrants). And check the distance to each border. What i mean by draw is keep going north until you hit a white pixel, then go south, west, and east.
2- Take the two lines you have drawn so far that have the closest intersection points, bisect the angle they create and add the new line to your set.
3- keep repeating step two until are you to a tolerance you can be happy with.
Actually you can stop before this and on a small enough interval just trace the border between two close points checking each point between them to refine the final answer.
Method Two (this wil work with the poorly behaved shapes and plays well with anti-aliasing):
1- draw a line in any direction until he hit the border (black to white). This will be your starting distance.
2- draw a circle at this distance noting everytime you go from black to white or white to black. These are your intersection points.
As long as you have more than two points, divide the radius in half and try again.
If you have no points increase your radius by 50% and try again (basically binary search until you get to two points - if you get one, you got lucky and found your answer).
3- your closet point lies in the region between your two points. Run along the border checking each one.
If you want to, to reduce the cost of step 3 you can keep doing step 2 until you get a small enough range to brute force in step 3.
Also to prevent a very unlucky start, draw four initial lines (also east, south, and west) and start with the smallest distance. Those are easy to draw and greatly reduce your chance of picking the exact longest distance and accidentally thinking that single pixel is the answer.
Edit: one last optimization: because of the symmetry, you only need to calculate the circle points (those points that make up the border of the circle) for the first quadrant, then mirror them. Should greatly cut down on computation time.
If you define the distance in terms of 'the minimum number of steps that need to be taken to reach from the start pixel to any pixel on the margin', then this problem can be solved using any shortest path search algorithm like bread first search or even better if you use A* search algorithm.

minimal bounding box of a clipped point cloud

I am trying to find the minimal bounding box of a 2d point cloud, where only a part of the point cloud is visible.
Given a point cloud with a rough rectangular shape, clipped so that only one corner is visible:
The point cloud is clipped at the green border. I know the position of the border in the image, and I know that there will always be exactly one corner of the rectangular shape visible within this border. I also know the size of the rectangular shape.
Now I want to find the minimal bounding box that contains all the points of this shape, even those not visible on-screen. Since I know the dimensions of the box, finding the two sides visible is enough to determine the other two.
(there are actually two possible solutions, since width and height of the shape can be swapped, but let's ignore that for the moment)
I want to find the red box.
I do not need an exact solution, or a fast one. My current attempt uses a simple brute force algorithm that rotates the point cloud in 1° steps and finds the axis-aligned bounding box.
I just need a criterion that tells me which rotation is the best one for this case. Minimal-Area is the usual criterion for a minimal bounding box, but that obviously only works if all points are visible.
There is probably some optimal algorithm involving convex hulls, but I'd rather keep the solution as simple as possible
All you really need is the positions of the corners of the intersection between your red and green rectangle. Assuming the points are a decent approximation of the border, this should be a reasonably reliable method to get those:
Pick the two points A and B most distant from eachother. Those are two corners of the area of intersection.
Find the points C and D with the greatest perpendicular distance from the line AB (example) on either side. Those are another two corners of the area intersection.
A, B, C & D are some combination of corners of the red rectangle and intersections between the green and the red rectangles. To work out which are which, just check which are within some small tolerance of the green rectangle's border. And with that, you've got enough information to easily work out the position of the red rectangle.

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