I need to track the speed of a kick. I programmed this code, but when I run the program even when I move my Right Foot very fast, the speed does not change too much.
what is wrong?
Is there a different approache?
if (bandera == true)
{
X1 = skeleton.Joints[JointType.FootRight].Position.X;
Y1 = skeleton.Joints[JointType.FootRight].Position.Y;
Z1 = skeleton.Joints[JointType.FootRight].Position.Z;
}
if (bandera == false)
{
X2 = skeleton.Joints[JointType.FootRight].Position.X;
Y2 = skeleton.Joints[JointType.FootRight].Position.Y;
Z2 = skeleton.Joints[JointType.FootRight].Position.Z;
}
bandera = !bandera;
float d= (((X1 - X2) * (X1 - X2)) + ((Y1 - Y2) * (Y1 - Y2)) + ((Z1 - Z2 * (Z1 - Z2))));
double distance = System.Math.Sqrt(d);
double speed= 30 * distance;
Console.WriteLine(speed);
As you know: Speed= distance/time
And I understand there are 30 FPS per second, so time = 1/30
So speed equals distance divided by (1/30) is equal 30 * distance
Well ... because you're using the same points ... so when you're subtracting, it's all 0's ...
X1 = skeleton.Joints[JointType.FootRight].Position.X;
...
X2 = skeleton.Joints[JointType.FootRight].Position.X;
...
same point, so x1=x2, x1-x2=0, and everything goes pear shape from there...
As per your update:
I hope that is in a loop, otherwise, your flag (bandera) won't do much. I hope you also realize that the first time through the loop, some of your X and Y won't be initialized (because it'll only go through one of the cases).
now, d=t*s, so your distance calculation is completely correct.
If you chuck some debug output after initializing your variables, and calculations, what do you get ?
You messed up the distance formula. Take great care when placing parentesis. It should look like so
float d = (X1 - X2) * (X1 - X2) + (Y1 - Y2) * (Y1 - Y2) + (Z1 - Z2) * (Z1 - Z2);
Also there is no need to compare a bool value to true. You can also move out the distance calculation to its own method to make things clearer and avoid misstakes that take time to find. I suggest something like this:
double distance(Joint a, Joint b)
{
float d2 = (b.X - a.X) * (b.X - a.X) + (b.Y - a.Y) * (b.Y - a.Y) + (b.Z - a.Z) * (b.Z - a.Z);
return System.Math.Sqrt(d2)
}
...
if (bandera)
{
a = skeleton.Joints[JointType.FootRight];
}
else
{
b = skeleton.Joints[JointType.FootRight];
}
bandera = !bandera;
double speed = 30 * distance(a, b);
Console.WriteLine(speed);
Your speed calculation is very prone to fluctuation, so averaging over say 10 frames would probably also help.
The only mistake I see in your code is that you're missing parenthesis on the distance calculation: (Z1 - Z2) must go between parenthesis, or else the order of the operations is incorrect. Everything else should work fine. As vidstige stated, the speed will vary when the kick is in progress, so for your stated purpose I would recommend simply keeping the greatest value.
Saludos!!
Related
I have a line segment whose end points I know
Line1 (X1,Y1) (X2,Y2)
I have a second line
Line2 (X3,Y3) (X4,Y4)
I want to calculate new end points for line 1 such that the resulting line is parallel to Line2, and Line1's centre point remains at the same coordinates.
i.e. such that Line1 simply rotates so it is parallel to Line2
I know I can calculate each line's angle
var line1Angle = (Mathf.Atan2(x2 - x1, y2 - y1));
var line2Angle = (Mathf.Atan2(x4 - x3, y4 - y3));
I can also calculate the lengths
var len1 = Math.Sqrt((x2-x1)*(x2-x1)+ (y2-y1) * (y2-y1));
var len2 = Math.Sqrt((x4-x3)*(x4-x3)+ (y4-y3) * (y4-y3));
but everything I have tried seems to fail - either not rotating correctly, or rotating but with the incorrect length.
The closest code I have (below) rotates correctly, but the length of Line1 is not retained.
The code uses an 'offset' which was used by the code this version is based on as it simply drew a parallel line 'offset' pixels from the destination line - I have set it to an arbitrary value but I believe should be the distance of Line1's centre point from the closest point on Line2.
I'd love it if someone could supply a code version, rather than an explanation (or as well as!) as I've read and tried so many non-code solutions, and evidently my understanding / translation to code is flawed!
float len1 = (float)Math.Sqrt((x2-x1)*(x2-x1)+ (y2-y1) * (y2-y1));
float len2 = (float)Math.Sqrt((x4-x3)*(x4-x3)+ (y4-y3) * (y4-y3));
float offset = 3.0f; // This should be the dist from our center to the closest wall but I"m compromising for now!
float newX1 = x3 + offset * (y4 - y3) * (len1 / len2);
float newX2 = x4 + offset * (y4 - y3) * (len1 / len2);
float newY1 = y3 + offset * (x3 - x4) * (len1 / len2);
float newY2 = y4 + offset * (x3 - x4) * (len1 / len2);
Approach without angles: you know segment lengths, and can just form new segment ends with the same direction as line2 defines
dx1 = x2 - x1
dy1 = y2 - y1
dx2 = x4 - x3
dy2 = y4 - y3
len1 = hypot(dx1, dy1)
len2 = hypot(dx2, dy2)
midx = (x1 + x2) / 2
midy = (y1 + y2) / 2
coeff = 0.5 * len1 / len2
//now we make a vector with direction of line2
//and length of half of line1
newx1 = midx - dx2 * coeff
newy1 = midy - dy2 * coeff
newx2 = midx + dx2 * coeff
newy2 = midy + dy2 * coeff
I would highly recommend that you define actual types for your line segment and points. You can use Math.Net or System.Numerics.Vectors if you want something to start with.
Assuming your line segment have a StartPoint and EndPoint we can define a MidPoint and Direction extension methods. I'm going to use the Math.Net types for the example, but it is not difficult to make your own types.
static Vector2D Midpoint(this Line2D l) => (l.StartPoint + l.EndPoint) / 2;
static Vector2D Direction(this Line2D l) => (l.EndPoint - l.StartPoint ).Normalize() ;
We can also define a static method to create a new line from these methods/Properties:
static Line2D FromMidpointDirection(Vector2D midpoint, Vector2D direction, float length){
var halfDir = direction * length/ 2;
return new Line2D(midpoint - halfDir , midpint + halfDir );
Note that you might want to add comments or pick another name for Direction, since it is not obvious if this is normalized or not.
Then you can recreate your line:
var mid = sourceLine.Midpoint();
var dir = targetLine.Direction();
var newLine = FromMidpointDirection(mid, dir,sourceLine.Length);
Using higher level types like this tend to make your code more reusable and easier to read and understand.
I am trying to interpolate between 4 points using a Hermite spline. However my spline seems to always start on the second point and only interpolate to the 3rd point. I have tried this with several differnt calculations and keep getting the same result.
Can anyone give me insight on this? Here is my code.
public ControlPoint Get(float t)
{
//speed multiplyer
//t = t * 10;
return new ControlPoint(
new Vector3(Hermite(points[0].pos.x, points[1].pos.x, points[2].pos.x, points[3].pos.x, t)
, Hermite(points[0].pos.y, points[1].pos.y, points[2].pos.y, points[3].pos.y, t)
, Hermite(points[0].pos.z, points[1].pos.z, points[2].pos.z, points[3].pos.z, t)
),
new Quaternion(Hermite(points[0].rot.x, points[1].rot.x, points[2].rot.x, points[3].rot.x, t)
, Hermite(points[0].rot.y, points[1].rot.y, points[2].rot.y, points[3].rot.y, t)
, Hermite(points[0].rot.z, points[1].rot.z, points[2].rot.z, points[3].rot.z, t)
, Hermite(points[0].rot.w, points[1].rot.w, points[2].rot.w, points[3].rot.w, t)
)
);
}
float Hermite(
float y0, float y1,
float y2, float y3,
float mu,
float tension = 0,
float bias = 0)
{
float m0, m1, mu2, mu3;
float a0, a1, a2, a3;
mu2 = mu * mu;
mu3 = mu2 * mu;
m0 = (y1 - y0) * (1 + bias) * (1 - tension) / 2;
m0 += (y2 - y1) * (1 - bias) * (1 - tension) / 2;
m1 = (y2 - y1) * (1 + bias) * (1 - tension) / 2;
m1 += (y3 - y2) * (1 - bias) * (1 - tension) / 2;
a0 = 2 * mu3 - 3 * mu2 + 1;
a1 = mu3 - 2 * mu2 + mu;
a2 = mu3 - mu2;
a3 = -2 * mu3 + 3 * mu2;
return (a0 * y1 + a1 * m0 + a2 * m1 + a3 * y2);
}
I'm not an expert Hermite Splines by any stretch of the imagination, but from what I've seen is that the expected behavior would be to interpolate between the second and third point. It looks to me like you just hardcoded in each coordinate to your Get function, so it makes sense that you only get a single interpolation when a Hermite Spline is a function. Think of the second and third points as the two points you want to interpolate between, and the first and fourth points just help to create a better curve.
Since it appears you only have four points total, to interpolate between the first and second points, and third and fourth points, try repeating your first coordinates and last coordinates.
//Interpolate between 1st and 2nd points' x coord
Hermite(points[0].pos.x, points[0].pos.x, points[1].pos.x, points[2].pos.x);
//Interpolate between 3rd and 4th points' x coord
Hermite(points[2].pos.x, points[3].pos.x, points[4].pos.x, points[4].pos.x);
To interpolate between the first and second points points[0] is repeated twice because there is no points[-1]. For interpolation between the third and fourth points, points[4] is repeated because there is no points[5].
To reiterate, do not hardcode in coordinates unless you only want a single interpolation. You'll have to modify your Get function and call it a few times to adjust for the behavior you want. Check out how Snea implemented a Hermite Spline in his DrawGraph function, it helped me to better understand Hermite Spline behavior: Cubic Hermite Spline behaving strangely
I have a problem where I'm required to find the maximum number of points that are less than or equal to a given distance D to a line drawn in a two-dimensional Euclidean plane. To solve this I wrote the algorithms that would compute a possible maximum if the line was orthogonal to either the x-axis or the y-axis. My problem is when only a diagonal line would yield the maximum number of points.
Given the constraints that both x and y have a minimum value of -1000000 and maximum of 1000000. I wrote the following algorithm to try and find out the maximum. I don't seem to be getting the right answer. Could someone please guide me on where I am going wrong. I've tried drawing a regression line as well but that used vertical distance which did not work for my purposes. Maybe I'm going all wrong and this problem can be solved as an optimization problem. Anyways' any help with a descent explanation is much appreciated.
// diagonal sweep
for (int degree = 1; degree < 180; degree++) if (degree % 90 != 0)
{
int k = 1, degrees = degree;
double x1 = -1000000, x2 = 1000000;
if (degree > 90 && degree < 180)
{
degrees = 180 - degrees;
k = -1;
}
//slope
double m1 = Math.Tan(Math.PI * degrees * k / 180.0);
//Point A
Point A = new Point(x1, m1 * x1);
//Point B
Point B = new Point(x2, m1 * x2);
for (int i = 0; i < x.Length; i++)
{
//Point P = household that needs power
Point P = new Point(x[i], y[i]);
double normalLength = Math.Sqrt((B.X - A.X) * (B.X - A.X) + (B.Y - A.Y) * (B.Y - A.Y));
double segmentLength = 1d * Math.Abs((P.X - A.X) * (B.Y - A.Y) - (P.Y - A.Y) * (B.X - A.X)) / normalLength;
if (segmentLength <= D)
tempCnt++;
}
maxConnections = Math.Max(maxConnections, tempCnt);
tempCnt = 0;
}
return maxConnections;
If you want to define this problem as an optimization problem, you should do it as follows, but it doesn't seem to me this optimization problem is solveable efficiently as is.
maximize: x_1 + x_2 + ... + x_n + 0*a + 0*b + 0*c
s.t.
x_i * d(p_i, line(a,b,c))/ MAX_DISTANCE <= 1
x_i is in {0,1}
Explanation:
x_i are inclusion variables - can get a value of 0 / 1 , and it indicates if the point p_i is in the required distance from the line.
a,b,c are the parameters for the line: ax + by + c = 0
The idea is to maximize the sum of included points, such that each included point is in the desired range. This is represented by the constraint, if x_i=0 - there is no restriction on the point p_i, as the constraint is always satisfied. Otherwise, x_i=1, and you need the distance from the line (let it be d) satisfy 1* d/MAX_DISTANCE <= 1 - which is exactly what you want.
Though I don't think there is an optimal efficient solution to this optimization problem, you might want to try some heuristical solutions for this optiization - such as Genetic Algorithms or Hill Climbing
As a side note, my gut says this problem is NP-Complete, though I have no proof for it yet - and will update this part of the answer if I (or someone else) can come up with a reduction/polynomial solution.
I'm trying to implement a method to check if a circle and a line intersect. I took most of this code (fixed based on the answer), and also modified the code a bit to use Point's instead of Vector2f's`.
This is currently what I have:
private bool CircleLineIntersect(int x, int y, int radius, Point linePoint1, Point linePoint2) {
Point p1 = new Point(linePoint1.X,linePoint1.Y);
Point p2 = new Point(linePoint2.X,linePoint2.Y);
p1.X -= x;
p1.Y -= y;
p2.X -= x;
p2.Y -= y;
float dx = p2.X - p1.X;
float dy = p2.Y - p1.Y;
float dr = (float)Math.Sqrt((double)(dx * dx) + (double)(dy * dy));
float D = (p1.X * p2.Y) - (p2.X * p1.Y);
float di = (radius * radius) * (dr * dr) - (D * D);
if (di < 0) return false;
else return true;
}
It looks consistent with this algorithm, so I'm not sure what the problem is.
If anyone could provide guidance it would be much appreciated.
EDIT:
It doesn't seem to be calculating correctly. For example with input x=1272, y=1809, radius=80, linePoint1={X=1272,Y=2332}, linePoint2={X=1272,Y=2544} there shouldn't be an intersection (y+radius is less than both y values of the line segment), but the function is returning true.
Error exists in your test case. Not only does the it intersect, but your line goes through the center of the circle. The line is a vertical line (X =1272). Your circle is centred about (1272, 1809). ERGO it goes through the centre.
Perhaps you have a misunderstanding between the terms line and line-segment, within mathematics.
I'm drawing a custom diagram of business objects using .NET GDI+. Among other things, the diagram consists of several lines that are connecting the objects.
In a particular scenario, I need to shorten a line by a specific number of pixels, let's say 10 pixels, i.e. find the point on the line that lies 10 pixels before the end point of the line.
Imagine a circle with radius r = 10 pixels, and a line with start point (x1, y1) and end point (x2, y2). The circle is centered at the end point of the line, as in the following illustration.
How do I calculate the point marked with a red circle, i.e. the intersection between circle and line? This would give me the new end point of the line, shortening it by 10 pixels.
Solution
Thank you for your answers from which I was able to put together the following procedure. I named it LengthenLine, since I find it more natural to pass a negative number of pixels if I want the line shortened.
Specifically, I was trying to put together a function that could draw a line with rounded corners, which can be found here.
public void LengthenLine(PointF startPoint, ref PointF endPoint, float pixelCount)
{
if (startPoint.Equals(endPoint))
return; // not a line
double dx = endPoint.X - startPoint.X;
double dy = endPoint.Y - startPoint.Y;
if (dx == 0)
{
// vertical line:
if (endPoint.Y < startPoint.Y)
endPoint.Y -= pixelCount;
else
endPoint.Y += pixelCount;
}
else if (dy == 0)
{
// horizontal line:
if (endPoint.X < startPoint.X)
endPoint.X -= pixelCount;
else
endPoint.X += pixelCount;
}
else
{
// non-horizontal, non-vertical line:
double length = Math.Sqrt(dx * dx + dy * dy);
double scale = (length + pixelCount) / length;
dx *= scale;
dy *= scale;
endPoint.X = startPoint.X + Convert.ToSingle(dx);
endPoint.Y = startPoint.Y + Convert.ToSingle(dy);
}
}
Find the direction vector, i.e. let the position vectors be (using floats) B = (x2, y2) and A = (x1, y1), then AB = B - A. Normalize that vector by dividing by its length ( Math.Sqrt(xx + yy) ). Then multiply the direction vector AB by the original length minus the circle's radius, and add back to the lines starting position:
double dx = x2 - x1;
double dy = y2 - y1;
double length = Math.Sqrt(dx * dx + dy * dy);
if (length > 0)
{
dx /= length;
dy /= length;
}
dx *= length - radius;
dy *= length - radius;
int x3 = (int)(x1 + dx);
int y3 = (int)(y1 + dy);
Edit: Fixed the code, aaand fixed the initial explanation (thought you wanted the line to go out from the circle's center to its perimeter :P)
I'm not sure why you even had to introduce the circle. For a line stretching from (x2,y2) to (x1,y1), you can calculate any point on that line as:
(x2+p*(x1-x2),y2+p*(y1-y2))
where p is the percentage along the line you wish to go.
To calculate the percentage, you just need:
p = r/L
So in your case, (x3,y3) can be calculated as:
(x2+(10/L)*(x1-x2),y2+(10/L)*(y1-y2))
For example, if you have the two points (x2=1,y2=5) and (x1=-6,y1=22), they have a length of sqrt(72 + 172 or 18.38477631 and 10 divided by that is 0.543928293. Putting all those figures into the equation above:
(x2 + (10/l) * (x1-x2) , y2 + (10/l) * (y1-y2))
= (1 + 0.543928293 * (-6- 1) , 5 + 0.543928293 * (22- 5))
= (1 + 0.543928293 * -7 , 5 + 0.543928293 * 17 )
= (x3=-2.807498053,y3=14.24678098)
The distance between (x3,y3) and (x1,y1) is sqrt(3.1925019472 + 7.7532190152) or 8.384776311, a difference of 10 to within one part in a thousand million, and that's only because of rounding errors on my calculator.
You can use similar triangles. For the main triangle, d is the hypotenuses and the extension of r is the vertical line that meets the right angle. Inside the circle you will have a smaller triangle with a hypotenuses of length r.
r/d = (x2-a0)/(x2-x1) = (y2-b0)/(y2-y1)
a0 = x2 + (x2-x1)r/d
b0 = y2 + (y2-y1)r/d