Given a circle with a known center point and two points on the circle (thus known radius), how do I determine the angle of the minimum arc between the two points on the circle?
Turn the center to the two points into a pair of vectors, then shove through this.
So, cos-1 ((x1x2 + y1y2 + z1z2) / r2).
Related
Given a non-self-intersecting polygon as a list of points (p1...pn), and a point (A) outside that polygon:
I want to calculate the total angular field of view covered by the polygon from the point, as well as the direction from the point towards the middle of that field of view (as either a vector or angle from horizontal).
Visually, I want the angle Θ and direction of the green vector:
Diagram
I tried finding the minimum and maximum angles from horizontal to each of the polygon points, but I don't know how to tell which is the start of the range and which is the end. Assuming the smaller angle is the start gives incorrect results from the left of a simple box.
I'm guessing the solution will have something to do with whether the polygon points are in clockwise or counterclockwise order.
Whether the polygon goes clockwise or counterclockwise doesn't matter. What matters is that the extent of any edge, as seen from the point, must be less than π radians. That will tell us whether the edge -- as seen from the point -- goes counterclockwise from A to B, or from B to A.
For example, suppose the bearings (in radians) from the point to the vertices are {0, 2π/5, 4π/5, 6π/5, 8π/5}. If the edges are represented by the (unordered) pairs (A,C), (A,E), (B,D), (B,E), (C,D). Then the edges run:
0->4π/5
2π/5->6π/5
4π/5->6π/5
8π/5->0
8π/5->2π/5
So the range of the polygon is [8π/5, 6π/5].
I'd need a formula to calculate 3D position and direction or orientation of a camera in a following situation:
Camera starting position is looking directly into center of the Earth. Green line goes straight up to the sky
Position that camera needs to move to is looking like this
Starting position probably shouldn't matter, but the question is:
How to calculate camera position and direction given 3D coordinates of any point on the globe. In the camera final position, the distance from Earth is always fixed. From desired camera point of view, the chosen point should appear at the rightmost point of a globe.
I think what you want for camera position is a point on the intersection of a plane parallel to the tangent plane at the location, but somewhat further from the Center, and a sphere representing the fixed distance the camera should be from the center. The intersection will be a circle, so there are infinitely many camera positions that work.
Camera direction will be 1/2 determined by the location and 1/2 determined by how much earth you want in the picture.
Suppose (0,0,0) is the center of the earth, Re is the radius of the earth, and (a,b,c) is the location on the earth you want to look at. If it's in terms of latitude and longitude you should convert to Cartesian coordinates which is straightforward. Your camera should be on a plane perpendicular to the vector (a,b,c) and at a height kRe above the earth where k>1 is some number you can adjust. The equation for the plane is then ax+by+cz=d where d = kRe^2. Note that the plane passes through the point (ka,kb,kc) in space, which is what we wanted.
Since you want the camera to be at a certain height above the earth, say h*Re where 1 < k < h, you need to find points on ax+by+cz=d for which x^2+y^2+z^2 = h^2*Re^2. So we need the intersection of the plane and a sphere. It will be easier to manage if we have a coordinate system on the plane, which we get from an orthonormal system which includes (a,b,c). A good candidate for the second vector in the orthonormal system is the projection of the z-axis (polar axis, I assume). Projecting (0,0,1) onto (a,b,c),
proj_(a,b,c)(0,0,1) = (a,b,c).(0,0,1)/|(a,b,c)|^2 (a,b,c)
= c/Re^2 (a,b,c)
Then the "horizontal component" of (0,0,1) is
u = proj_Plane(0,0,1) = (0,0,1) - c/Re^2 (a,b,c)
= (-ac/Re^2,-bc/Re^2,1-c^2/Re^2)
You can normalize the vector to length 1 if you wish but there's no need. However, you do need to calculate and store the square of the length of the vector, namely
|u|^2 = ((ac)^2 + (bc)^2 + (Re^2-c^2))/Re^4
We could complicate this further by taking the cross product of (0,0,1) and the previous vector to get the third vector in the orthonormal system, then obtain a parametric equation for the intersection of the plane and sphere on which the camera lies, but if you just want the simplest answer we won't do that.
Now we need to solve for t such that
|(ka,kb,kc)+t(-ac/Re^2,-bc/Re^2,1-c^2/Re^2)|^2 = h^2 Re^2
|(ka,kb,kc)|^2 + 2t (a,b,c).u + t^2 |u|^2 = h^2 Re^2
Since (a,b,c) and u are perpendicular, the middle term drops out, and you have
t^2 = (h^2 Re^2 - k^2 Re^2)/|u|^2.
Substituting that value of t into
(ka,kb,kc)+t(-ac/Re^2,-bc/Re^2,1-c^2/Re^2)
gives the position of the camera in space.
As for direction, you'll have to experiment with that a bit. Some vector that looks like
(a,b,c) + s(-ac/Re^2,-bc/Re^2,1-c^2/Re^2)
should work. It's hard to say a priori because it depends on the camera magnification, width of the view screen, etc. I'm not sure offhand whether you'll need positive or negative values for s. You may also need to rotate the camera viewport, possibly by 90 degrees, I'm not sure.
If this doesn't work out, it's possible I made an error. Let me know how it works out and I'll check.
So let's say I have 2 objects. One with the sprite of a circle, other with the sprite of triangle.
My triangle object is set to the position of mouse in every step of the game, while circle is either standing in place or just moving in its own way, whatever.
What I want to do is to have the TRIANGLE move around the circle, but not on it's own, rather on the way your cursor is positioned.
So basically, calculate degree between circle's center and triangle's center. Whenever they are far from each other I just set triangle position to mouse position, BUT when you hover your mouse too close (past some X distance) you can't get any closer (the TRIANGLE is then positioned at maximum that X distance in the direction from circle center to mouse point)
I'll add a picture and hopefully you can get what I mean.
https://dl.dropboxusercontent.com/u/23334107/help2.png
Steps:
1. Calculate the distance between the cursor and the center of the circle. If it is more than the 'limit' then set the triangle's position to the cursor's position and skip to step 4.
2. Obtain the angle formed between the center of the circle and the cursor.
3. Calculate the new Cartesian coordinates (x, y) of the triangle based of off the polar coordinates we have now (angle and radius). The radius will be set to the limit of the circle before we calculate x and y, because we want the triangle to be prevented from entering this limit.
4. Rotate the image of the triangle to 1.5708-angle where angle was found in step 2. (1.5708, or pi/2, in radians is equivalent to 90°)
Details:
1. The distance between two points (x1, y1) and (x2, y2) is sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2))
2. The angle (in radians) can be calculated with
double angle = Math.atan2(circleY-cursorY, cursorX-circleX);
The seemingly mistaken difference in order of circleY-cursorY and cursorX-circleX is an artefact of the coordinate system in most programming languages. (The y coordinate increases downwards instead of upwards, as it does in mathematics, while the x coordinate increases in concord with math - to the right.)
3. To convert polar coordinates to Cartesian coordinates use these conversions:
triangle.setX( cos(angle)*limit );
triangle.setY( sin(angle)*limit );
where limit is the distance you want the triangle to remain from the circle.
4. In order to get your triangle to 'face' the circle (as you illustrated), you have to rotate it using the libgdx Sprite function setRotation. It will rotate around the point set with setOrigin.
Now, you have to rotate by 1.5708-angle – this is because of further differences between angles in mathematics and angles in programming! The atan2 function returns the angle as measured mathematically, with 0° at three o'clock and increasing counterclockwise. The setRotation function (as far as I can tell) has 0° at twelve o'clock and increases clockwise. Also, we have to convert from radians to degrees. In short, this should work, but I haven't tested it:
triangle.setRotation(Math.toDegrees(1.4708-angle));
Hope this helps!
This is related to the arc drawn by HTML5 canvas "arcTo" function. I need to calculate the two tangent points of a circle with the radius R and two lines given by three points Q(x0,y0), P(x1,y1) and R(x2,y2).
The sketch explains the problem more. I need to find the tangent points A(xa,ya) and B(xb,yb). Note that the center of the circle is not given. Please help.
This is a question of solving a triangle with 2 known angles and one known side. Label the centre of the circle C, then the side you know is BC (or AC if you want). Angle PBC (CAP) is a right angle. The line CP bisects the angle RPQ.
Not all such triangles have a solution.
Given that:
The shape is a regular polygon in 3D space
The start point (the end of one arbitrary vertex of the shape) is known
the point in the middle of the shape (not on an edge - equidistant from all corners) is known
the angle at each corner (((numEdges-2)*PI)/numEdges), the radius of the shape (distance from a corner to the midpoint = sqrt(dx^2 + dy^2 + dz^2)), and the length of each edge (radius*2*sin(pi/numEdges)) can be calculated.
Given all this information, is it possible to fill in the blanks, if you like, and work out the rest of the start/endpoints for each vertex of the shape?
I can sort of see the beginnings of the logic in 2D, but in 3D i'm lost.
I'm thinking it can't be done, since your knowns do not uniquely identify your polygon. The points you do know define a unique line, but I can provide infinitely many congruent polygons with the same vertex and center, all rotations of one another about this line.