rigid body dynamics penetration correction - simulation

I've been working on rigid body simulation for a while and I still have no idea how to deal with this problem. (I use discrete collision detection and use LCP to solve the impulse of each contact point.)
Imagine a fixed bowl (a hemisphere centered at C) and a particle at the edge of the bowl. The particle rolls down on the surface to the inside of the bowl. And at some time step, there should be a contact point A, and the LCP solver will give the result impulse which makes the particle's velocity perpendicular to vector CA. But after updating one time step, the particle moves along this velocity a little bit and actually goes out of the bowl, and things get worse after several more time steps. When I used a cube instead of the particle, the cube can penetrate and sink through the bowl.
So is there a way to avoid this? The impulse method is not perfect and there can still be penetration after the collision response. I need to somehow correct the penetration, but simply moving the object along the surface normal at the contact point is not a good idea, because it can produce new penetrations.
Edit:
It is not the problem of bowl being too thin or time step being too large. The reason is the Euler's integral produce a polygon instead of a circle. And we cannot just modify the positions of these 2 object, because if there is a third object on the other side, object 2 and 3 may have a new penetration. I think one way is to add some elastic force based on the penetration depth, but it is not neat enough.
Thanks it's a good idea to look through the Bullet source code, working on it.

Compute a step, get penetration of all particles. Compute spherical probability of occurences on the penetrated points, mirror the occurence probabilities from surfaces, delete the penetrated probabilities, subtract other particles' probabilities from its local probability map, place the particle on the highest probability point.
Example:
o ---> |
| o penetrated to here
| %5 %50 %90
%90 %50 %5 |
o |
probabilities to left of it and right of it is same(about %80) so it is stationary now, so it is non-elastic collision.
now lets assume there is a second particle
o ---> o |
o | o penetrated here
-100% | %5 %50 %90
%90 %0 %-45|
o o |
so particle bounced back from other particle which also bounced back from wall but gave its momentum back to first particle. Then, probability to left side is bigger so its final velocity is "left" handside. Do this serially for all penetrated particles (which should be a few only?)
Its adding N particles N*M probabilities subtracted from all other particles probability maps which is N * N * M operations where M is K * L * M of a K by L by M sized cube space

Related

Catmull Clarke doesn't preserve planar normals

In the toy example I show, one of the surface normals is clearly incorrectly pointing inwards. I can create a new cube with the normals outward facing as expected, but after processing with Catmull Clarke, there is no guarantee that all normals will remain extant facing.
Since I'm using quadrilaterals by necessity, I know I can fix the face by transposing the vertice order i.e. [a b c d] -> [d c b a] and thus fix the normal. But how do I determine that a given face's normal is pointing the wrong direction?
(not enough rep to embed) https://gyazo.com/e20576e700196a43a2378eb055a71b38
You can check for sign of the dot product between the face normal vector and the vector from the cube's centroid to any point on the face.
Let's say the normal vector of the face [a,b,c,d] is n. Next, compute the centroid of the cube by averaging its 8 vertex coordinates, and let's call it p.
Then, calculate dir = dot(n,(a-p)). If dir > 0, the normal n is pointing outwards from the cube. If dir is negative, you have to flip the normal.
This method will work for the faces of any convex polyhedron. If you're dealing with non-convex polyhedra, you will have to use an approach like the one mentioned here.

Indexing along a line of 3 D array

Consider a line joining two point X(a, b, c) and Y(d, e, f)in a 3 dimension array. How to find indices of all points in between them along the line, except Least square?
You should definitely stay away from least squares, which would browse the entire 3D space if I understood you correclty. Instead, have a look at Bresenheim's Line Algorithm.
Basically you start with the starting cube, compute the line's gradient in each XYZ direction, and start marching.
You alternate marching in X (for example) direction until the line is no longer inside the cube, then you switch to whichever other direction (Y, Z) brings the line back into the current cube. And so on an so forth until the current cube is the target.
All usual links are in 2D, but the process in 3D is exactly the same.
The trickier bits resides in choosing which direction to start matching. There's an algo in 3D, which whould be adapted to 2D.
Notes:
A cool optimization is, each time you march in a given direction, you can march Nx, or Ny, or Nz steps straight. these 3 numbers can be computed before hand and will never change.
A cooler optimization, is, you should only have to compute the order of X-Y-Z iteration (which might well be Y,X,Z in some cases) only once, at the beginning. Then the marching is nicely periodic and should stay the same until the target is reached.

Sorting array of points in clockwise order

Is there such an algorithm to sort an array of 3D points in clockwise order?
I'm specifically dealing with right triangle in my case so only 3 points. (for build mesh)
Assume you have two edges connecting your three vertices.
E1 = V2 - V1
E2 = V1 - V3
They span a triangle. You can calculate the triangle's normal N like this:
N = cross(E1, E2)
This tells you which direction the triangle is facing. You can calculate whether the triangle is facing towards, or away from, a certain point of view P by projecting N onto the distance of your triangle from P.
D = V1 - P
d = dot(N, D)
If d is positive, the triangle looks away from P, if it is negative, it faces P.
You are now able to judge for every set of (V1,V2,V3) whether they are sorted correctly or not. If not, just swap V2 and V3 and they will be.
There is one pitfall though. If you are trying to build the hull of a closed mesh, the requirement is that all triangles are facing towards the outside. This can not be modelled by trying to make all triangles face a certain point, because that point would have to be different for each triangle. If the mesh is convex through, you can model it by requiring that all triangles face away from a certain point, which lies inside the convex mesh.
The algorithm for sorting is not difficult. The problem is, what plane that those points lie on. And which side it facing
Only a bunch of points cannot clockwise or counter clockwise by itself. You need a plane and a side to reference those point
edit : Actually what I used to said is a bit inaccurate. What you really need is a position and direction to reference, not a plane

How to draw a moving laser beam?

I'm looking to draw a laser beam which can possibly bounce around a box. Basically the laser beam is of variable length and when it bounces off a surface it will reflect at the angle that it collides.
I can handle the collision stuff myself (probably, haven't tried it yet though), but I'm confused about how the actual drawing would work here. It's not like I'm drawing a straight line, I need to sometimes duplicate the line so there are two lines at angles to each other, but when the laser beam stops, the game needs to work out where the end of the beam is so that it can stop drawing the first line after the entire beam has bounced off the surface.
Sorry for the poor explanation.
My math and trig are a little rusty but here's my attempt.
The correct position and length of your beam depends on four variables,
v, the velocity of the beam, since presumably this is not a true laser beam and thus it's velocity is much slower than c. For convenience, we can store v as distance covered in the forward direction from the beam's perspective, per unit of time.
theta, the angle of incidence, that is, the angle at which the beam has struck a wall or barrier.
l, the length of the beam.
t, the time of the incident (let T be the current time).
Basically, a beam traveling at velocity v strikes a wall at angle theta. How long will the collision occur? (How long will it be from the time that the collision occurs until the time that the beam has completely traveled past the incidence point?)
First, because the beam is traveling at an angle relative to an orthogonal coordinate set, we should get the x and y components of velocity and length.
v.x = cos(theta) * v
v.y = sin(theta) * v
l.x = cos(theta) * l
l.y = sin(theta) * l
If the walls off which the beam can reflect are themselves at angles, you will have to project onto them by using the wall's angle as a frame of reference (use the difference between the two angles).
Now the time it takes for the beam to strike from the left side and leave out the right side is given by:
d = l.x/v.x
Suppose that the incident begins at time t, and the current time is T. Then, the proportion of the beam which is drawn on the left and right sides of the incidence point is,
r = (T - t)/d
left = l * r
right = l * (1 - r)
This example has been simplified to show only how one might compute the beam position if it strike from the left to the right. I think it should be a fairly simple process to apply these principles to a beam striking a vertical barrier from the top or the bottom. Also, consider the case that the head of the beam strikes a second barrier while still in collision with the first.
In that case, we need another variable in place of l to represent not the entire length of the beam, but the length of the segment of the beam available for collision (Euclidean distance between the two incident locations).
It sounds like you're not really talking about a laser beam but instead about a gun shooting a bright projectile that reflects off the surface, and you then want to watch it bounce around the box. (Well, at least that's the problem I'm answering!) There are more complicated, efficient, general, accurate, etc, methods, but there's an easy solution to the problem, especially when the box has perpendicular walls (i.e. a normal box):
Using the direction that the gun is fired, find the three velocity components, (vx, vy, vz), and at each timestep while you're drawing the bullet, update it's position x+=dtvx, y+=dtvy, z+=dt*vz, and keep doing this until you hit a wall. When you hit a wall, just reverse the appropriate component of the velocity vector, e.g. if you hit the wall parallel to the y-z plane, take vx to -vx. And just keep going the same way until you hit another wall, and then reverse the appropriate component again...
Here's an example in 2D, just so I can show a plot, but 3D is exactly the same with this simple method. I show both the full path in black, and highlight some sections of it in red. Also, the example's in python, but the only import key lines (x+=dt*vx,...) probably won't require much in translation:
from pylab import *
from collections import deque
dt = .01
x, y = .5, .5
vx, vy = .233, .61
data = deque(maxlen=100)
all_data = []
for i in range(6000):
x += dt*vx
y += dt*vy
if x<0 or x>1:
vx = -vx
if y<0 or y>1:
vy = -vy
# store data and plot
data.append((x, y))
all_data.append((x, y))
if i%400==0:
plot(*zip(*data), color='r', linewidth=4)
plot(*zip(*all_data), color='k')
show()
Like I said, not so efficient, but very easy.
I think you'll want to look into OpenGL. Here's an often-linked resource on OpenGL on the iPhone: OpenGL ES from the Ground Up.
Since OpenGL is used on many platforms, there are all sorts of resources out there that you can use. A quick google search for "bouncing laser opengl" produces some promising results. If you throw "gaming" into your search, you'll probably find things more like the example you gave (actually seeing the ends of a laser beam bouncing around).

How can the friction drag be calculated for a moving and spinning disk on a 2D surface?

Let's consider a disk with mass m and radius R on a surface where friction u also involved. When we give this disk a starting velocity v in a direction, the disk will go towards that direction and slow down and stop.
In case the disk has a rotation (or spin with the rotational line perpendicular on the surface) w beside the speed then the disk won't move on a line, instead bend. Both the linear and angular velocity would be 0 at the end.
How can this banding/curving/dragging be calculated? Is it possible to give analytical solution for the X(v,w,t) function, where X would give the position of the disk according to it's initial v w at a given t?
Any simulation hint would be also fine.
I imagine, depending on w and m and u there would be an additional velocity which is perpendicular to the linear velocity and so the disk's path would bend from the linear path.
If you're going to simulate this, I'd probably recommend something like dividing up the contact surface between the disk and the table into a radial grid. Compute the relative velocity and the force at each point on the grid at each time step, then sum up the forces and torques (r cross F) to get the net force F and the net torque T on the disk as a whole. Then you can apply the equations F=(m)(dv/dt) and T=(I)(dw/dt) to determine the differential changes in v and w for the next time step.
For what it's worth, I don't think a flat disk would curve under the influence of either a frictional force (velocity-independent) or a drag force (linearly proportional to velocity).
A ball will move in a large arc with spin, but a [uniform] disk on a 2D surface will not.
For the disk it's center of spin is the same as it's center of gravity, so there is no torque applied. (As mentioned by duffymo, a nonuniform disk will have a torque applied.)
For a uniform ball, if the axis of the spin is not perpendicular to the table, this causes the ball to experience a rotational torque which causes it to move in a slight arc. The arc has a large radius, and the torque is slight, so usually friction makes the ball stop quickly.
If there was a sideways velocity, the ball would move along a parabola, like a falling object. The torque component (and the radius of the arc) can be computed in the same way you do for a precessing top. It's just that the ball sits at the tip of the top (err....) and the bottom is "imaginary".
Top equation: http://hyperphysics.phy-astr.gsu.edu/HBASE/top.html
omega_p = mgr/I/omega
where
omega_p = rotational velocity...dependent on how quickly you want friction to slow the ball
m = ball mass
g = 9.8 m/s^2 (constant)
r = distance from c.g. (center of ball) to center, depends on angle of spin axis (solve for this)
omega = spin rate of ball
I = rotational inertia of a sphere
My 2 cents.
Numerical integration of Newton's laws of motion would be what I'd recommend. Draw the free body diagram of the disk, give the initial conditions for the system, and numerically integrate the equations for acceleration and velocity forward in time. You have three degrees of freedom: x, y translation in the plane and the rotation perpendicular to the plane. So you'll have six simultaneous ODEs to solve: rates of change of linear and angular velocities, rates of change for two positions, and the rate of change of angular rotation.
Be warned: friction and contact make that boundary condition between the disk and the table non-linear. It's not a trivial problem.
There could be some simplifications by treating the disk as a point mass. I'd recommend looking at Kane's Dynamics for a good understanding of the physics and how to best formulate the problem.
I'm wondering if the bending of the path that you're imagining would occur with a perfectly balanced disk. I haven't worked it out, so I'm not certain. But if you took a perfectly balanced disk and spun it about its center there'd be no translation without an imbalance, because there's no net force to cause it to translate. Adding in an initial velocity in a given direction wouldn't change that.
But it's easy to see a force that would cause the disk to deviate from the straight path if there was an imbalance in the disk. If I'm correct, you'll have to add an imbalance to your disk to see bending from a straight line. Perhaps someone who's a better physicist than me could weigh in.
When you say friction u, I'm not sure what you mean. Usually there is a coefficient of friction C, such that the friction F of a sliding object = C * contact force.
The disk is modeled as a single object consisting of some number of points arranged in circles about the center.
For simplicity, you might model the disk as a hexagon evenly filled with points, to make sure every point represents equal area.
The weight w of each point is the weight of the portion of the disk that it represents.
It's velocity vector is easily computed from the velocity and rotation rate of the disk.
The drag force at that point is minus its weight times the coefficient of friction, times a unit vector in the direction of its velocity.
If the velocity of a point becomes zero, its drag vector is also zero.
You will probably need to use a tolerance about zero, else it might keep jiggling.
To get the total deceleration force on the disk, sum those drag vectors.
To get the angular deceleration moment, convert each drag vector to an angular moment about the center of the disk, and sum those.
Factor in the mass of the disk and angular inertia, then that should give linear and angular acclerations.
For integrating the equations of motion, make sure your solver can handle abrupt transitions, like when the disk stops.
A simple Euler solver with really fine stepsize might be good enough.