Finding circle from a normal vector c# [duplicate] - c#

This question already exists:
circle in three dimensional coordiantes [closed]
Closed 1 year ago.
I want to draw a circle in three dimensional coordiantes, i'm given a vector, the angle where vector's intersects with the circle is 90 degrees, the intersection point is the centre of the circle. The radius can be parametrized. EDIT: I am programming a server plugin for minecraft. At this point I have made a sword that can be thrown. I want to add some decor. I want that after the sword there was a trace in the form of a circle. But I don't understand how to draw a circle in 3D coordinates so that the angle of intersection of the sword throw vector with the center of the circle is 90 degrees. The radius can be arbitrary, and the vector can enter the center of the circle. I thought I could just rotate the throw vector on 3 axes and get a circle, but nothing worked. I need an equation with which I can draw a given circle.

You have center C, normal vector N, radius R. Seems you want to get points at the circumference.
At first get some base vector in the circle plane.
Possible way:
Reveal normal component with the largest magnitude and with the second magnitude. For example, abs(N.X) is the largest, abs(N.Z) has the second magnitude, and abs(N.Y) is the smallest. Make the smallest component zero, exchange two larger ones, and negate the largest. For this example base vector will be:
A = (N.Z, 0, -N.X)
It is perpendicular to normal, hence lies in the circle plane.
Then get the next basis vector using vector product (B will be perpendicular both to A and to N, it lies in the plane too)
B = N x A
Now normalize vectors A and B (make them unit length)
A = A / len(A)
B = B / len(B)
and you can get any point at the circumeference with parametric equation where t changes in the range 0..2*Pi
P(t) = C + R * A * Cos(t) + R * B * Sin(t)
or in components:
P.X = C.X + R * A.X * Cos(t) + R * B.X * Sin(t)
and so on

Related

Shifting angles while using Atan2

I am currently using Atan2 to calculate the player heading angle.
however after some trial and error I discovered that the in-game angle's are rather different to that of a "normal" lay out :
ReturnedAngle = Math.Atan2(Y2 - Y1, X2 - X1); /// ArcTan2 the difference in our Y axis is always passed first followed by X
ReturnedAngle = (180 / Math.PI) * ReturnedAngle; /// Converting our radians to Degrees the convervion ends at 358 not the full 360 degrees.
ReturnedAngle = Math.Round(ReturnedAngle + 360, MidpointRounding.AwayFromZero) % 360; /// MOD and round our angle.
Above is the C# code I am using to calc the heading angle. My questions is how would I go about converting this angle from the "normal" angle system to the in-game one.
I think this is your situation. You have a right-hand coordinate system, but you are measuring a clock-wise angle, which is inconsistent.
In any case, draw a small positive angle from 360 (red below) to form a right triangle (purple below) with positive sides.
To measure the angle θ of the triangle, measure the short side Δx and the long side Δy and compute.
var θ = Math.Atan2(Δx, Δy);
This would work for any positive or negative values for the two sides. For example, if the angle goes above 90° then Δy would flip signs, as your target point is going to be below the origin. But the beauty of Atan2() is that you don't need to worry about these cases as it works on all four quadrants if you make it work for a small positive angle.
In reverse you have
var Δx = R*Math.Sin(Θ);
var Δy = R*Math.Cos(Θ);
where R is the distance between the target and the reference point.
Math.Atan2(Y2 - Y1, X2 - X1) computes the angle anticlockwise from the x axis. Math.Atan2(X2 - X1, Y2 - Y1) computes the angle clockwise from the y axis, which is what you want.
The 'clockwise from north' convention is used in navigation and mapping. Over the years I've found that it easiest to think in terms of vectors having components north, east. This means that atan2 is called the same way, that is, to get the direction of q from p:
dirn = atan2( q[1]-p[1], q[0]-p[0]);
If you are thinking of p and q as x,y vectors this gives you the angle anti-clockwise from the x axis. If you are thinking of p and q as n,e vectors it gives you the angle clockwise from north.
It also means that the formulae for a rotation matrix is the same. To rotate through an angle a, you use the matrix
R = ( cos(a) -sin(a) )
( sin(a) cos(a) )
Again, if you are thinking of the vectors as being x,y then applying R rotates through and angle a, anti-clockwise from the axis, while if you think of vectors as being n,e applying R rotates through an angle a, clockwise from north.

Find Angle Between Two Vectors

I have read some of the duplicate answers about angle between two vectors, but I'm still stuck with my problem. I have two vectors and I want that the angle between them to always be 90 degrees. To achieve that I need to find the angle between them, so that I can subtract or add the correct amount of degrees so that the angle between them always is 90 degrees.
The picture illustrates a sprite and two vectors. How do I find the angle A between them two? I have tried to use this code to get the angle between two vectors, but I must have missed something out, because I don't get the correct results:
public float GetAngleBetween (Vector2 A, Vector2 B)
{
float DotProd = Vector2.Dot (A, B);
float Length = A.Length () * B.Length ();
return (float)MathHelper.ToDegrees ((float)Math.Acos (DotProd/Length));
}
Any input is welcome and thank you in advance for any answers.
The actual angle in radians is
Math.ACos(Vector2.Dot(a, b));
Make sure that a and b are normalized vectors or the results can get pretty weird.
I think you may be looking for the Vector2.Dot method which is used to calculate the product of two vectors, and can be used for angle calculations.
For example:
// the angle between the two vectors is less than 90 degrees.
Vector2.Dot(vector1.Normalize(), vector2.Normalize()) > 0
// the angle between the two vectors is more than 90 degrees.
Vector2.Dot(vector1.Normalize(), vector2.Normalize()) < 0
// the angle between the two vectors is 90 degrees; that is, the vectors are orthogonal.
Vector2.Dot(vector1.Normalize(), vector2.Normalize()) == 0
// the angle between the two vectors is 0 degrees; that is, the vectors point in the same direction and are parallel.
Vector2.Dot(vector1.Normalize(), vector2.Normalize()) == 1
// the angle between the two vectors is 180 degrees; that is, the vectors point in opposite directions and are parallel.
Vector2.Dot(vector1.Normalize(), vector2.Normalize()) == -1
Is this what you're looking for, or do you need the exact angle?
If I understand your question diagram and comments, the Dot product and Acos are not the only bits of info you need. You also need to account for when the sprite is not located at (0,0).
float angleInRadians = (float) Math.Acos(Vector2.Dot(Vector2.Normalize(vector1 - spritePosition), Vector2.Normalize(vector2 - spritePosition)));
int angleInDegrees = MathHelper.ToDegrees(angleInRadians);

converting xinput coordinates to a square

i'm working on a small c# program that uses xinput to read the xbox 360 thumb stick.
i have no problem with reading the coordinates and normalizing the values so i get a float between -1 and +1 for X and Y directions.
the problem i have is that the stick itself is physically limited to a circle and in my case i would like to "stretch out" the coordinates so it becomes more of a square than a circle.
the reason is that each direction is controlling a motor and if i move the stick for example top right i would like both X and Y to become 1.
since the stick is circular this is not possible and this also makes it impossible to make both motors run at full speed.
any advice?
So you want a point on a circle of radius r to be mapped to a point on a square of radius r on the same ray through the origin. Toward that goal you have to compute the radius using the usual formula
r = sqrt(x*x+y*y)
and then from that the scale factor
f = r / max ( abs(x), abs(y) )
and in the end replace x by f*x and y by f*y.
One can vary this computation by noting that the factor is
f = sqrt ( 1 + (x*x)/(y*y) )
if abs(y) > abs(x) and
f = sqrt ( 1 + (y*y)/(x*x) )
in the opposite case. Or by noting that the largest coordinate gets replaced by r and the smaller scaled accordingly, which also does not reduce the logistics by much.

Getting rotation axis from initial and final rotated quaternions

I have to find the axis and angle of rotation of a camera with an UP and Direction vector(They both are perpendicular to each other). I have the initial and final positions of the UP and direction vectors of the camera that is rotated. I want to find the axis and angle of the rotation for the camera. I am using C# for my project. I am new to this 3D rotation. So pardon my questions if you find them silly.
From the direction (forward) vector f and up vector u you can get the side vector s by performing a vector cross product (s = f x u). All three vectors are now orthogonal. You should also make them orthonormal by normalizing each one of them. Taken together, these vectors form an orthonormal basis.
You now have two such basis: the one from your initial camera orientation and the one from your final camera orientation. Both basis can be represented as a rotation matrix. A rotation matrix is simply a 3x3 matrix where the 3 rows are respectively:
The forward vector
The up vector
The side vector
For example, the matrix:
[[1 0 0]
[0 1 0]
[0 0 1]]
could be your initial camera orientation at start-up with its forward vector, up vector and side vector pointing towards the positive x axis, y axis and z axis, respectively.
You can now convert these two basis (M1 and M2) to two unit quaternions (Q1 and Q2) using this algorithm which takes care about potential problems like divides by zero.
At this point, you have two unit quaternions representing your initial and final camera orientation. You must now find the quaternion qT that transforms Q1 into Q2, that is:
q2 = qT * q1
q2 * q1^-1 = qT * (q1 * q1^-1) = qT
=> qT = q2 * q1^-1
Knowing that the inverse of a unit quaternion is equal to its conjugate:
q1^-1 = q1* iif ||q1|| = 1
qT = q2 * q1^-1 = q2 * q1*
There is a single step left: extracting the axis and angle from quaternion qT:
angle = 2 * acos(qw)
x = qx / sqrt(1-qw*qw)
y = qy / sqrt(1-qw*qw)
z = qz / sqrt(1-qw*qw)
The angle is, of course, given in radian. Beware of the divide by zero when calculating x, y and z. This situation would happen when there is no rotation or a very small one, so you should test if angle > epsilon where you would choose epsilon to be quite small an angle (say 1/10 of a degree) and not calculate the vector if that is the case.

Cone-Line Segment Intersection 2D

I would like to know if is there any way to determine if a cone is intersecting with a (finite) line segment. The cone is actually a circle located at P(x,y) with theta degree field of view and radius r:
I'm trying to do it in C# but I don't have any idea how to that, so for now this is what I'm doing:
Check if the line segment is intersecting with the circle;
If the line segment is intersecting with the circle then I check every single point in the line segment using a function I found here.
But I don't think this is the best way to do it. Does anyone have an idea?
For additional info, I need this function to make some kind of simple vision simulator.
Working with Polar Co-ordinates might help. Here, instead of representing a point as (x,y) you represent it as (r, angle), where r is distance from origin and angle is the angle made with a chosen axis (which corresponds to angle 0).
In your case, if you set P(x,y) to be origin and one of the rays of the cone as angle = 0 and find polar co-ordinates of the end points of the line segment, say (r1, ang1) and (r2, ang2) then you need the following four conditions to be true for the line segment to be completely within (including boundary) of the cone.
r1 <= r
r2 <= r
ang1 <= theta
ang2 <= theta
where r is the radius of the cone and theta is the angle of view and you chose the axis so that rotating counter-clockwise gives a corresponding positive angle.
Switching between polar and (x,y) (called rectangular) coordinates is easy, and you can find it on the wiki link I gave above.
In order to determine if any point of the line segment intersects the curve you can use the polar equation of a line give here: Link
We can use the Polar normal form
R = p sec(ang - omega)
We can figure out p and omega given the two end-points of the line segment as follows:
We have
p = r1 * cos(ang1-omega) = r2*cos(ang2-omega)
Using cos(x-y) = cos(x)*cos(y) + sin(x)*sin(y) we get
[r1*cos(ang1) - r2*cos(ang2)] * cos(omega) = [r2*sin(ang2) - r1*sin(ang1)] * sin(omega)
Thus you can calculate tan(omega) = sin(omega)/cos(omega) and use arctan (the inverse function of tan) to get the value of omega. Once you know what omega is, you can solve for p.
Now we need to know if there is some (R, ang) combination on this line such that
R <= r
0 <= ang <= theta
min{ang1, ang2} <= ang <= max{ang1, ang2}
(Note r was radius of cone, and theta was the angle of view, ang1 was angle of P1 and ang2 was angle of P2).
The equation can be rewritten as
Rcos(ang-omega) = p
Now cos(ang-omega) is a very nicely behaved function in terms of monotonicity and you only need to consider it in the interval [min{ang1, ang2}, max{ang1, ang2}].
You should be able to do some manual manipulations first in order to simplify your code.
I will leave the rest to you.
I'd Google around for line/convex polygon intersection algorithms, your field of view is composed of a triangle and a part of a circle which can be approximated to any degree of accuracy by a convex polygon. Your first step might still be useful to rule out lines which go nowhere near the field of view.
If you keep it 2D like above, intersection can be calculated as follows:
Starting point of line segment is S1, ending is S2.
Left edge of code is a vector along the edge C1, right edge is C2, Origin of code is O.
Take the sign of the Z component of the cross product of the vector formed from (O to S1) and C1.
Take the sign of the Z component of the cross product of the vector fromed from (O to S2) and C1. If the signs differ, your starting and ending points are on opposite sides of C1 and therefore they must intersect. If not, do the same comparisons with C2 instead of C1.
If neither side's signs differ, no edge intersection.
In 3D, it's a bit more complicated. I've googled and found cone sphere intersection any number of times. Doing it for lines, would be very similiar, I just need to think about it for a bit :)
A quick google of 'cone line intersection' got all sorts of hits. The basic idea is to form a plane from the cone's origin and the starting and ending point of the line. Once you have that, you can take the angle between that plane and the cone's direction normal. If that angle is less than the angle of the spread on the cone, you have an intersection.

Categories

Resources