Related
My name is Stanley and I need help :).
I am attempting to find the average rotation from an array of positions. (Stay with me here). If you are confused with what I mean, just like I am myself, then here is an example. I am making a boating game and there are raycast hits that find four points at each corner of the boat. In order to make the floating look realistic, I made it so that the average y position of all four points would be the y position of the boat. But the average rotation I cannot seem to figure out.
I have done some tests if there is a point at 0,0,0 and 1,1,0 and 0,1,1 the average rotation using xyz coordinates is -25,-25,50 and I can't seem to figure out the math behind it. (I eyeballed the final rotation in unity and it looks pretty spot on, that is how I got that number.) If anyone has seen anything about this online like an equation or way of solving this it would be a huge help.
Thanks Everyone
Stan.
I dont know whether I understood you correctly, but how exactly do u get an average rotation of (-25, -25, 50)? What I would do is (if the number of points are always three) create a plane, calculate the normal of that plane and trying to figure out what combination of rotation matrices lead to the corresponding components.
If your three points are (0,0,0), (1,1,0), (0,1,1) the corresponding plane's normal would be (-1, 1, -1), and from that you could deduce what the rotations must be in order to get a reference vector (lets say (1,0,0)) that satisfies R_X(a) * R_Y(b) * R_Z(c) * (1,0,0) = (-1, 1, -1)
But I guess thats not what you want, do you?
If a circle is defined by the X, Y of it's center and a Radius, then how can I find a Circle that encompasses a given number of circles? A single circle that is the smallest possible circle to completely contain 2 or more circles of any size and location.
At first I tried just encompassing 2 circles by finding the midpoint of the centers and that being the midpoint of the new circle while the radius was equal to the half of the radius of the 2 initial circles and half the distance between their centers, but somehow it always turned out to be a little off. The problem always seemed to be a problem with finding the radius, but I have such a headache about this I can't make it work.
I don't necessarily need a method for finding a circle that encompasses 3 or more circles. I can find a circle that encompasses 2, take that circle and encompass it with another, and another, and the final circle should encompass all circles given throughout the steps.
Given two circles, with centers [x1,y1], [x2,y2], and radii R1 and R2. What is the center of the enclosing circle?
Assume that R1 is no larger than R2. If the second circle is the smaller, then just swap them.
Compute the distance between centers of the circles.
D = sqrt((x1-x2)^2 + (y1-y2)^2)
Does the first circle lie entirely inside the second circle? Thus if (D + R1) <= R2, then we are done. Return the larger circle as the enclosing circle, with a center of [x2,y2], with radius R2.
If (D+R1) > R2, then the enclosing circle has a radius of (D+R1+R2)/2
In this latter case, the center of the enclosing circle must lie along the line connecting the two centers. So we can write the new center as
center = (1-theta)*[x1,y1] + theta*[x2,y2]
where theta is given by
theta = 1/2 + (R2 - R1)/(2*D)
Note that theta will always be a positive number, since we have assured that (D+R1) > R2. Likewise, we should be able to ensure that theta is never larger than 1. These two conditions ensure that the enclosing center lies strictly between the two original circle centers.
There problem you have at hand is called Smallest enclosing sphere of spheres. I have written my thesis about it, see "Smallest enclosing ball of balls", ETH Zurich.
You can find a very efficient C++ implementation in the Computational Geometry Algorithms Library (CGAL) in package Bounding Volumes. (There is no need to use all of CGAL; just extract the required source and header files and you are up and running.)
Note: If you are looking for an algorithm to compute the smallest enclosing sphere of points only, there are other implementations out there, see this post.
Since my inexact solution was not liked. Heres a way to get the exact solution. But its slow ( O(N^4)? ) and computationally nasty. (Unlike the inexact method)
First you need to know that given three circles we can find a circle tangential to them all than contains all three. This is one of the circles of Apollonius. You can get the algorithm from mathworld.
Next you can show that the smallest enclosing circle for N circles is tangential to at least 3 of the N circles.
To find this circle we do the following
loop through all triples of circles - O(N^3)
find the enclosing Apollonius circle of those 3 circles - computationally nasty
if it encloses all the circles add it to a list of potentials - check is O(N)
Solution is potential with smallest radius
There may be some tricks to speed this up, but it should give you the exact solution.
Some of the "tricks" for getting Smallest Enclosing Circle algorithms to linear time may be applicable here, but I suspect they would not be trivial adaptions.
I'm going to recommend against this, now
See the discussion below.
Original thoughts
I would consider an iterative push-pull method.
Guess where to put the center (simplest would be the mean position of all centers)
Compute the vectors to the farthest point on each circle. These are always in the direction to the center of that circle and have length distance_to_center_of_circle[i]+radius_of_circle[i] and form the vector sum as you go. Also note that the necessary radius at the current location is the maximum of these lengths.
Propose a step of (say) 1/5 or 1/10 of the vector sum from 2, and redo the computations from 2 for the new point
If the new point needs a smaller circle than the old, make the new point the current point, otherwise, split the difference, reduce the size of the proposed step (say half it).
goto 3
You're done when it stops[+] converging.
Nikie poked at it until...
As requested clarifying step two. Call the position to be tested \vec{P} (a vector quantity).[++] Call the centers of each circle \vec{p}_i (also vector quantities) and the radius of each circle is r_i. Form the sum \sum_i=1^n \hat{p_i - P}*|(p_i-P)|+r_i).[+++] Each element of the sum points in the direction from the current evaluation point towards the center of the circle in question, but is longer by r_i. The sum itself it a vector quantity.
The radius R need to enclose all the circle from P is the max(|p_i-P|_r_i).
Pathological case
I don't think the particular case nikie's brought up is a problem, but it has put me onto a case where this algorithm fails. The failure is one of failing to improve a solution, rather than one of diverging, but still...
Consider four circles all of radius 1 positioned at
(-4, 1)
(-5, 0)
(-4, 1)
( 5, 0)
and a starting position of (-1, 0). Symmetric by design so that all distances lie along the x axis.
The correct solution is (0, 0) with radius 6, but the vector calculated in step 2 be about ::calculates furiously:: (-.63, 0), pointing in the wrong direction resulting in never finding the improvement towards the origin.
Now, the algorithm above would actual pick (-2, 0) for the starting point, which gives an initial vector sum of ::calculates furiously:: about +1.1. So, a bad choice of step size on (3) would result in a less than optimal solution. ::sigh::
Possible solution:
In (3) throw a random fraction between (say +1/5 and -1/5) possibly weighted towards the positive size.
In (4) if the step is rejected, simply return to step three without altering the step size limits.
However, at this point it is not much better than a pure random walk, and you don't have an easy condition for knowing when it has converged. Meh.
[+] Or slows to your satisfaction, of course.
[++] Using latex notation.
[+++] Here \hat{} means the normalized vector pointing in the same direction as the argument.
I've taken what some of you had to say and here's the solution I discovered:
public static Circle MinimalEnclosingCircle(Circle A, Circle B) {
double angle = Math.Atan2(B.Y - A.Y, B.X - A.X);
Point a = new Point((int)(B.X + Math.Cos(angle) * B.Radius), (int)(B.Y + Math.Sin(angle) * B.Radius));
angle += Math.PI;
Point b = new Point((int)(A.X + Math.Cos(angle) * A.Radius), (int)(A.Y + Math.Sin(angle) * A.Radius));
int rad = (int)Math.Sqrt(Math.Pow(a.X - b.X, 2) + Math.Pow(a.Y - b.Y, 2)) / 2;
if (rad < A.Radius) {
return A;
} else if (rad < B.Radius) {
return B;
} else {
return new Circle((int)((a.X + b.X) / 2), (int)((a.Y + b.Y) / 2), rad);
}
}
Circle is defined by the X, Y of it's center and a Radius, all are ints. There's a constructor that is Circle(int X, int Y, int Radius). After breaking out some old trig concepts, I figured the best way was to find the 2 points on the circles that are farthest apart. Once I have that, the midpoint would be the center and half the distance would be the radius and thus I have enough to define a new circle. If I want to encompass 3 or more circles, I first run this on 2 circles, then I run this on the resulting encompassing circle and another circle and so on until the last circle is encompassed. There may be a more efficient way to do this, but right now it works and I'm happy with that.
I feel weird answering my own question, but I could not have come to this solution without everybody's ideas and links. Thanks everybody.
So if you don't need the exact circle this approximation might do.
Take the average of all your centers of the circles call this
point X
Let R1 be the maximum distance from X to a circle center.
Let R2 be the maximum radius of the circles
The all the circles must fall inside the circle centered at X with radius R1+R2
This is not a trivial problem. I haven't read all the answers above, so if I repeat what someone has already said, the fault is mine.
Each circle c_i is defined by 3 parameters x_i,y_i,r_i
3 parameters need to be found x*,y*,r* for the optimal circle C*
C* is such that it contains c_i for all i
Let d_i = ||(x,y)-(x_i,y_i)|| + r_i
Then if r is radius of a circle that contains all c_i, then r >= d_i for all i
We want r to be as small as possible
So, r* = max(d_i)
Thus we want to minimize the max of d_i
So (x*,y*) are given by the arg min of max(d_i). And once (x*,y*) are found, r* can be readily computed and will equal max(d_i). This is a minimax problem.
To make things easier to understand consider just 2 circles, how can we find (x*,y*)?
(x*,y*) can be found by finding the (x,y) that minimize (d_1 - d_2)^2. In the general case
let e_ij = (d_i - d_j)^2
Then define e = \sum e_ij for i != j (there are n Choose 2 terms in this sum)
(x*,y*) = arg min of e
And this is what needs to be solved for.
Tip: if r_i = 0 for all i, then this reduces to the traditional minimum enclosing circle problem when the input is a bunch of points, and we want to find minimum circle that covers all of them.
Just understand the equations of the circle and derive an equation (or a series) for find the answer then start implementing. Perhaps we will be able to help you in that given you have done something.
I'm trying to create a .bvh file via kinect.
It means in need to get rotations of each bone of a skeleton. I need the rotations in Euler angles. I already tried many different approaches, but any of them gave me good result. Could anyone give me some advice what am I doing wrong?
Here is (I think) the main part of my code.
foreach (Skeleton skeleton in newSkeleton)
{
if (skeleton.TrackingState != SkeletonTrackingState.Tracked)
continue;
int j = 0;
foreach (BoneOrientation orientation in skeleton.BoneOrientations)
{
Matrix4 matrix = orientation.HierarchicalRotation.Matrix;
double y = Math.Asin(matrix.M13);
double x = Math.Atan2(-matrix.M23, matrix.M33);
double z = Math.Atan2(-matrix.M12, matrix.M11);
rotationMatrix[j, 0] = x * 180 / Math.PI;
rotationMatrix[j, 1] = y * 180 / Math.PI;
rotationMatrix[j, 2] = z * 180 / Math.PI;
j++;
}
}
My euler angles should be stored in the rotationMatrix array for further use (saving into bvh file). Here comes my problem... the rotations calculated this way doesn't make sense (I mean they have nothing to do with the position of me ahead of kinect) and they seems to be random.
Edit:
I would also need to explain some unclear topics about kinect. I tried to Google it, but didn't succeed.
Does kinect skeleton have something like zero pose? I mean any pose where all bone rotations are zero. (e.g. T-pose and so on)
What kind of standards does kinect use? I mean how does kinect store data into rotation matrices? I would like to know if the matrix is like
[X1, Y1, Z1,
X2, Y2, Z2,
X3, Y3, Z3]
or does it use some other order?
About the marices.. Is it possible to calculate Euler angles from the matrix given by kinect in standard way? I mean some of algorithms mentioned in this paper?
http://www.geometrictools.com/Documentation/EulerAngles.pdf
OK, after some more time spend researching, i think i might be able to answer some of mine questions. If is anyone interested...
i havent found any zero pose, but i created my own using some kind of calibration. I saved rotation matrices for my chosen zero pose (let's call these Mz), made these matrices trandposed (MzT) and I multiplied all the next matrices kinect gave me (let's call these Mr).
It means I calculated matrices for further use this way: M = MzT x Mr.
I used the conversion from link in 3. question for Rxyz order and all worked well, it means the rotation matrices given by kinect probably have the order given in the question. This should be answer to the third question as well.
I suppose by distance I mean radius, so another way of phrasing it would be "how do I get random points on the circumference of a circle of a given radius, given also the circles centre point".
I don't understand the markdowns. This is a simple C# question that requires a simple C# answer as provided adequately by Daniel DiPaolo below.
Neither the markdowns nor the associated comments are helpful by way of improving the question or providing an answer.
If your center and radius are fixed, then really the only thing that's varying is the angle. So, just calculate some random angle between 0 and 360 degrees (or 0 and 2π radians) and use that to get the x-y coordinates using the polar conversion.
x = r × cos( θ )
y = r x sin( θ )
Add the x,y coords of your center as the offset and you have your coordinates.
Calculate a random angle and then use the angle and distance as a polar offset from the first point.
Have a look at Circle Point Tracking there's a few methods for picking points.
Algorithmic code
Given circle of {[0,0], 1} - {centre, radius}
x => Get random number x from [-1, 1]
y+ or y- => Randomly select either positive or negative y quarter (0 or 1 for example)
y => Get intersection of vertical line x=X1 (from step 1) and circle, select either positive or negative quarter (from step 2)
NB This is can be done simpler, faster, and more uniformly distributed by using angles, see other answers.
The problem with my algorithm, in case anyone would try to use it, is that because of the bending shape of a circle, points close to X=r+ and X=r- will be picked up less often than the one close to X=0. See comments by #Servy.
I played around with it for a while, but I simply can't figure it out.
I made a tank that fires missiles, and when the missiles hit the walls, I want them to bounce off, but I want them to bounce off to the right angle.
Right now I haven't got any obstacles, the missiles just bounce off when they get outside the viewportRectangle I made.
Is the solution I'm looking for quite advanced?
Is there a relativly simple way to do it?
You might think that because your walls are aligned with the coordinate axes that it makes sense to write special case code (for a vertical wall, negate the x-coordinate of the velocity; for a horizontal wall, negate the y-coordinate of the velocity). However, once you've got the game working well with vertical and horizontal walls, probably the next thing you'll think is, "what about walls at arbitrary angles?" So it's worth thinking about the general case from the beginning.
In the general case, suppose your missile has velocity v and hits a wall with surface normal n.
Split v into components u perpendicular to the wall and w parallel to it.
Where:
u = (v · n / n · n) n
w = v − u
Here, v · n is the dot product of the vectors v and n. See the link for an explanation of how to compute it. The dot product n · n evaluates to the square of the length of the normal vector; if you always keep your normals in the form of unit vectors then n · n = 1 and you can omit the division.
After bouncing, the component of motion parallel to the wall is affected by friction f, and the component perpendicular to the wall is affected by elasticity, which can be given in the form of a coefficient of restitution r.
So the velocity after the collision is v′ = f w − r u. In a perfectly elastic, frictionless collision, v′ = w − u; that is, the motion is reflected about the normal at the point of collision, as in the diagram given in Bill's answer.
This approach works just the same in three dimensions too.
(Obviously this is a very simplified notion of bouncing; it takes no account of angular momentum or deformation. But for many kinds of video games this kind of simplification is perfectly adequate.)
I think an easier way to do this is to use the velocity of the missile instead of calculating angles. Say you have a missile that has xVelocity and yVelocity to represent its movement horizontally and vertically. Those velocities can be positive or negative to represent left, right, up, or down.
If a missile hits a top or bottom border reverse the sign of the yVelocity.
If a missile hits a left or right border reverse the sign of the xVelocity.
This will keep the movement in the opposite axis the same.
Borrowing the image from ChrisF's answer, let's say the missile starts out at position I.
With the xVelocity and yVelocity both being positive (in 2D graphics right and down are typically positive) the missile will travel in the direction indicated. Let's just assign values of
xVelocity = 3
yVelocity = 4
When the missile hits the wall at position C, its xVelocity shouldn't change, but its yVelocity should be reversed to -4 so that it travels back in the up direction, but keeps going to the right.
The benefit to this method is that you only need to keep track of a missile's xPosition, yPosition, xVelocity, and yVelocity. Using just these four components and your game's update rate, the missile will always get redrawn at the correct position. Once you get into more complicated obstacles that are not at straight angles or are moving, it will be a lot easier to work with X and Y velocities than with angles.
For perfect particles (& light) the angle of reflection is equal to the angle of incidence, as illustrated by this diagram (from commons.wikimedia.org).
The Wikipedia page on reflection is quite good at explaining how it works.
It's a little bit more complicated when you take into account the elasticity and materials of the object and the obstacles, but this is probably good enough for most applications.
I've had this problem, the only way I found was separating the axes of collision!
Try it:
x += velocity * Math.cos(angle * Math.PI /180);
y += velocity * Math.sin(angle * Math.PI /180);
if (x < 0 || x > canvas.width) {
angle = 180 - angle;
}
else if (y < 0 ||y > canvas.height) {
angle = 360 - angle;
}
I hope this helps you!
As an aside to the specific physics question you are asking, I would recommend the book "Beginning Math and Physics for Game Programmers" by Wendy Stahler. I found it quite useful for my game/physics programming projects.
The code that accompanies the book is C++ but if you know C#, it would be pretty easy to make the conversion.
Have a good one!
180-a will not work in all instances, unless you are merely working a bounce on a top surface when X is increasing.
One direction to head is the XNA forums or pick up XNA sample code. It is C# and it is for building games. I am not stating you want to build your games in XNA, but it is a great tool, and it is free.
Not complicated at all - pseudo-code:
angleObjectHitWall = a;
bounceAngle = 180-a;
Of course this is a very simple calculation, and is totally irrelevant once you start to take into account factors such as material, gravity, walls which aren't straight, etc...
This is really a physics question, so if you are not a physicist (and since you are asking this question, I'm going to take it that you are not) it will require a lot of reading and brainstorming to get it right.
I suggest reading this wikipedia entry to get the basic idea about the depth of your question.
If you only want to make it "look plausible" then I wouldn't worry about it too much and use Bill the Lizard's answer, however if you want to make it right you will have quite an adventure. Don't let this scare you tho! Good luck!
a = 2w - b
where:
a => resulting angle
w => wall or floor or ceiling angle
b => ball angle
This is what I come up after trying to find the simplest formula for computing just the resulting angle of ball bouncing the walls, ceiling and floor. The result could go beyond +360 or -360 degrees but they are still equivalent angle.For example if the ceiling angle is 270deg and the ball angle is 30deg, the resulting angle is 510deg which is equivalent to +150deg or -210 deg. If you'll use 90deg for the ceiling instead of 270deg, the result is still 150deg.
if(!Collide(Missle, Mainchar)){
(Velocity.x)*-1;
(Velocity.y)*-1;
}
It works and is simple, good luck.