I have a list of points (x,y coordinates) which describe a path. Suppose {(1,1),(2,2),(5,2)} can be a list of points of a path.
Now, I want to instruct my user the way to move along the path. For example, at each point, there will be a string attached which will describe the user how to go to the next point. It can be something like, "go 90 degree left", "go 35 degree right" etc.
Is there any algorithm or suggested way to do that?
Please let me know if any part of the problem description is not understandable.
If your user is at point 1 (x1,y1) and you want him to go to point 2 (x2, y2) then you calculate what is called the position vector. The short answer is that you calculate the position vector's magnitude and angle. The magnitude tells the user how far to move and angle tell him the direction. So,
magnitude = sqrt( (x2-x1)^2 + (y2-y1)^2 )
angle = arc tan( (y2-y1)/(x2-x1))
and then you may want to convert the angle from radians to degrees with angle=angle*(180/pi).
Related
I am looking for some information on how to "bend" an arbitrary list of points/vertices similar to the bend modifier you can find in typical 3D modelling programs.
I want to provide a list of points, a rotation focal point, and a "final angle." For my purposes, I will always be saying "points at minimum y of the set will not change, points at maximum y will be rotated at the maximum angle, everything in between is interpolated."
Example Image of starting configuration and desired result, given a 90 degree rotation:
Can anyone suggest a resource that would explain how to go about this? I'm prepared to code it (C++) but I'm wracking my brain on a concept that would make this work. It would be easy to generate the vertices, but the application I'm writing this for takes in user-created content and needs to bend it.
(Edited to add: I don't need a miracle matrix or deep equation solution... if you say something like "for each vertex, do this" that's good enough to get the green checkmark)
Thanks!
You seem to be transforming a straight line to a circular arc, preserving distances between adjacent points.
So, if the point A is the one you want to hold constant, pick another point B to be the center of that circle. (The nearer B is to A, the more severe the bending.) Now for any point C you want to transform, break the vector C-B into the component parallel to A-B (call that component R) and the component perpendicular to it (call that k). The magnitude of R will be the radius of the circle you map C to, and you can transform the magnitude of 'k' into distance along that circle:
theta = |k|/|R|
C` = B + R cos(theta) + k|R|/|k| sin(theta)
In a 2D plane, I have 2 objects (A and B) with 2 coordinates. Their centers are A(xA, yA) and B(xB, yB) (and C(xC, yC)=C(xB, yA) as AC parallel to the OX line and BC is perpendicular on AC). I can manipulate the rotation of an object and I have access to all usual math operations and can use degrees and radians.
I researched but I couldn't find anything explained in detail.
I also tried using the math formula with arccos formula as follows:
I tried to calculate the distance from A to B (AB) using the Pythagoras theorem, then calculate A to C (AC), then calculate cos(angle)=AC/AB, so the final angle to which I would need to rotate object A towards B is arccos(AC/AB).
Problem is this sounds insanely buggy as you can probably get a lot of digits and ruin everything.
So how can I do this? Please explain mathematically. Thanks!
The simplest way to find the angle between two points is to take their arctangent (a.k.a. inverse tangent). You were on the right track with using cosine, but tangent simplifies the process by not requiring the distance between the points to be known.
As such, you'll want to use an atan2 function in your choice of language. The C# Math.Atan2, for example:
double angle = Math.Atan2(B.Y - A.Y, B.X - A.X);
Note: This particular function returns the angle in radians.
Do you want to rotate object A towards B with C like center of the rotation ?
If it's the case you have only to rotate with an angle of 90 degrees because your triangle is special. But if you want to apply a rotation with a specific angle around a specific center you have to use a transformation TRT.
You will find more explanation here.
I need help creating a specialized line-collision algorithm that allows "cutting corners" at certain angles.
In the following pictures, let the blue square represent the player and the black square represent a wall. The white squares, then, represent squares in a player's "line of sight" (valid squares), and the grey squares are squares outside a player's "line of sight" (invalid squares):
The second image is where things get more interesting as we start cutting corners:
Let's take a closer look at this line which is allowed despite passing over the corner of the wall:
The line is allowed because:
dx <= 0.5 (with a square being 1x1)
dx/dy is above a certain ratio (say, 2 - I'm not sure of the exact value represented in these images.)
The converse line is not allowed because the ratio (of dy/dx in this case) is too low:
Or perhaps I should talk about the angle of entry vs exit from the square....
The main problem I'm having is that I can't figure out how to generalize a solution for vectors traveling at any angle between two points on the grid. I can't decide if I should use trigonometry or what. My closest solution so far has been to use the decimal parts of line interceptions with each square as the dx and dy's and check whether it's allowed based on the slope of the line and what quadrant it's in.
Can anyone help?
I've also looked at borrowing or starting from other line algorithms, but I haven't found anything too useful. Most of them that I've seen want a line from (x1, y1) to (x2, y2) to be the same as from (x2, y2) to (x1, y1) which makes this problem quite different.
I suggest using circles, they are quite optimal corner wise.
I assume that coordinates are taken at the center of each pixels.
The algorithm for knowing if (xo,yo) is hiding the view from (xa,ya) to (xb,yb) would then be:
compute (xc,yc) the nearest point to (xo,yo) on the line from (xa,ya) to (xb,yb)
compute distance d from (xo,yo) to (xc,yc)
if d < half a pixel, then the view is hidden
You can simplify first two stages by directly calculating the distance between point and line http://en.wikipedia.org/wiki/Distance_from_a_point_to_a_line and eventually compute squared distance if you want to avoid sqrt
I cant seem to figure out how to calculate the incline of a curve for the following situation...
Essentially what I am trying to do is increase the speed of an object based on the incline of the curve at a particular point. The speed will be reduced if the incline is upwards and increase if downward.
I was using the derivative of a point t on the bezier curve to establish the tangent but this doesnt seem to be right as I would expect that value to be negative if the slope is downward.
I have been using the below equation for the tangent to evaluate X, Y and Z but then I only use Y to establish the incline...I think that step may be wrong
Any ideas?
EDIT:
Ultimately this is an object moving along an inclined plane but I cant establish the angle of the plane in order to do this, I believe if I could correctly find the angle it may solve the problem. I tried to take the point in question and then another point in front (so for example t = 0.5 and then a point in front would be t=0.51) and then calculate the angle using tan. I completely ignore the Z axis but is that wrong? If not how should I calculate the angle?
Thanks a lot
This should help: http://www.physicsclassroom.com/Class/vectors/U3L3e.cfm .
Essentially, you need to calculate the angle of inclination. If the angle is \theta , then the acceleration depends on sin(\theta).
I am assuming z as the vertical dimension.
if dx,dy and dz is are the gradients in each directions, dw = sqrt( dx^2+dy^2). \theta = tan_inverse( dz/dw). Acceleration = g*sin(\theta).
NOTE: You can directly calculate sin(\theta) without explicitly calculating \theta. sin(\theta) = dz/sqrt(dx^2+dy^2+dz^2).
=== More formal description ===
Let x be the east-west dimension, y be the north-south dimension and z be the up-down dimension.
Let z = F(x,y) give the elevation of the terrain at any given location x,y.
Calculate dz/dx = fx(x,y) and dz/dy = fy(x,y), the partial derivatives of z w.r.t to x and y.
Now, sin(\theta) = dz/sqrt(dx^2+dy^2+dz^2) = 1/(sqrt( (dx/dz)^2+ (dy/dz)^2 )= 1/(sqrt( (1/fx(x,y))^2, (1/fy(x,y))^2 ).
This is how you calculate sin(\theta).
The value of derivation is negative when the slope is "downward". And yes, the derivation is the tangent of the slope angle. Only you should pay attention to the directions. They can change the sign, of course. Only you should take dy/dx, not dy/something else. That is all on 2d curves.
You mention Z in the last paragraph. You curve is 3D? Then, of course, the term "derivation" should be put more precisely. Derivation of what to what do you need? The second idea is - please, explain better, what do you want. BTW, maybe after you write down the task correctly, you'll see the solution as obvious.
If it is 3D, let us say, you have your curve as 3 functions of x(t), y(t), z(t). then you need dz/dq, where dq= dt*sqrt((dx/dt)^2+(dy/dt)^2). Obviously, isn't it?
As I said, no maths here. Merely Pythagor's theorem and proportions. (I take z as height)
Addition: it can be rerecounted as tan(a)=dz/(dt*sqrt((dx/dt)^2+(dy/dt)^2)) => tan(a)=(dz/dt)/sqrt((dx/dt)^2+(dy/dt)^2)) ==> a=ATAN((dz/dt)/sqrt((dx/dt)^2+(dy/dt)^2)). But look out for directions you are moving! They can reverse the sign. For under sqrt(^2+^2) we have lost the direction of the dt proection.
It does not need to be very accurate. Does anyone know a good way to do this?
any help is much appreciated.
When you say “it does not need to be very accurate” you don’t say how inaccurate a solution you’re prepared to accept. Also, you don’t say how big the geographic region under consideration is likely to be. These two criteria make a big difference to the kind of approach that needs to be taken.
With a small regions (a few kilometres, say), a flat approximation may be good enough (for example, the Mercator projection) and some of the other responses tell you how to do that. With larger regions you have to take the Earth’s sphericity into account. And if you want inaccuracy less than a percent or so, you need to take the eccentricity of Earth into account.
I’m going to assume for the purposes of this answer that a spherical approximation is good enough, and that your points are at similar enough altitudes that we don’t need to worry about their heights.
You can convert a geographical point (ψ, λ) to Cartesian Earth-centred coordinates using the transformation
(ψ, λ) → (a cos(ψ) cos(λ), a cos(ψ) sin(λ), a sin(ψ))
where a is the mean radius of the Earth (6,371 km). So let’s suppose that the two points that define your line are p₀ and p₁; then the shortest line through p₀ and p₁ is a great circle, which defines a plane that slices the Earth into two halves, with normal n = p₀ × p₁.
Now we need to find the border of the circular region. Suppose the centre of this region is at c and that the surface radius of the region is s. Then the straight-line radius of the region is r = a sin(s/a). We’ll also need the true centre of the circular region, c’ = c cos(s/a). (This point is buried deep underground!)
We’d like to intersect the two circles and solve for the points of intersection. Unfortunately, because of numerical imprecision, the chances are that this procedure will never find any solutions because the imprecise circles will miss each other in 3 dimensions. So I suggest the following procedure: intersect the planes of the two circles, getting the dotted line shown below (unless c’ × n = 0 in which case the two circles are parallel and either c’ = o, in which case they are coincident, or else they do not intersect). Then intersect the line with the circular region.
This two-step procedure reduces the problem to two dimensions, and guarantees that a solution will be found even if numerical imprecision makes the two circles miss in 3 dimensions.
If you need more accuracy than this, then you might need to use geodetic coordinates on a reference ellipsoid such as WGS 1984.
I'd say find the closest point on the line to the center of the circle, then determine whether that point is within the circle (i.e. the distance in question is less than or equal to the circle's radius).
Outline for solving the problem: assume the Earth is a sphere of radius one centered at the origin. Convert all three lat, lon points to 3D coordinates. The two points of the line plus the origin define a plane; intersect that plane with the sphere of radius d centered on the other point. If there is no plane-sphere intersection, then the answer is the line does not intersect the region. If there is a plane-sphere intersection, then the problem is simplified to intersecting the circular region defined by the plane-sphere intersection with the shortest circular arc on the plane going between the end points of the line and centered at the origin. This is a straightforward 2D problem if you convert to the coordinate system of the plane.
This question is too vague to be answered precisely. What do you mean by
a line form by 2 geo points (lat, lon)
This can be either a great circle going through them (also called orthodrome) or it a can be a linear function of spherical coordinates (loxodrome).
BTW, I assume your circle is a circle on the surface of the sphere, right?
Assuming line is formed by points (x1, y1) and (x2, y2), and circle has radius r with origin (0,0):
Calculate:
Incidence = r^2 * [(x2 - x1)^2 + (y2 - y1)^2] - (x1 * y2 - x2 * y1)^2
Then, from the value of Incidence, we can determine the following:
Incidence < 0: No intersection
Incidence = 0: Tangent (intersection at 1 point on circle)
Incidence > 0: Intersection
It's likely your circle is not at the origin (0,0), so to fix this, just add the origin coordinates from your line coordinates in the equation above. So, if the circle is at (x3, y3), x1 in the above equation would become x1 + x3. Likewise, y1 would be y1 + y3, and the same goes for x2 and y2.
For more info check out this link