Volume of a 3D closed mesh car object - volume

I have a 3D closed mesh car object having a surface made up
triangles. I want to calculate its volume, center of volume and inertia tensor.
Could you help me
Regards.
George

For volume...
For each triangular facet, lookup its corner points. Call 'em P,Q,R.
Compute this quantity (I call it "partial volume")
pv = PxQyRz + PyQzRx + PzQxRy - PxQzRy - PyQxRz - PzQyRx
Add these together for all facets and divide by 6.
Important! The P,Q,R for each facet must be arranged clockwise as seen from outside. (Or all counter-clockwise, as long as it's consistent for all facets.)
If the mesh has any quadrilaterals, just temporarily hallucinate a diagonal joining one pair of opposite corners. That makes it into two triangles.
Practical computationial improvement: Before doing math with P,Q and R, subtract the coordinates of some "center" point C. This can be the center of mass, a midpoint between the min/max x, y and z, or any convenient point inside or near the mesh. This helps minimize truncation errors for more accurate volumes.

From numerical point of view, what you are trying to achieve is quite simple and can be reduced to calculating few quadratures. Wikipedia will provide needed information about maths behind it.
If you are looking for out-of-the-box volume calculation, take a look at this entry.
As of inertia -- shape is not enough, as you also need distribution of mass.

Well, there isn't much information on the car being provided here - you should be able to break down the car into simpler shapes - the higher degree of approximation your require - the more simpler shapes you can break it into. (This could be difficult if the car is somehow dynamically generated and completely different every time ... but I don't see that situation making any sense).
This should help with finding the Inertial Tensor of various simpler shapes: http://www.gamedev.net/community/forums/topic.asp?topic_id=57001 , finding the volumes and the likes of things like spheres and cubes is pretty common knowledge so I won't bother linking that.

I think it was Archimedes who discovered that if you submerge the car in a volume of liquid, the displaced liquid will have the same volume as the car.
I'm not sure what this would help you in this case though. Having a liquid simulation running in the background and submerging the mesh into it sounds a bit over the top. Although, I think it does work, and therefore qualifies as a (bit useless nonetheless) answer. ;^)

Related

Registration of slightly overlapping point cloud

Problem image
I am trying to align/register (>4) 2-D point cloud segments from several laser scanners with high accuracy, producing an perimeter contour of the scanned product. The segments between lasers may look like that above. The issue is that the calibration process may be both incorrect, and slightly not accurate enough thus I am where I am (and possibly containing individual elevation tilt errors so the segments are not shape-wise similar--close but not exact) and trying to make the best of the situation.
Visually, the segments have a slight bias in both directions as well as a rotational error compared to each other.
The difficulty is that the segments only partially overlap, contain a low but noticeable noise which maybe coherent, and the sampled point distribution is both low and uneven in the overlapping region, since the camera placement are apart (approximately 90 degrees).
My solution so far is to ignore the rotational bias, estimate the mean bias of selected corresponce points within point cloud segments in the overlapping region, and translate each segment by that estimate until I get to the opposite corner. It works somewhat OK, but it is a problem in the last set of sensors since all the errors appear to add up there. Additionally, it fails when there is little or no overlapping region.
I am not a specialist, so complicated solutions maybe useful for others. A relatively robust, iterative approach that can be simply coded is the best! I am thankfully grateful for any advice to solve this simple but quite challenging problem.

How to smooth hand drawn lines?

So I am using Kinect with Unity.
With the Kinect, we detect a hand gesture and when it is active we draw a line on the screen that follows where ever the hand is going. Every update the location is stored as the newest (and last) point in a line. However the lines can often look very choppy.
Here is a general picture that shows what I want to achieve:
With the red being the original line, and the purple being the new smoothed line. If the user suddenly stops and turns direction, we think we want it to not exactly do that but instead have a rapid turn or a loop.
My current solution is using Cubic Bezier, and only using points that are X distance away from each other (with Y points being placed between the two points using Cubic Bezier). However there are two problems with this, amongst others:
1) It often doesn't preserve the curves to the distance outwards the user drew them, for example if the user suddenly stop a line and reverse the direction there is a pretty good chance the line won't extend to point where the user reversed the direction.
2) There is also a chance that the selected "good" point is actually a "bad" random jump point.
So I've thought about other solutions. One including limiting the max angle between points (with 0 degrees being a straight line). However if the point has an angle beyond the limit the math behind lowering the angle while still following the drawn line as best possible seems complicated. But maybe it's not. Either way I'm not sure what to do and looking for help.
Keep in mind this needs to be done in real time as the user is drawing the line.
You can try the Ramer-Douglas-Peucker algorithm to simplify your curve:
https://en.wikipedia.org/wiki/Ramer%E2%80%93Douglas%E2%80%93Peucker_algorithm
It's a simple algorithm, and parameterization is reasonably intuitive. You may use it as a preprocessing step or maybe after one or more other algorithms. In any case it's a good algorithm to have in your toolbox.
Using angles to reject "jump" points may be tricky, as you've seen. One option is to compare the total length of N line segments to the straight-line distance between the extreme end points of that chain of N line segments. You can threshold the ratio of (totalLength/straightLineLength) to identify line segments to be rejected. This would be a quick calculation, and it's easy to understand.
If you want to take line segment lengths and segment-to-segment angles into consideration, you could treat the line segments as vectors and compute the cross product. If you imagine the two vectors as defining a parallelogram, and if knowing the area of the parallegram would be a method to accept/reject a point, then the cross product is another simple and quick calculation.
https://www.math.ucdavis.edu/~daddel/linear_algebra_appl/Applications/Determinant/Determinant/node4.html
If you only have a few dozen points, you could randomly eliminate one point at a time, generate your spline fits, and then calculate the point-to-spline distances for all the original points. Given all those point-to-spline distances you can generate a metric (e.g. mean distance) that you'd like to minimize: the best fit would result from eliminating points (Pn, Pn+k, ...) resulting in a spline fit quality S. This technique wouldn't scale well with more points, but it might be worth a try if you break each chain of line segments into groups of maybe half a dozen segments each.
Although it's overkill for this problem, I'll mention that Euler curves can be good fits to "natural" curves. What's nice about Euler curves is that you can generate an Euler curve fit by two points in space and the tangents at those two points in space. The code gets hairy, but Euler curves (a.k.a. aesthetic curves, if I remember correctly) can generate better and/or more useful fits to natural curves than Bezier nth degree splines.
https://en.wikipedia.org/wiki/Euler_spiral

Triangulating a huge set of points

When triangulating a set of points and the number of points is huge (10 millions), you need to triangulate one chunk at time after subdividing the problem using a quad-tree or an oct-tree.
So far so good, we are now looking for a smart approach to fill the small straight gaps between each mesh. Do you know a good one?
Thanks.
Rather than finish by welding together the separate parts of the mesh, why not start by decomposing the point set into overlapping chunks ? This way your problem becomes one of removing unwanted edges rather than finding missing ones, at the expense of duplicating the computation of the mesh along the borders. This might be easier though I suspect its computational complexity is no different.
I believe that most standard approaches to triangulation can not be expected to produce the same mesh across the boundary for the two overlapping chunks. However, I also believe (without proof) that the computation of the mesh across the boundary between (the interior of neighbouring) chunks is increasingly likely to produce the same triangulation across the boundary as the depth of the overlap increases.
Think of an existing triangulation of a set of points, and add a new point outside the hull of the existing points. Triangulating the extended set of points will require only local (in some vague sense) adjustment of the existing mesh, in most cases. Simlilarly, deleting a point at the edge of an existing mesh will rarely affect the triangulation at the centre of the mesh.
If this ad-hoc approach doesn't appeal to you, use your favourite search engine and look for parallel delaunay triangulation
If the mesh is connected using linear elements (straight sides), the only way you can have gaps is if endpoints on adjacent edges aren't coincident.
You can check within some tolerance sphere whether two points should be made one, but the tolerance has to be smaller than the shortest edge in your mesh or you'll collapse elements.
The smartest thing I can think of is to parallelize the job. Break the mesh into one chunk per thread/process and do the tolerance check on each one.
It might be a good map-reduce job. Or perhaps GPUs and CUDA would be a good way to go.
When you calculate the distance between two points you can forgo the expensive square root and just look at the square of the distance compared to the tolerance.

Vector Shape Difference & intersection

Let me explain my problem:
I have a black vector shape (let's say it's a series of joined, straight lines for now, but it'd be nice if I could also support quadratic curves).
I also have a rectangle of a predefined width and height. I'm going to place it on top of the black shape, and then take the union of the two.
My first issue is that I don't know how to quickly extract vector unions, but I think there is a well-defined formula I can figure out for myself.
My second, and more tricky issue is how to efficiently detect the position the rectangle needs to be in (i.e., what translation and rotation are needed by the matrices), in order to maximize the black, remaining after the union (see figure, below).
The red outlined shape below is ~33% black; the green is something like 85%; and there are positions for this shape & rectangle wherein either could have 100% coverage.
Obviously, I can brute-force this by trying every translation and rotation value for every point where at least part of the rectangle is touching the black shape, then keep track of the one with the most black coverage. The problem is, I can only try a finite number of positions (and may therefore miss the maximum). Apart from that, it feels very inefficient!
Can you think of a more efficient way of tackling this problem?
Something from my Uni days tells me that a Fourier transform might improve the efficiency here, but I can't figure out how I'd do that with a vector shape!
Three ideas that have promise of being faster and/or more precise than brute force search:
Suppose you have a 3d physics engine. Define a "cone-shaped" surface where the apex is at say (0,0,-1), the black polygon boundary on the z=0 plane with its centroid at the origin, and the cone surface is formed by connecting the apex with semi-infinite rays through the polygon boundary. Think of a party hat turned upside down and crumpled to the shape of the black polygon. Now constrain the rectangle to be parallel to the z=0 plane and initially so high above the cone (large z value) that it's easy to find a place where it's definitely "inside". Then let the rectangle fall downward under gravity, twisting about z and translating in x-y only as it touches the cone, staying inside all the way down until it settles and can't move any farther. The collision detection and force resolution of the physics engine takes care of the complexities. When it settles, it will be in a position of maximal coverage of the black polygon in a local sense. (If it settles with z<0, then coverage is 100%.) For the convex case it's probably a global maximum. To probabilistically improve the result for non-convex cases (like your example), you'd randomize the starting position, dropping the polygon many times, taking the best result. Note you don't really need a full blown physics engine (though they certainly exist in open source). It's enough to use collision resolution to tell you how to rotate and translate the rectangle in a pseudo-physical way as it twists and slides uniformly down the z axis as far as possible.
Different physics model. Suppose the black area is an attractive field generator in 2d following the usual inverse square rule like gravity and magnetism. Now let the rectangle drift in a damping medium responding to this field. It ought to settle with a maximal area overlapping the black area. There are problems with "nulls" like at the center of a donut, but I don't think these can ever be stable equillibria. Can they? The simulation could be easily done by modeling both shapes as particle swarms. Or since the rectangle is a simple shape and you are a physicist, you could come up with a closed form for the integral of attractive force between a point and the rectangle. This way only the black shape needs representation as particles. Come to think of it, if you can come up with a closed form for torque and linear attraction due to two triangles, then you can decompose both shapes with a (e.g. Delaunay) triangulation and get a precise answer. Unfortunately this discussion implies it can't be done analytically. So particle clouds may be the final solution. The good news is that modern processors, particularly GPUs, do very large particle computations with amazing speed. Edit: I implemented this quick and dirty. It works great for convex shapes, but concavities create stable points that aren't what you want. Using the example:
This problem is related to robot path planning. Looking at this literature may turn up some ideas In RPP you have obstacles and a robot and want to find a path the robot can travel while avoiding and/or sliding along them. If the robot is asymmetric and can rotate, then 2d planning is done in a 3d (toroidal) configuration space (C-space) where one dimension is rotation (so closes on itself). The idea is to "grow" the obstacles in C-space while shrinking the robot to a point. Growing the obstacles is achieved by computing Minkowski Differences.) If you decompose all polygons to convex shapes, then there is a simple "edge merge" algorithm for computing the MD.) When the C-space representation is complete, any 1d path that does not pierce the "grown" obstacles corresponds to continuous translation/rotation of the robot in world space that avoids the original obstacles. For your problem the white area is the obstacle and the rectangle is the robot. You're looking for any open point at all. This would correspond to 100% coverage. For the less than 100% case, the C-space would have to be a function on 3d that reflects how "bad" the intersection of the robot is with the obstacle rather than just a binary value. You're looking for the least bad point. C-space representation is an open research topic. An octree might work here.
Lots of details to think through in both cases, and they may not pan out at all, but at least these are frameworks to think more about the problem. The physics idea is a bit like using simulated spring systems to do graph layout, which has been very successful.
I don't believe it is possible to find the precise maximum for this problem, so you will need to make do with an approximation.
You could potentially render the vector image into a bitmap and use Haar features for this - they provide a very quick O(1) way of calculating the average colour of a rectangular region.
You'd still need to perform this multiple times for different rotations and positions, but it would bring it algorithmic complexity down from a naive O(n^5) to O(n^3) which may be acceptably fast. (with n here being the size of the different degrees of freedom you are scanning)
Have you thought to keep track of the remaining white space inside the blocks with something like if whitespace !== 0?

Math programming help for a gimble-based painting machine

I'm an artist involved with building various sorts of computer controlled machines. I've started prototyping a gimble-based XY painting machine and have realized that the maths needed are out of my reach. I'm a decent enough programmer but not strong in math- esp. 3D math.
To get a sense of what I'm needing to do, it might be helpful to look at the rig:
Early prototype:
http://roypardi.com/gimble/gimbleSmall.MOV (small video)
http://roypardi.com/gimble/gimbleLarge.mov (larger video)
The two inner rings represent the X/Y axes and are controlled by stepper motors. I want to be able to use both raster images and vector data (gcode). So I need to be able to address a point in 2D space on the paper/from my data and have the gimble figure out what orientation it needs to be at in order to get there (i.e. how much to step each motor).
I've been searching out 2D > 3D projection, Euler angles, etc. but I'm out of my depth. Any pointers, pushes in the right direction, or code snippets would be most welcome. I can make sense of most programming languages.
Very nice machine you have made, I hope this works for you I believe it is correct.
The way I see it, is to get one angle is simple, but the other is slightly harder to visualise as we have tilted the axis which it turns upon.
I'm going to avoid using tan, as when programming this could result in a division by 0, which could be frustrating. Also Z is going to be the height of the origin above the paper.
YAxis = arcsin( X / sqrt(X² + Z²))
XAxis = arcsin( Y / sqrt(Y² + X² + Z²))
or we could use
XAxis = arcsin(Y / sqrt(Y² + Z²))
YAxis = arcsin( X / sqrt(X² + Y² + Z²))
Also, I'd very much like to see a video of this plotting, if it works.
Edit:
After thinking about it i believe only one solution will work it depends on which axis is affected by the other. Is the YAxis in the Middle or the Xaxis?
I think it's a problem of simple http://en.wikipedia.org/wiki/Trigonometry
Let's say that the distance from the centre of your rings to the nearest point on the paper (which I'll call point 'O' for 'Origin') is distance X.
Take another point P directly north of O, whose distance from O is Y.
To paint this point, you need the angle alpha such that tan(alpha)=Y/X, i.e. you can calculate alpha using the formula "arctan(Y/X)" [arctan is sometimes also known as atan]. Arctan is a trignometric function, which I think you'll probably find defined in the API of a general purpose math library.
The above is the simplest case.
The only other case that I can think of is when the point P isn't due north. Instead of being due north, let's say that its distance is Y1 to the north, and Y2 to the east. The solution is two angles (one angle for each of two rings), one of which is "arctan(Y1/X)" and the other of which is "arctan(Y2/X)".
Perhaps I misunderstand, but I don't believe a gimbal will do what you want. A gimbal can point in any 3D direction, but it cannot move to arbitrary points in 3D space. If the plane of the paper intersects the volume swept by the pen held in the gimbal, the pen might be able to draw a circle, but nothing more. Even drawing a circle is not a sure thing, since in this case the paper would also intersect the volume swept by the gimbal rings; trying to orient the pen would make a ring hit the paper.
I think what you want is a plotter, not a gimbal.

Resources