i just get to the point and describe my problem .
Given a square not parallel to the axis !
i have (x1,y1) and (x2,y2) and the distance beetween them dx(width/height of the square)
i need to find the point (x,y) describe in the photo
(cant upload photo)
link to the image : the problem photo
first i tried the equation (x-x1)^2 + (y-y1)^2 = dx^2
(x-x2(^2 + (y-y2)^2 = 2 dx^2
but i cant manage to solve this equation when i try to code it ,
anyone have any idea's how to solve the problem in code or another equation or solution to find the point ?.
*i using c# 4,0
Very simple.
var dx = x2 - x1;
var dy = y2 - y1;
var rotatedDx = dy;
var rotatedDy = -dx;
x = x1 + rotatedDx;
y = y1 + rotatedDy;
Basically, you compute vector P1 -> P2 and rotate it by 90 degrees.
You can solve it using complex numbers by representing the points on an Argand diagram. (I think)
Since its a square, the sides are equal and 90degrees apart you can do this. (Refer to dropbox picture)
https://www.dropbox.com/s/ymimimgkuzhkcub/IMAG3818.jpg?dl=0
A is point (x1, y1) with value x1 + (y1)i
B is x2 + (y2)i
P and Q are the locations of the 2 possible places (x, y) can be and they are x + yi. Solve the 2 equation in the picture for values of x and y.
Related
I am trying to draw an arc between two points that represents a projectile's path. The angle that the projectile leaves point A at is known, and the X/Y coordinates of both points are known.
I'm trying to figure out the math behind this, and how to draw it up in c#.
Here is my failed attempt, based on some path examples I found
var g = new StreamGeometry();
var xDistance = Math.Abs(pointA.X - pointB.X);
var yDistance = Math.Abs(pointA.Y - pointB.Y);
var angle = 60;
var radiusX = xDistance / angle;
var radiusY = yDistance / angle;
using (var gc = g.Open())
{
gc.BeginFigure(
startPoint: pointA,
isFilled: false,
isClosed: false);
gc.ArcTo(
point: pointB,
size: new Size(radiusX, radiusY),
rotationAngle: 0d,
isLargeArc: false,
sweepDirection: SweepDirection.Clockwise,
isStroked: true,
isSmoothJoin: false);
}
Any help would be greatly appreciated!
Edit #2 (added clarity): For this problem assume that physics play no role (no gravity, velocity, or any outside forces). The projectile is guaranteed to land at point B and move along a parabolic path. The vertex will be halfway between point A and point B on the horizontal axis. The angle that it launches at is the angle up from the ground (horizontal).
So Point A (Ax, Ay) is known.
Point B (Bx, By) is known.
The angle of departure is known.
The X half of the vertex is known (Vx = Abs(Ax - Bx)).
Does this really boil down to needing to figure out the Y coordinate of the vertex?
Following on from the comments, we need a quadratic Bezier curve. This is defined by 3 points, the start, end, and a control point:
It is defined by the following equation:
We therefore need to find P1 using the given conditions (note that the gravity strength is determined implicitly). For a 2D coordinate we need two constraints / boundary conditions. They are given by:
The tangent vector at P0:
We need to match the angle to the horizontal:
The apex of the curve must be directly below the control point P1:
Therefore the vertical coordinate is given by:
[Please let me know if you would like some example code for the above]
Now for how to add a quadratic Bezier; thankfully, once you have done the above, it is not too difficult
The following method creates the parabolic geometry for the simple symmetric case. The angle is measured in degrees counterclockwise from the horizontal.
public Geometry CreateParabola(double x1, double x2, double y, double angle)
{
var startPoint = new Point(x1, y);
var endPoint = new Point(x2, y);
var controlPoint = new Point(
0.5 * (x1 + x2),
y - 0.5 * (x2 - x1) * Math.Tan(angle * Math.PI / 180));
var geometry = new StreamGeometry();
using (var context = geometry.Open())
{
context.BeginFigure(startPoint, false, false);
context.QuadraticBezierTo(controlPoint, endPoint, true, false);
}
return geometry;
}
A body movement subject only to the force of gravity (air resistance is ignored) can be evaluated with the following equations:
DistanceX(t) = dx0 + Vx0·t
DistanceY(t) = dy0 + Vy0·t - g/2·t^2
Where
g : gravity acceleration (9.8 m/s^2)
dx0 : initial position in the X axis
dy0 : initial position in the Y axis
Vy0 : initial X velocity component (muzzle speed)
Vy0 : initial Y velocity component (muzzle speed)
Well that doesn't seem very helpful, but lets investigate further. Your cannon has a muzzle speed V we can consider constant, so Vx0 and Vy0 can be written as:
Vx0 = V·cos(X)
Vy0 = V·sin(X)
Where X is the angle at which you are shooting. Ok, that seems interesting, we finally have an input that is useful to whoever is shooting the cannon: X. Lets go back to our equations and rewrite them:
DistanceX(t) = dx0 + V·cos(X)·t
DistanceY(t) = dy0 + V·sin(X)·t - g/2·t^2
And now, lets think through what we are trying to do. We want to figure out a way to hit a specific point P. Lets give it coordinates: (A, B). And in order to do that, the projectile has to reach that point in both projections at the same time. We'll call that time T. Ok, lets rewrite our equations again:
A = dx0 + V·cos(X)·T
B = dy0 + V·sin(X)·T - g/2·T^2
Lets get ourselves rid of some unnecessary constants here; if our cannon is located at (0, 0) our equations are now:
A = V·cos(X)·T [1]
B = V·sin(X)·T - g/2·T^2 [2]
From [1] we know that: T = A/(V·cos(X)), so we use that in [2]:
B = V·sin(X)·A/(V·cos(X)) - g/2·A^2/(V^2·cos^2(X))
Or
B = A·tan(X) - g/2·A^2/(V^2*cos^2(X))
And now some trigonometry will tell you that 1/cos^2 = 1 + tan^2 so:
B = A·tan(X) - g/2·A^2/V^2·(1+tan^2(X)) [3]
And now you have quadratic equation in tan(X) you can solve.
DISCLAIMER: typing math is kind of hard, I might have an error in there somewhere, but you should get the idea.
UPDATE The previous approach would allow you to solve the angle X that hits a target P given a muzzle speed V. Based on your comments, the angle X is given, so what you need to figure out is the muzzle speed that will make the projectile hit the target with the specified cannon angle. If it makes you more comfortable, don't think of V as muzzle speed, think of it as a form factor of the parabola you are trying to find.
Solve Vin [3]:
B = A·tan(X) - g/2·A^2/V^2·(1+tan^2(X))
This is a trivial quadratic equation, simply isolate V and take the square root. Obviously the negative root has no physical meaning but it will also do, you can take any of the two solutions. If there is no real number solution for V, it would mean that there is simply no possible shot (or parabola) that reaches P(angle X is too big; imagine you shoot straight up, you'll hit yourself, nothing else).
Now simply eliminate t in the parametrized equations:
x = V·cos(X)·t [4]
y = V·sin(X)·t - g/2·t^2 [5]
From [4] you have t = x/(V·cos(X)). Substitute in [5]:
y = tan(X)·x - g·x^2 /(2·V^2*cos^2(X))
And there is your parabola equation. Draw it and see your shot hit the mark.
I've given it a physical interpretation because I find it easier to follow, but you could change all the names I've written here to purely mathematical terms, it doesn't really matter, at the end of the day its all maths and the parabola is the same, any which way you want to think about it.
I am attempting to calculate the angle required to fire a projectile in order to hit a specific coordinate.
My projectile is located a random coordinate and my target coordinate at a static coordinate.
I ended up running across the following equation on Wikipedia for calculating the angle required to hit a coordinate at (x,y) from (0,0):
I have made some attempts to understand this and other formula and attempted the following implementation (I am using c# and XNA).
double y = source.Y - target.Y;
double x = Vector2.Distance(source, target);
double v = 1440; //velocity
double g = 25; //gravity
double sqrt = (v*v*v*v) - (g*(g*(x*x) + 2*y*(v*v)));
sqrt = Math.Sqrt(sqrt);
double angleInRadians = Math.Atan(((v*v) + sqrt)/(g*x));
I have also attempted the following, which resulted in an identical angle where the values of v and g remain the same.
double targetX = target.X - source.X;
double targetY = -(target.Y - source.Y);
double r1 = Math.Sqrt((v*v*v*v) - g*(g*(target.X*target.X) + ((2*target.Y)*(v*v))));
double a1 = ((v*v) + r1)/(g*target.X);
angleInRadians = -Math.Atan(a1);
if (targetX < 0)
{
angleInRadians -= 180/180*Math.PI;
}
My conjecture is that even in my (assumed) attempt to zero out the source coordinate, that I am still not performing the calculation correctly for coordinates with a non (0,0) source and different elevations.
Below is an image that depicts my coordinate system. It is the default for XNA.
Thanks to the help in the comments the solution to find this angle ended up requiring that the positions be translated to a (0,0) based system. For anyone looking for the same scenario the final working solution was:
double x = -(source.x - target.x);
double y = (source.y - target.y);
double v = 1440; //m/s
double g = 25; //m/s
double sqrt = (v*v*v*v) - (g*(g*(x*x) + 2*y*(v*v)));
sqrt = Math.Sqrt(sqrt);
angleInRadians = Math.Atan(((v*v) + sqrt)/(g*x));
Then to convert the radians into a vector that works with XNA, perform the following conversion:
Vector2 angleVector = new Vector2(-(float)Math.Cos(angleInRadians), (float)Math.Sin(angleInRadians));
I think the real problem lies in the use of arctan. Because the range is limited to -pi/2..pi/2 results are only in the right half plane.
Use arctan2 to get the proper coordinates:
angleInRadians = Math.Atan2(((v*v) + tmp), (g*x));
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to calculate the angle between two points relative to the horizontal axis?
I've been looking for this for ages and it's just really annoying me so I've decided to just ask...
Provided I have two points (namely x1, y1, and x2, y2), I would like to calculate the angle between these two points, presuming that when y1 == y2 and x1 > x2 the angle is 180 degrees...
I have the below code that I have been working with (using knowledge from high school) and I just can't seem to produce the desired result.
float xDiff = x1 - x2;
float yDiff = y1 - y2;
return (float)Math.Atan2(yDiff, xDiff) * (float)(180 / Math.PI);
Thanks in advance, I'm getting so frustrated...
From what I've gathered, you want the following to hold:
Horizontal line: P1 -------- P2 => 0°
Horizontal line: P2 -------- P1 => 180°
Rotating the horizontal line clockwise
You said, you want the angle to increase in clockwise direction.
Rotating this line P1 -------- P2 such that P1 is above P2, the angle must thus be 90°.
If, however, we rotated in the opposite direction, P1 would be below P2 and the angle is -90° or 270°.
Working with atan2
Basis: Considering P1 to be the origin and measuring the angle of P2 relative to the origin, then P1 -------- P2 will correctly yield 0.
float xDiff = x2 - x1;
float yDiff = y2 - y1;
return Math.Atan2(yDiff, xDiff) * 180.0 / Math.PI;
However, atan2 let's the angle increase in CCW direction.
Rotating in CCW direction around the origin, y goes through the following values:
y = 0
y > 0
y = 0
y < 0
y = 0
This means, that we can simply invert the sign of y to flip the direction. But because C#'s coordinates increase from top to bottom, the sign is already reversed when computing yDiff.
I need some c# code for the following:
I have two points (2D). The points are on a circle with radius r. I know the tangent angle in each of the points. I need to get hold of the circle mid point.
//Thomas
OK, I think I was a bit unclear. See image below. The point P1 is at the end of a line, the line has the angle At1. The point P2 is at the beginning of a line with the angle At2. I know the coordinates for P1 and P2. I also know the angles At1 and At2. A radius is formed between P1 and P2 and I need to know the center point Pc for the (invisible) circle the which is formed with P1, P2, At1 and At2. The points P1 and P2 can be anywhere in the coordiante system.
I know it's not c#, however I was hoping to come across someone who's solved this.
See image
If the points are not known to be most-far from one another on the circle, then there is an infinite amount of circles that they can be on.
Otherwise, it's simple:
Point pt1 = ...
Point pt2 = ...
Point mid = new Point((pt1.X + pt2.X) / 2, (pt1.Y + pt2.Y) / 2);
First, check if the tangent angles are parallel. If they are, then all you need to do is find the midpoint between them (as they both lay along the circle's diameter) as per Yorye Nathan's solution.
If they're not parallel, then you can draw two lines perpendicular to the tangent angles starting from your known P1 and P2. If you solve the intersection of these two lines, then that intersection will be Pc.
I don't have the time right now to write up the full C# math and test it, but some pseudocode for you might be:
public Point CalculateCircleCentre(Point p1, Degrees tangent1, Point p2, Degrees tangent2)
{
if (AreAnglesParallel(tangent1, tangent2))
{
return Midpoint(p1, p2);
}
else
{
var line1 = new Line(p1, tangent1 + 90);
var line2 = new Line(p2, tangent2 + 90);
var intersectionPoint = FindIntersection(line1, line2);
return intersectionPoint;
}
}
Assuming you have 2 points on a circle with coordinates (x1, y1), (x2, y2) and point (x3, y3) is the center of a circle with radius r all you need to do is to find x3 and y3. Solve this system:
(x3-x1)^2+(y3-y1)^2=r^2
(x3-x2)^2+(y3-y2)^2=r^2
expands to
x3*x3-2*x3*x1+x1*x1 + y3*y3-2*y3*y1+y1*y1 = r*r
x3*x3-2*x3*x2+x2*x2 + y3*y3-2*y3*y2+y2*y2 = r*r
2*x3*(x2-x1) + 2*y3*(y2-y1) + x1*x1 + x2*x2 + y1*y1 + y2*y2 = 0
You now can substitute x3 with this long expression and find y3
x3 = (2*y3*(y1-y2) - (x1*x1 + x2*x2 + y1*y1 + y2*y2)) / (2*(x2-x1))
After that you will know everything to find x3.
Lets Say I have a 3d Cartesian grid. Lets also assume that there are one or more log spirals emanating from the origin on the horizontal plane.
If I then have a point in the grid I want to test if that point is in one of the spirals. I acutally want to test if it within a certain range of the spirals but determining if it is on the point is a good start.
So I guess the question has a couple parts.
How to generate the arms from parameters (direction, tightness)
How to tell if a point in the grid is in one of the spiral arms
Any ideas? I have been googling all day and don't feel I am any closer to a solution than when I started.
Here is a bit more information that might help:
I don't actually need to render the spirals. I want to set the pitch and rotation and then pass a point to a method that can tell me if the point I passed is within the spiral (within a given range of any point on the spiral). Based on the value returned (true or false) my program will make a decision on whether or not something exists at the point in space.
How to parametrically define the log spirals (pitch and rotation and ??)
Test if a point (x, y, z) is withing a given range of any point on the spiral.
Note: Both of the above would be just on the horizontal plane
These are two functions defining an anti-clockwise spiral:
PolarPlot[{
Exp[(t + 10)/100],
Exp[t/100]},
{t, 0, 100 Pi}]
Output:
These are two functions defining a clockwise spiral:
PolarPlot[{
- Exp[(t + 10)/100],
- Exp[t/100]},
{t, 0, 100 Pi}]
Output:
Cartesian coordinates
The conversion Cartesian <-> Polar is
(1) Ro = Sqrt[x^2+y^2]
t = ArcTan[y/x]
(2) x = Ro Cos[t]
y = Ro Sin[t]
So, If you have a point in Cartesian Coords (x,y) you transform it to your equivalent polar coordinates using (1). Then you use the forula for the spiral function (any of the four mentinoned above the plots, or similar ones) putting in there the value for t, and obtaining Ro. The last step is to compare this Ro with the one we got from the coordinates converion. If they are equal, the point is on the spiral.
Edit Answering your comment
For a Log spiral is almost the same, but with multiple spirals you need to take care of the logs not going to negative values. That's why I used exponentials ...
Example:
PolarPlot[{
Log[t],
If[t > 3, Log[ t - 2], 0],
If[t > 5, Log[ t - 4], 0]
}, {t, 1, 10}]
Output:
Not sure this is what you want, but you can reverse the log function (or "any" other for that matter).
Say you have ln A = B, to get A from B you do e^B = A.
So you get your point and pass it as B, you'll get A. Then you just need to check if that A (with a certain +- range) is in the values you first passed on to ln to generate the spiral.
I think this might work...
Unfortunately, you will need to know some mathematics notation anyway - this is a good read about the logarithmic sprial.
http://en.wikipedia.org/wiki/Logarithmic_spiral
we will only need the top 4 equations.
For your question 1
- to control the tightness, you tune the parameter 'a' as in the wiki page.
- to control the direction, you offset theta by a certain amount.
For your question 2
In floating point arithmetic, you will never get absolute precision, which mean there will be no point falling exactly on the sprial. On the screen, however, you will know which pixel get rendered, and you can test whether you are hitting a point that is rendered.
To render a curve, you usually render it as a sequence of line segments, short enough so that overall it looks like a curve. If you want to know whether a point lies within certain distance from the spiral, you can render the curve (on a off-screen buffer if you wish) by having thicker lines.
here a C++ code drawing any spiral passing where the mouse here
(sorry for my English)
int cx = pWin->vue.right / 2;
int cy = pWin->vue.bottom / 2;
double theta_mouse = atan2((double)(pWin->y_mouse - cy),(double)(pWin->x_mouse - cx));
double square_d_mouse = (double)(pWin->y_mouse - cy)*(double)(pWin->y_mouse - cy)+
(double)(pWin->x_mouse - cx)*(double)(pWin->x_mouse - cx);
double d_mouse = sqrt(square_d_mouse);
double theta_t = log( d_mouse / 3.0 ) / log( 1.19 );
int x = cx + (3 * cos(theta_mouse));
int y = cy + (3 * sin(theta_mouse));
MoveToEx(hdc,x,y,NULL);
for(double theta=0.0;theta < PI2*5.0;theta+=0.1)
{
double d = pow( 1.19 , theta ) * 3.0;
x = cx + (d * cos(theta-theta_t+theta_mouse));
y = cy + (d * sin(theta-theta_t+theta_mouse));
LineTo(hdc,x,y);
}
Ok now the parameter of spiral is 1.19 (slope) and 3.0 (radius at center)
Just compare the points where theta is a mutiple of 2 PI = PI2 = 6,283185307179586476925286766559
if any points is near of a non rotated spiral like
x = cx + (d * cos(theta));
y = cy + (d * sin(theta));
then your mouse is ON the spiral... I searched this tonight and i googled your past question