Calculate field of view of simple polygon from a point - math

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].

Related

Sliding on a plane

I have a plane (Point, normal) and a circle(point, radius).
The circle moves around and hits the plane.
The position of the circle is reset to the touchPoint with the plane.
So far, so good.
But how can i modify the velocity of the circle, so it only moves
tangential to the plane?
So if it bumbs in the plane, the part of the velocity-vector which is
responsible for bumbing in the plane is consumed.
So, in the next step, it doesnt collide with the plane but can move on.
It "slides" on the plane.
Any ideas?
Since you give no code, I'll just state a few ideas without code.
The plane's definition of (Point, normal) is simpler if the normal vector is a unit vector (of length one). If it isn't, divide that vector by its length and it becomes a unit vector.
If the velocity of the circle is is given by a 3D Cartesian velocity vector, you can find the component of that velocity vector along the plane's unit normal vector by taking the dot product of those two vectors. The result is the directed size of the vector along the normal. You can then remove that component by multiplying the unit normal vector by that dot product, then subtracting that from the circle's velocity vector. The result of that subtraction is the circle's velocity along the plane. That apparently is what you wanted to find.
If you answer my questions in my comment under your question, I could show you some code in my current preferred language, Python 3.

Formula for calculating camera x,y,z position to force 3D point to appear at left side of the screen and rightmost position on the globe

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.

Vector direction equations

I have three vectors in 3D space, one is a light source, one is a ray and one is the point on a circle a ray hits. With this information, how can I work out the vector which points back at the light source from the point the ray hits the circle?
What you really have is two points (light source, circle intersection), and a vector between them, right? The vector is already implied by the two points -- it's the intersection coordinates minus light source coordinations. To reverse it, just negate all the coordinates of the vector!

Finding the endpoint of a vertex given startpoint of vertex and midpoint of shape

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.

Calculate point and circle segment collision

If I have calculated an intersection point between a line segment and a circle, how can I tell whether or not this intersection point lies on a segment of the circle?
I have the equations to tell whether or not a line segment intersects with the circle, and I also have the intersection point on that circle, but what I need to know is whether or not this collision point on the circle lies within the bounds of a specific arg segment of that circle. I have the end points of the arc segment, the circle's center & radius, and the point of collision.
Transform the intersection point into polar coordinates around the center and compare the angles.
As an alternative to Dario's idea (which should work as well), you can:
Calculate the distances between the intersection point and the endpoints of the arc (referred to as intdist1 and intdist2).
Calculate the distance between the endpoints of the arc (arcdist).
If the arc is less than half of the circle (covers less than 180 degrees), then you know if the point is in the arc if intdist1 and intdist2 are both less than arcdist.
Else, if the arc is greater than half the circle (covers more than 180 degrees), then you know if the point is in the arc if either intdist1 or intdist2 are greater than arcdist.
I'm guessing, since you haven't specified otherwise, that the arc between the endpoints goes the short way around. In that case, you don't need to worry about step 4 above.
The method fails though if you are using an arc that covers exactly 180 degrees of the circle. In that case you could break the 180 degrees arc into 90 degree arcs and check both of them I suppose.
Also, you can of course use the square of the distance for comparison of these distances to save yourself the square root. In addition, this method should be faster than calculating the angles because those involve using expensive inverse cosines.

Resources