So I'm attempting to calculate if a point is inside of an angle. While researching, I came across many terms I am unfamiliar with. Essentially from a point (A) with a 120° angle protruding from point (A). I want to test if a secondary point (B) would be inside of the angle. All that is known is the degree of the angle and the degree at which the angle is facing and the X and Y values of both points. This will all be done in Java so any and all help is appreciated!
To better explain it:
There is a point with two vectors protruding from said point. The angle that is known is the angle that is created by the protrusion of the two vectors.
First of all, an angle is not defined for two points -- only for two lines.
Define a line that is your 0° 2D-space. For a line, you need a point and a direction.
Calculate the normal-vector for your line (Turn your directional vector by 90°); normalize both your directional and normal vector so that sqrt(x^2+y^2) = 1.
Calculate the distance vector between your initial point and the other point, this is your second line, sharing the same initial point.
Calculate the dot-product of a and b:
a = distance vector × normal vector
b = distance vector × directional vector
Use simple trigonometry to calculate the angle. It's the arctangent of (a/b) or (b/a).
You probably wanna take the absolute value of the result as well if you don't care about left and right.
Related
I am making my own implementation of a raycaster in a game I am making, and I have come across a very hard problem. I have a player (the black dot), and I need to find the intersection nearest to the player. In the image below, the arrow is pointing to the intersection point I need.
What I guess I am trying to say is that I need a function something like this:
// Each line would take in 2 map values for it's 2 points
// In turn, the map would have to have an even number of points
public Point getNearestIntersection(int playerX, int playerY, int lineDir, Point[] map) {
// whatever goes here
}
I am going to have to do this about 50 times every frame, with about 100 lines. I would like to get 40 fps at the least if possible... Even if I divide it up into threads I still feel that it would cause a lot of lag.
The class Point has a method called distance which calculates the distance of two points. You then could loop all points to get the nearest. Could be something like this:
Point currentNearestIntersection;
double smallestDistance;
for (Point inter : intersections) {
double distance = player.distance(inter );
if (distance < smallestDistance) {
currentNearestIntersection= inter;
smallestDistance = distance;
}
}
axis/line intersection is in reality solving:
p(t)=p0+dp*t
q(u)=q0+(q1-q0)*u
p(t)=q(u)
t=? u=?
where:
p0 is your ray start point (vector)
dp is ray direction (vector)
q0,q1 are line endpoints (vectors)
p(t),q(u) are points on axis,line
t,u are line parameters (scalars)
This is simple system of 2 linear equations (but in vectors) so it lead to N solutions where N is the dimensionality of the problem so choose the one that is not division by zero ... Valid result is if:
t>=0 and u=<0.0,1.0>
if you use unit dp vector for direction of your ray then from computing intersection between axis and line the t parameter is directly distance from the ray start point. So you can directly use that ...
if you need to speed up the intersections computation see
brute force line/line intersection with area subdivision
And instead of remebering all intersections store always the one with smallest but non negative t ...
[Notes]
if you got some lines as a grid then you can compute that even faster exploiting DDA algorithm and use real line/line intersection only for the iregular rest... nice example of this is Wolfenstein pseudo 3D raycaster problem like this
So, I'm working on a 2D physics engine, and I have an issue. I'm having a hard time conceptualizing how you would calculate this:
Take two squares:They move, collide, and at some vector based off of the velocity of the two + the shape of them.
I have two vector lists(2D double lists) that represent these two shapes, how does one get the normal vector?
The hit vector is just (s1 is the first shape, s2 the second) s2 - s1 in terms of the position of the center of mass.
Now, I know a normal vector is one perpendicular to an edge, and I know that you can get the perpendicular vector of a line by 90 degrees, but what edge?
I read in several places, it is the edge a corner collided on. How do you determine this?
It just makes no sense to me, how you would mathematically or programmatically determine what edge.
Can anyone point out what I'm doing wrong in my understanding? Sorry for providing no code to explain this, as I'm having an issue writing the code for it in the first place.
Figure1: In 2D the normal vector is perpendicular to the tangent line:
Figure2: In 3D the normal vector is perpindicular to the tangent plane
Figure3: For a square the normal vector is easy if you are not at a corner; It is just perpendicular to the side of the square (in the image above, n = 1 i + 0 j, for any point along the right side of the square).
However, at a corner it becomes a little more difficult because the tangent is not well-defined (in terms of derivatives, the tangent is discontinuous at the corner, so perpendicular is ambiguous).
Even though the normal vector is not defined at a corner, it is defined directly to the left and right of it. Therefore, you can use the average of those two normals (n1 and n2) as the normal at a corner.
To be less technical, the normal vector will be in the direction from the center of the square to the corner of the collision.
EDIT: To answer the OP's further questions in the chat below: "How do you calculate the normal vector for a generic collision between two polygons s1 and s2 by only knowing the intersecting vertices."
In general, you can calculate the norm like this (N is total verts, m is verts inside collision):
vcenter = (∑N vi) / N
vcollision = (∑m vi) / m
n = vcollision - vcenter
Fig. 1 - vcollision is only a single vertex.
Fig. 2 - vcollision is avg of two verts.
Fig. 3 - vcollision for generic polygon intersection.
consider having a circle on map with center GLatLng (A) and a radius (r) in meters.
How to calculate the GLatLng at position B? Assuming that r is parallel to the equator.
Getting the radius when A and B is given is trivial using the GLatLng.distanceFrom() method - but doing it the other way around not so.
to summarize, given Lat/lng of Point A and R in meters, I need to get Lat/Lng of Point B. direction is not important.
All you need to do is take the original point and compute the distance for one degree to the east or west. That will give you the distance per degree along that line of latitude. Then divide r by the distance per degree and it will tell you how many degrees B is to the east or west.
I'm trying to understand how the quaternion rotations work, I found this mini tutorial http://www.julapy.com/blog/2008/12/22/quaternion-rotation/ but He makes some assumptions that I can't workout, like how can I do "work out the rotation vectors around each axis, simply by rotating the vector around an axis." and how does he calculate angleDegreesX, angleDegreesY and angleDegreesZ?
Can some one provide a working example or explanation?
The shortest possible summary is that a quaternion is just shorthand for a rotation matrix. Whereas a 4x4 matrix requires 16 individual values, a quaternion can represent the exact same rotation in 4.
For the mathematically inclined, I am fully aware that the above is super over-simplified.
To provide a little more detail, let's refer to the Wikipedia article:
Unit quaternions provide a convenient
mathematical notation for representing
orientations and rotations of objects
in three dimensions. Compared to Euler
angles they are simpler to compose and
avoid the problem of gimbal lock.
Compared to rotation matrices they are
more numerically stable and may be
more efficient
What isn't clear from that opening paragraph is that a quaternion is not only convenient, it's unique. If you have a particular orientation of an object, twisting on any number of axes, there exists a single unique quaternion that represents that orientation.
Again, for the mathematically inclined, my uniqueness comment above assumes right-handed rotations. There is an equivalent left-handed quaternion that rotates in the opposite direction around the opposite axis.
For the purpose of simple explanation, that is something of a distinction without a difference.
If you'd like to make a simple quaternion that represents rotation about an axis, here's a short series of steps that will get you there:
Pick your axis of rotation v = {x, y, z}. Just for politeness, please pick a unit vector: if it's not already of length 1, divide all the components by the length of v.
Pick an angle of rotation that you'd like to turn about this axis and call that theta.
The equivalent unit quaternion can be computed using the sample code below:
Quaternion construction:
q = { cos(theta/2.0), // This is the angle component
sin(theta/2.0) * x, // Remember, angle is in radians, not degrees!
sin(theta/2.0) * y, // These capture the axis of rotation
sin(theta/2.0) * z};
Note those divisions by two: those ensure that there's no confusion in the rotation. With a normal rotation matrix, rotating to the right 90 degrees is the same as rotating to the left by 270. The quaternions that are equivalent to those two rotations are distinct: you can't confuse one with the other.
EDIT: responding to the question in the comments:
Let's simplify the problem by setting the following frame of reference:
Pick the center of the screen as the origin (we're going to rotate around that).
X axis points to the right
Y axis points up (top of the screen)
Z axis points out of the screen at your face (forming a nice right handed coordinate system).
So, if we have an example object (say an arrow) that starts by pointing to the right (positive x axis). If we move the mouse up from the x axis, the mouse will provide us with a positive x and positive y. So, working through the series of steps:
double theta = Math.atan2(y, x);
// Remember, Z axis = {0, 0, 1};
// pseudo code for the quaternion:
q = { cos(theta/2.0), // This is the angle component
sin(theta/2.0) * 0, // As you can see, the zero components are ignored
sin(theta/2.0) * 0, // Left them in for clarity.
sin(theta/2.0) * 1.0};
You need some basic math to do what you need. Basically, you rotate a point around an axis by multiyplying the matrix representing that point with a rotation matrix. The result is the rotated matrix represantation of that point.
The line
angleX = angleDegreesX * DEGTORAD;
just converts the degrees representation into a radians reprensentation by a simple formular (see this Wikipedia entry on Radians)
You can find some more information and examples of rotation matrizes here: Rotation around arbitrary axes
There are probably tools in your programming framework to do that rotation work and retrieve the matrices. Unfortunately, I cannot help you with the quaternions but your problems seem to be a little bit more basic.
currently i have using a framework and it has a function called distance2D, and it has this description:
Calculate the Euclidean distance
between two points (considering a
point as a vector object). Disregards
the Z component of the vectors and is
thus a little faster.
and this is how i use it
if(g.getCenterPointGlobal().distance2D(target.getCenterPointGlobal()) > 1)
System.out.println("Near");
i have totally no idea what a Euclidean distance is, i am thinking that it can be used to calculate how far 2 points are? because i am trying to compare distance between 2 objects and if they are near within a certain range i want to do something. how would i be able to use this?
Euclidean distance is the distance between 2 points as if you were using a ruler. I don't know what are the dimensions of your Euclidean space, but be careful because the function you are using just takes in consideration the first two dimensions (x,y). Thus if you have a space with 3 dimensions(x,y,z) it will only use the first two(x,y of x,y,z) to calculate the distance. This may give a wrong result.
For what I understood, if you want to trigger some action when two points are within some range you should make:
<!-- language: lang-java -->
if(g.getCenterPointGlobal().distance2D(target.getCenterPointGlobal()) < RANGE)
System.out.println("Near");
The Euclidean distance is calculated tracing a straight line between two points and measuring as the hypotenuse of a imaginary isosceles triangle between the two lines and a complementary point. This measure is scalar, so it's a good metric for your calculations.
Euclidean geometry is a coordinate system in which space is flat, not curved. You don't need to care about non-Euclidean geometry unless for example you're dealing with coordinates mapped onto a sphere, such as calculating the shortest travel distance between two places on Earth.
I imagine this function will basically use Pythagoras' theorem to calculate the distance between the two objects. However, as the description says, it disregards the Z component. In otherwords, it will only give a correct answer if both points have the same Z value (aka "depth").
If you wish to compare distances and save time, use not the distance itself, but its square: (x1-x2)^2 + (y1-y2)^2. Don't take sqrt. So, your distances will work exactly as euclidian ones, but quickly.