I have got a square with the bounds of (0,0) to (800,600) In this raster I have to draw a line, given to me are the Angle and Radius of a line, starting from point (0,0).
These bounds are based on a screen with a resolution of 800x600
I know how to calculate the (X,Y) points from this point,
X = Radius * Cos(Angle)
Y = Radius * Sin(Angle)
But from this point I don't know how to continue. In the images below I've defined my use cases. (X3,Y3) are the points I know how to calculate as told above. But how do I find (X1, Y1) and (X2, Y2)?
The Angle and Radius can be all kinds of values, see for example the values below. When both X3 and Y3 are a negative value I know the (X1,Y1) and (X2, Y2) will not fall in the raster.
I think this isn't to dificult to calculate, but I just don't know how to do this.
The line from the origin can be expressed by the equation
y = mx
where the slope m = y3/x3. You will need a line perpendicular to your first line, which means it has a slope of
m' = -1/m
Therefore it can be expressed by the equation
y = m'(x-x3) + y3
The point (X1,Y1) will have X1 = 0 and Y1 can be calculated via Y1 = m'x + y3. The point (X2,Y2) will have Y2 = 0 and X2 = (y - Y2)/m' + x3.
Related
I have a piece of code that returns the angle between two vectors in the range of [0,360]. For this I used this question: Direct way of computing clockwise angle between 2 vectors. Now I need to create a function that takes a vector and an angle as input and returns a vector, that has the specified angle with the inputvector. The length of this vector doesn't matter. For this, I need to know how to reverse the effect of Atan2. The rest is pretty simple math.
internal virtual double AngleWith(Vector2 direction, Vector2 location)
{
Vector2 normDir = Vector2.Normalize(direction);
Vector2 normLoc = Vector2.Normalize(location);
double dot = (normDir.X * normLoc.X) + (normDir.Y * normLoc.Y);
double det = (normDir.X * normLoc.Y) - (normDir.Y * normLoc.X);
return Math.Atan2(-det, -dot) * (180 / Math.PI) + 180;
}
Any help is appreciated.
I don't know what you need this for, but arguably there is merit in transforming your vectors from the x,y-coordinate system to the polar coordinate system, in which points in a plane are given by their distance from the origin and the angle to a reference vector (for instance the x-axis in the explanation below), or
To convert from (x, y) to (r, t) with r being the distance between (x,y) and (0,0) and t being the angle in radians between the x-axis and the line connecting (0, 0) and (x, y), you use this:
(r, t) = (sqrt(x^x+y^y), atan(y/x))
The result can be stored in Vector2, just like with x and y. You just have to remember that the values inside don't signify x and y.
If you want the difference in angle, you can just subtract t2 and t1 of your polar coordinates (in radians, still need to convert to degrees).
If you need to add a certain angle in degrees, just add or subtract it to the t value of your polar coordinate.
To convert back to x and y, use
(x, y) = (r cos(t), r sin(t))
The typical way to do this is with a rotation matrix.
RotatedX = x * sin ϴ - y * sin ϴ
RotatedY = x * sin ϴ + y * cos ϴ
Or use System.Numerics.Matrix3x2.CreateRotation(angle) and use it to transform your vector. Note that 'Clockwise' may depend on what coordinate conventions are used. So you might need to adjust the formula depending on your convention.
The problem I want to solve is:
Calculate the intersection of the ball and the circle with the following information.
Known information about the circle:
1. The coordinates of the center A are known, and the center A is on the spherical surface.
2. The radius ra of the circle A is known.
3. Know the coordinates of a point B on the circle
Known information about the ball:
1. The coordinates of the spherical center B of the known ball.
2. The radius of the known ball rb.
Picture is as follows
Icon
With the above information, I hope to calculate the coordinates of the intersection point.
Then put the algorithm into C# so that the associated points on the plane can be placed on the sphere and the distance between these points does not change.
If the above method works, I can place many points equidistant from A on the sphere, and after placement, the distance between these points and A is unchanged.
I tried before:
1. Solve the problem with simultaneous equations, but unfortunately the final result is not available.
2. Try to get the result by the intersection of two circles, but the circle and the circle are both in a plane relationship, only the coordinates of x, y can be obtained, and the coordinates of z cannot be obtained.
I successfully put some points on the sphere through the following code, but the distance between the points and the points has changed, and the more the number of points, the more obvious this change, I don't want their distance to change, so I came up with it. Determine the position of these points by intersecting the circle with the ball。
The parameter (List atoms ) stores some points on the plane, and (double r) is the radius of the ball. By this method, the point on the plane will be "sticked" to the sphere.
/// <summary>
/// Stick the atom to the sphere
/// </summary>
private void BendAtom(List <Atom> atoms,double r)
{
double L = 2d * Math.PI * r;
double w = L;// * 2d;
double h = L / 2d;
for (int i = 0; i < atoms.Count; i++)
{
atoms[i].Point.x = (float)((360 / w) * atoms[i].Point.x - 180);
atoms[i].Point.y = (float)((180 / h) * atoms[i].Point.y - 90);
}
for (int i = 0; i < atoms.Count; i++)
{
double lat = atoms[i].Point.x;
double lng = atoms[i].Point.y;
double phi = ((90d - lat) * Math.PI) / 180d;
double theta = ((180 - lng) * Math.PI) / 180d;
double x = r * Math.Sin(phi) * Math.Cos(theta);
double y = r * Math.Cos(phi);
double z = r * Math.Sin(phi) * Math.Sin(theta);
atoms[i].Point.x = (float)x;
atoms[i].Point.y = (float)y;
atoms[i].Point.z = (float)z;
}
}
I hope that after the point is "posted" on the ball, the distance of the points does not change, but as a result, they change, and the more the number of points, the greater the change.
My math level is limited. If you have a better way to solve this problem, thank you very much and thank you for your help.
The result of the above code
It's been 10 years since I did any math like this... I am programming a game in 2D and moving a player around. As I move the player around I am trying to calculate the point on a circle 200 pixels away from the player position given a positive OR negative angle(degree) between -360 to 360. The screen is 1280x720 with 0,0 being the center point of the screen. The player moves around this entire Cartesian coordinate system. The point I am trying trying to find can be off screen.
I tried the formulas on article Find the point with radius and angle but I don't believe I am understanding what "Angle" is because I am getting weird results when I pass Angle as -360 to 360 into a Cos(angle) or Sin(angle).
So for example I have...
1280x720 on a Cartesian plane
Center Point (the position of player):
let x = a number between minimum -640 to maximum 640
let y = a number between minimum -360 to maximum 360
Radius of Circle around the player: let r always = 200
Angle: let a = a number given between -360 to 360 (allow negative to point downward or positive to point upward so -10 and 350 would give same answer)
What is the formula to return X on the circle?
What is the formula to return Y on the circle?
The simple equations from your link give the X and Y coordinates of the point on the circle relative to the center of the circle.
X = r * cosine(angle)
Y = r * sine(angle)
This tells you how far the point is offset from the center of the circle. Since you have the coordinates of the center (Cx, Cy), simply add the calculated offset.
The coordinates of the point on the circle are:
X = Cx + (r * cosine(angle))
Y = Cy + (r * sine(angle))
You should post the code you are using. That would help identify the problem exactly.
However, since you mentioned measuring your angle in terms of -360 to 360, you are probably using the incorrect units for your math library. Most implementations of trigonometry functions use radians for their input. And if you use degrees instead...your answers will be weirdly wrong.
x_oncircle = x_origin + 200 * cos (degrees * pi / 180)
y_oncircle = y_origin + 200 * sin (degrees * pi / 180)
Note that you might also run into circumstance where the quadrant is not what you'd expect. This can fixed by carefully selecting where angle zero is, or by manually checking the quadrant you expect and applying your own signs to the result values.
I highly suggest using matrices for this type of manipulations. It is the most generic approach, see example below:
// The center point of rotation
var centerPoint = new Point(0, 0);
// Factory method creating the matrix
var matrix = new RotateTransform(angleInDegrees, centerPoint.X, centerPoint.Y).Value;
// The point to rotate
var point = new Point(100, 0);
// Applying the transform that results in a rotated point
Point rotated = Point.Multiply(point, matrix);
Side note, the convention is to measure the angle counter clockwise starting form (positive) X-axis
I am getting weird results when I pass Angle as -360 to 360 into a Cos(angle) or Sin(angle).
I think the reason your attempt did not work is that you were passing angles in degrees. The sin and cos trigonometric functions expect angles expressed in radians, so the numbers should be from 0 to 2*M_PI. For d degrees you pass M_PI*d/180.0. M_PI is a constant defined in math.h header.
I also needed this to form the movement of the hands of a clock in code. I tried several formulas but they didn't work, so this is what I came up with:
motion - clockwise
points - every 6 degrees (because 360 degrees divided by 60 minuites is 6 degrees)
hand length - 65 pixels
center - x=75,y=75
So the formula would be
x=Cx+(r*cos(d/(180/PI))
y=Cy+(r*sin(d/(180/PI))
where x and y are the points on the circumference of a circle, Cx and Cy are the x,y coordinates of the center, r is the radius, and d is the amount of degrees.
Here is the c# implementation. The method will return the circular points which takes radius, center and angle interval as parameter. Angle is passed as Radian.
public static List<PointF> getCircularPoints(double radius, PointF center, double angleInterval)
{
List<PointF> points = new List<PointF>();
for (double interval = angleInterval; interval < 2 * Math.PI; interval += angleInterval)
{
double X = center.X + (radius * Math.Cos(interval));
double Y = center.Y + (radius * Math.Sin(interval));
points.Add(new PointF((float)X, (float)Y));
}
return points;
}
and the calling example:
List<PointF> LEPoints = getCircularPoints(10.0f, new PointF(100.0f, 100.0f), Math.PI / 6.0f);
The answer should be exactly opposite.
X = Xc + rSin(angle)
Y = Yc + rCos(angle)
where Xc and Yc are circle's center coordinates and r is the radius.
Recommend:
public static Vector3 RotatePointAroundPivot(Vector3 point, Vector3 pivot, Vector3 angles)
{
return Quaternion.Euler(angles) * (point - pivot) + pivot;
}
You can use this:
Equation of circle
where
(x-k)2+(y-v)2=R2
where k and v is constant and R is radius
I am drawing an imaginary circle around the middle of a button.
The radius of the circle is the Height/2 if Height>Width or Width/2 if Width>Height.
Now i have to calculate which coordinates (in pixels) are in this circle.
The idea is that if e.g. the mouse cursor hovers over that circle, something happens.
Calculating each co-ordinate is overkill; just compare the distance to the center. For example:
int radius = 5; // whatever
int deltaX = originX - mouseX, deltaY = originY - mouseY;
// compare the square distance, to avoid an unnecessary square-root
if((deltaX * deltaX) + (deltaY * deltaY) <= (radius * radius)) {
// inside the circle, or on the edge
}
To avoid a little math, you could also do a quick bounding-box check, i.e. checking the rectangular region (just addition/subtraction). This can be used in combination, i.e.
check the bounding box
if it isn't in the bounding box it certainly isn't in the circle
if it is in the bounding box, do the math to compare the square-distance
You are inside the circle when this equation is satisfied:
Math.pow(mouse_pos_x-center_circle_x,2)+Math.pow(mouse_pos_y-center_circle_y,2)<Math.pow(radius,2)
The area of a a circle by definition is a group of points whose distance is equal to or less than the center.
All you must do to test if a point is within a circle is to calculate the distance between it and the center point. If this distance is smaller than the radius of the circle, the point is within the circle.
double Distance(Point p1, Point p2)
{
int x = p1.X - p2.X;
int y = p1.Y - p2.Y;
return Math.Sqrt(x * x + y * y);
}
You can use next condition:
x^2+y^2<R^2
Where R - radius,
All this points are in circle.
This piece of code has been taken from a game built with XNA framework. I'd like some explanation of how it works in terms of trig and physics.
ball.velocity = new
Vector2((float)Math.Cos(cannon.rotation),
(float)Math.Sin(cannon.rotation));
ball.rotation is the rotation of a sprite in what i should think, radians.
Why is it that they can use the angle in radians only to find the x position then the same thing to find the y position of a direction of where the hypotenuse is pointing.
Reason why I asked this. I would like to get a feel of how this frameworks does calculations for trig. I am trying to get a sprite to turn in the direction of where the mouse is, that is: x and y is known, i just need the angle.
So there are 2 questions here. explaining that code above and pointing a sprite in the direction of a known point.
Update:
I found out that the point a which the object is at is not (0,0) because xna uses inverse coordinate system. So now the variables I have are these:
point of object.
point of mouse.
Every angle corresponds to a point on the unit circle (the unit circle is the unique circle centered at the origin with radius one; that is, the unit circle is the set of points satisfying x^2 + y^2 = 1). The correspondence is the following: given an angle theta, theta corresponds to the point (cos theta, sin theta). Why does (cos theta, sin theta) live on the unit circle? Because of everyone's favorite identity
cos^2 theta + sin^2 theta = 1.
That is with x = cos theta and y = sin theta, the point (x, y) satisfies x^2 + y^2 = 1 so that (x, y) is on the unit circle.
To reverse this, given a point on the unit circle you can find the angle by using the inverse tangent (perhaps known to you as arctan or atan and sometimes tan-1). Precisely, given (x, y) on the unit circle you can find the angle corresponding to (x, y) by computing theta = arctan(y / x).
Of course, there are some messy details here. The function arctan can't tell the difference between the inputs (x, y) and (-x, -y) because y / x and (-y / -x) have the same sign. Further, arctan can't handle inputs where x = 0. So we typically handle these by defining the function atan2 that will handle these messy details for us
atan2(y, x) = arctan(y / x) if x > 0
= pi + arctan(y / x) if y >= 0, x < 0
= -pi + arctan(y / x) if y < 0, x < 0
= pi / 2 if y > 0, x = 0
= -pi / 2 if y < 0, x = 0
= NaN if y = 0, x = 0
In C#, Math.Atan is the function arctan that I have referred to above, and Math.Atan2 is the function atan2 that I have referred to above.
|
y.-----* P
| /|
| / |
| r/ |
| / a |
|/)___.__
O x
we have:
a = angle in radians
O: origin
P: known point
r: distince between O & P
to calculate x, y:
x = r*cos(a)
y = r*sin(a)
(in your example : r = 1, a = cannon.rotation)
Now, if you have x, y and you want a:
if x!= 0 a = atan(y/x)
otherwise a = sign(y)*Pi/2
for more informations (& prettier graphs): Wikipedia: Polar coordinate system
You can see cos and sin returning the point on a circle.
In that respect see the middle of the canon as the center of the circle. Then given an angle (the angle of the canon) you can get the position on the circle it points to with sin and cos.
If you think of the cannon being centered on the 0,0 position, then this value is also the direction the bullet should travel to.
answer2: if you know x and y and you need to know the angle..you need the atan function which returns the angle formed from the sloping side of the triangle where one point is 0,0, the other point is the x,y point and one point is a point which is at the 90 degree angle
Sadly, this is a good question where SO isn't the best format to answer in.
Instead of explaining in text, I think it would be helpful to learn about parametric equations. You can start by searching "circle parametric equation" in Google.
The way that this concept clicked for me was to experiment with different pieces of code until I understood the relation between sin, cos, circles, and angles. Seeing pictures and images help a lot as well. Before then I would read descriptions but could never firmly grasp the explanations.
What you're asking is difficult to explain if you're not familiar with trig.
The line of code in question calculates a unit vector for the direction of the ball, that I presume will be fired from the cannon. The Cos and Sin part of things extract the X and Y components, respectively, of the cannon's angle. So, where the cannon points, that's the direction the ball shoots.
It's a little misleading because the result is most likely only a direction, not an actual velocity. I would assume there's a line below that one that multiplies that vector by a constant, to give the ball its final movement speed.