ok i am trying to get a pool game going in c#/java.
start = back of pool cue(x,y)
end = front of pool cue(x,y)
circles = list of balls (x,y,r)
So every time you move your mouse I update start, end and then I loop through `circles check if it intersects. Then this is my problem I need to figure out what will happen with ball if I hit it at the intersection point( will it go right up down).
How will I do this. I looked at some examples on google but could only find example where they did it with vector and that way over my head....
my first thought was get the angle of the pool cue and from the circle mid point draw a line the same angle but for some reason that is wrong. It might be my GetEnd function
public Point GetEnd(Point start, double angle, int len)
{
double y = start.Y + (len * Math.Sin(angle));
double x = start.X + (len * Math.Cos(angle));
return new Point((int)x, (int)y);
}
I think the angle between the direction where the cue points and the ball moves is:
Math.ASin(a/r)
with a the minimal distance between the ray representing the cue and the center of the ball, and r the radius of the ball.
You obtain a by minimizing a^2 = (Cue.Position+Cue.Direction*Lamda-Ball.Position)^2 for lamda and then calculating the squareroot of that expression.
But I'm too lazy to reformulate that expressions without vectors.
Related
I am looking to generate some 3D trajectory data for an aircraft simulation.
The idea is that the aircraft takes off at some location x and continues to ascend at some average ascent velocity a_v and angle a_theta until it reaches a maximum altitude m_a. The aircraft would then continue at its m_a until it reaches a certain distance d_d from its destination, at which point it will begin its descent at some angle d_theta with an average descent velocity of d_v. Finally, the aircraft lands at destination y.
I would like the function to return a list of 3D points.
I am looking to implement this in either Python (preferred) or C#.
For illustration purposes:
Does anyone know how I can achieve this? Is there perhaps some open source project which does this? I have been looking for a while now, but have not found anything.
I recommend you to solve the problem in 2 independent steps so that the airplane does not pass through the ground :
Calculate the path on the surface of a sphere.
Interpolate the height along this path.
For 1. you can use the spherical interpolation techniques on Quaternions.
Quaternion slerp(Quaternion v0, Quaternion v1, double t) {
// Only unit quaternions are valid rotations.
// Normalize to avoid undefined behavior.
v0.normalize();
v1.normalize();
// Compute the cosine of the angle between the two vectors.
double dot = dot_product(v0, v1);
const double DOT_THRESHOLD = 0.9995;
if (fabs(dot) > DOT_THRESHOLD) {
// If the inputs are too close for comfort, linearly interpolate
// and normalize the result.
Quaternion result = v0 + t*(v1 – v0);
result.normalize();
return result;
}
// If the dot product is negative, the quaternions
// have opposite handed-ness and slerp won't take
// the shorter path. Fix by reversing one quaternion.
if (dot < 0.0f) {
v1 = -v1;
dot = -dot;
}
Clamp(dot, -1, 1); // Robustness: Stay within domain of acos()
double theta_0 = acos(dot); // theta_0 = angle between input vectors
double theta = theta_0*t; // theta = angle between v0 and result
Quaternion v2 = v1 – v0*dot;
v2.normalize(); // { v0, v2 } is now an orthonormal basis
return v0*cos(theta) + v2*sin(theta);
}
You didn't write any code, so I won't write any either. Python with math package is more than enough to solve this problem.
Required steps:
The plane should fly on a great circle. This means you only need one distance to describe X and Y.
You could place the origin at X and specify Y with a latitude.
Calculate the tangent of the Earth at X, and rotate by a_theta. Find the point where it reaches m_a altitude.
Calculate the tangent of the Earth at Y, and rotate by d_theta. Find the point where it reaches m_a altitude.
Draw an arc between the two previous points, with a radius of EarthRadius + m_a
Every coordinate is known in the 2D of the great circle, you just need to rotate them back to 3D coordinates.
For a list of 3D points, you don't need either a_v, d_v or d_d.
I have successfully implemented the floor clip plane to measure the distance of left foot to the floor, which is fairly accurate. The problem I have is that as I move away from the camera (i.e. left foot Z axis is increased), the foot distance to the floor changes (increases).
Note: The floor itself is not tilted nor the Kinect stand.
I tested it with Kinect 1 and had the same result. The subject's head height (Y axis) also changes value as I move away or get closer to the camera. It does not matter of the camera is tilted or line of sight. the D value in the FloorClipPlane equation shows a constant number during the test.
A = bodyFrame.FloorClipPlane.X;
B = bodyFrame.FloorClipPlane.Y;
C = bodyFrame.FloorClipPlane.Z;
D = bodyFrame.FloorClipPlane.W;
distanceLeftFoot = A * leftFootPosX + B * leftFootPosY + C * leftFootPosZ + D;
Just to let you know, I have coordinate mapping between depth and colour. Not sure if that has anything to do with the issue.
The FloorClipPlane is expressed in hessian normal form - as explained in the docs. Specifically, your A, B, and C values compromise the unit vector from camera origin (center of the Kinect) to floor plane such that it produces a perpendicular intersection with the floor plane. D is the magnitude of that vector (distance from camera origin to floor plane).
Even if you think the floor is flat and the Kinect is parallel to the ground, you have a perspective warping problem which means the body location (measured in depth space) is going to change as you come closer and further.
To fix this you need to provide as input both your 3D coordinate values and the floor plane, which will then give you back what you want, a measured distance from floor plane to joint:
// j is your joint - left foot or any other joint
float x = j.Position.X;
float y = j.Position.Y;
float z = j.Position.Z;
float distance = (Math.Abs((x * floorPlane.X) + (y * floorPlane.Y) + (z * floorPlane.Z) + floorPlane.W))/((float)Math.Sqrt((Math.Pow(floorPlane.X,2)) + (Math.Pow(floorPlane.Y, 2)) + (Math.Pow(floorPlane.Z, 2))));
I hope this helps you. Can't elaborate further what influence your mapping from depth to color might be doing here without seeing what you are specifically doing
I'm using C#, I have a list of Vector points and would like to try and approximate how close they look like a circle.
Any ideas how to implement this or if someone else has?
Based on the "gestures" tag I guess you not only want to know how close are these points to the smallest-circle (search for "Smallest-circle problem"), but you have to be concerned also about their order and spread:
I would start with the distance from the smallest-circle. If they are too far, you're done, it's not a circle.
If they are close enough to your configured threshold, compute the angle between the vector defined by the circle center, first point and each other point (picture bellow)
Check that each angle is greater than the previous.
Check that difference between any two angles next to each other is not over some configured threshold.
Check that the last point is close enough to the first one.
You will probably think of some other checks eventually, so make it simple to extend.
Another possibility:
Find the centroid
(http://en.wikipedia.org/wiki/Centroid#Of_a_finite_set_of_points) of
the points
Determine the distance (radius) of each point from the location of
the centroid
Calculate the distribution and determine if the points
are within acceptable tolerances (e.g. standard deviation < ±0.05 × mean radius or something like that)
Without knowing more about the source of the points, it's hard to suggest the best solution.
These might be of use: http://link.springer.com/article/10.1007%2FBF02276879#page-1 and http://www.dtcenter.org/met/users/docs/write_ups/circle_fit.pdf. Those methods will give you the best fitting circle through the points, but you are still going to need to determine whether your data points are close enough for your purposes.
UPDATE: based on the 'gesture' tag, somebody has already implemented it: http://depts.washington.edu/aimgroup/proj/dollar/
1) Pick any three points from that list, find the center of their appropriate circle
We can do this, using triangle circumcircle construction method, you find the medians of all three sides (two are sufficient) and their intersection is the center of the circle. Something like this:
public PointF findCenter(PointF a, PointF b, PointF c)
{
float k1 = (a.Y - b.Y) / (a.X - b.X) //Two-point slope equation
float k2 = (a.Y - c.Y) / (a.X - c.X) //Same for the (A,C) pair
PointF midAB = new PointF((a.X + b.X) / 2, (a.Y + b.Y) / 2) //Midpoint formula
PointF midAC = new PointF((a.X + c.X) / 2, (a.Y + c.Y) / 2) //Same for the (A,C) pair
k1 = -1*k1; //If two lines are perpendicular, then the product of their slopes is -1.
k2 = -1*k2; //Same for the other slope
float n1 = midAB.Y - k1*midAB.X; //Determining the n element
float n2 = midAC.Y - k2*midAC.Y; //Same for (A,C) pair
//Solve y1=y2 for y1=k1*x1 + n1 and y2=k2*x2 + n2
float x = (n2-n1) / (k1-k2);
float y = k1*x + n1;
return new PointF(x,y);
}
2) Check if the other points are equivalently distanced from this center, if yes, you have a circle, if no, you don't.
P.S. I haven't tested the code, so be prepared to debug. Ask if you need anything else
Take any three points from your point set.
If the points are co-linear then, your point set doesn't all lie on a circle.
Find the circumcircle of the triangle. The diameter is given by: d = (a*b*c)/2*area. The center of the circle is the point of intersection of the perpendicular bisectors of the three sides.
Now for every remaining point in the point set, if the distance from the center is not equal to the radius then the points are not on a circle. You can speed up the calculations by comparing the square of the radius against the square of the distance between the given point and the center.
So basically, I am doing my first xna game and it's an arkanoid game. My ball right now is a square that rotate.
Unfortunately, it's impossible to correctly detect the collision of a rotated rectangle in xna.
I found thing about scalars but I am only in computer science in college so I don't know about these big maths...
Can anyone direct me in the right way to detect these kind of collision ? or at least to be able to obtain a new rectangle in the right way so that I can detect the collision on this one?
EDIT
I just thought about making my rotating square in a still square and test the collision with the outer square would that be viable ?
If you want to detect a collision of the square ball with the outer rectangle, you need to know the coordinates of the four corners of the ball. Then simply compare these points with the outer rectangle.
If s is the length of the sides of the rectangle. The corners can be calculated like this:
double h = 0.707106781 * s; // Half diagonal
double angle = rotation_angle + 0.25 * Math.PI; // 0.25 * Math.PI = 45 degrees
// inclination of the diagonal.
double x = h * Math.Cos(angle);
double y = h * Math.Sin(angle);
// The four points are
p1x = +x + squareCenterX;
p1y = +y + squareCenterY;
p2x = -y + squareCenterX;
p2y = +x + squareCenterY;
p3x = -x + squareCenterX;
p3y = -y + squareCenterY;
p4x = +y + squareCenterX;
p4y = -x + squareCenterY;
Do you really want your ball to be a square?
Or a simple circle could do?
You could use a collision circle instead, the logic behind the collision is much more simple than rotated squares... (If you really want a square and a pixel-perfect collision, disregard this answer and see Terrance's comment)
if(circle.Center.X - circle.Radius < ScreenBounds.XMin ||
circle.Center.X + circle.Radius > ScreenBounds.XMax ||
circle.Center.Y - circle.Radius < ScreenBounds.YMin ||
circle.Center.Y + circle.Radius > ScreenBounds.YMax)
{
//Ball is partly or entirely outside of the screen
}
This is not really a direct answer to your question, but more of an alternative
Edit: This code assumes that the position of your ball is relative to its center.
Also, you can approximate your rotated square's collision with a collision circle (or a non-rotated square as a matter of fact). The collision won't be pixel perfect, but I think that'll be hardly noticeable. It will also be easier to implement (considering this is your first game).
I am trying to make a user-defined arc with the Helix 3D toolkit. The user selects 3 points on the arc (start, middle, end) and the program finds the center of the circle and draws the arc from start to end. My problem is I'm not good at math and I am having problems making this work. My main problem is getting the start and end angles and having it draw arcs of all sizes accurately. Any help is appreciated. Here is my code:
private void Draw_Arc(object sender, MouseButtonEventArgs e)
{
linept = new List<Point3D>();
linept.Add(startPoint);
linept.Add(endPoint);
linept.Add((Point3D)GetPoints(e));
LinesVisual3D line = new LinesVisual3D();
line.Thickness = 2;
line.Color = Colors.Blue;
line.Points = linept;
port.Children.Add(line);
double startAngle, sweepAngle;
Point3D center = GetCenterOfArc(linept.ElementAt(0), linept.ElementAt(1), linept.ElementAt(2));
GetAngles(linept.ElementAt(0), linept.ElementAt(1), linept.ElementAt(2), out startAngle, out sweepAngle);
circle = new PieSliceVisual3D();
double RadiusX = Math.Abs(startPoint.X - center.X);
double RadiusY = Math.Abs(startPoint.Y - center.Y);
circle.Center = center;
if (RadiusX >= RadiusY)
circle.OuterRadius = RadiusX;
else
circle.OuterRadius = RadiusY;
circle.InnerRadius = circle.OuterRadius + 3;
circle.StartAngle = (180 / Math.PI * Math.Atan2(startPoint.Y - circle.Center.Y, startPoint.X - circle.Center.X));
circle.EndAngle = (180 / Math.PI * Math.Atan2(linept.ElementAt(2).Y - circle.Center.Y, linept.ElementAt(2).X - circle.Center.X));
port.Children.Add(circle);
}
I think that you have to know the center of the circle in order to know the starting and ending angle of the arc.
Say that you just have three points, and you want to find a circle that goes through all three, you basically have three equations with three variables:
(x-x0)^2 + (y-y0)^2 = R^2
(x-x1)^2 + (y-y1)^2 = R^2
(x-x2)^2 + (y-y2)^2 = R^2
Solving that can get a little tricky if you try to program that on your own and have average knowledge in math, but you can do it fairly easily using matrices. Read here for a bit information.
After you've solved the three equations, you should have X, Y, R.
X and Y will be the center point of the circle, and R - it's radius.
Now, as far as I remember, they count the arc's degrees starting from the positive X axis, going upwards. So you would need to calculate the angle between two lines - the line that stretches between the center to your floating point, and the line that stretches from your center point to the "limitless" right. You may just Google "calculate angle between two lines". Repeating that process for both your starting point and your ending point, will give each their respective entering/exiting angle.
The middle point isn't really used anymore, but the radius is. You just set it to be the radius and you're good to go.
I haven't really implemented anything - just giving you a fair direction. (and I bet that there's a much cleaner and nicer-to-work-with solution)