I'm working on a 3D mapping application, and I've got to do some work with things like figuring out the visible region of a sphere (Earth) from a given point in space for things like clipping mapped regions and such.
Several things get easier if I can project the outline of Earth into screen space, clip polygons there, and then project back to the surface of the Earth (lat/lon), but I'm lost as to how to do that.
Is there a reasonable way to compute the outline of a sphere after perspective projection, and then a reasonable way to project things back onto the sphere?
You can clip the polygons in 3D. The silhouette of the sphere - back-projected into 3D - will always be a circle on a plane. Perspective projection does not change that. Thus, you can clip all polygons at the plane.
Calculating the plane is not too hard. If you consider the sphere's center the origin, then the plane could be represented in normal form as:
dot(n, x) = d
n is the normal. This one is easy. It is just the unit direction vector from the sphere center to the observer.
d is the distance from the sphere center. This is a bit harder but not too hard. If l is the distance of the observer to the sphere center and r is the sphere radius, then
d = r^2 / l
This is the plane which you can use to clip your polygons in 3D. If you need the radius of the circle on it, you can use the following formula:
r_c = r / sqrt(1 - r^2/(l-d)^2)
Let us take a point on a sphere in spherical coordinates (cos(u)sin(v),sin(u)sin(v),cos(v)) and an arbitrary projection center (x,y,z).
We express that a projecting line is tangent to the sphere by the perpendicularity condition of the direction of the line and the vector from the origin of the sphere:
(x-cos(u)sin(v))cos(u)sin(v) + (y-sin(u)sinv))sin(u)sin(v) + (z-cos(v)) cos(v) = 0
This simplifies to
x cos(u)sin(v) + y sin(u)sin(v) + z cos(v) = 1
which is a curve in the longitude/latitude coordinates. You can solve u as a function of v or conversely.
Related
Suppose I have a bullet as shown below where the measurements are in units of bullet diameters (this thing is 3 dimensional, so imagine rotating it about the x axis here)
If this bullet were to be tilted upwards by an angle θ, how could I numerically find its projected area?
I'm trying to find the area that such a bullet would present to the air as it moves through it and so if it is not tilted away from the direction of motion this area is simply a circle. I know for small tilts, it will simply present the projected area of a cylinder but I am unsure about how to deal with tilts large enough that one needs to care about the tip of the bullet for purposes of finding the area. Anyone have ideas about how to deal with this?
Hint:
The boundary curves of the bullet are the apparent outline of the inner surface of a self-intersecting torus. They can be found by expressing that the normal vector is parallel to the projection plane.
With z being the axis of the bullet, the parametric equation of the surface is
x= (R + r sinφ) cosΘ
y= (R + r sinφ) sinΘ
z= r cosφ
and the normal is obtained by setting R=0,
x= r sinφ cosΘ
y= r sinφ sinΘ
z= r cosφ
Now for some projection plane with a normal in direction (cosα, 0, sinα), the outline is such that
r sinφ cosΘ cosα + r cosφ sinα = 0.
From this you can draw Θ as a function of φ or conversely and construct points along the curve.
When α increases, the tip of the bullet starts entering the ellipse resulting from the projection of the basis of the cylindre. This ellipse corresponds to the angle φ such that z=0.
The surface is known as a lemon shape: http://mathworld.wolfram.com/Lemon.html
I'm trying to generate a mesh from a sphere of radius r. My goal is to create a UV sphere such that every point on the polyhedron has distance from the sphere smaller than tol.
The following code creates a grid of points on the sphere. How can I compute parallels_count and meridians_count so that all the point of the mesh are within tolerance?
for j in parallels_count:
parallel = PI * (j+1) / parallels_count
for i in meridians_count:
meridian = 2.0 * PI * i / meridians_count
return spherical_to_cartesian(meridian, parallel)
The code comes from here, and this is a picture of the UV sphere:
The distance between each face of the mesh and the sphere will be maximum around the center of the face.
So, for the distance between a face and the sphere to be smaller than tol it is not sufficient that the distances between the edges of the face and the corresponding circumferences are smaller than tol.
This picture is out of context but helps me explaining what I mean.
the biggest distance between points is on equator so use circle circumference to obtain angular step if I am not mistaken it should be...
dangle = tol/r; //[rad]
where r is sphere radius in the same units as tol you can use smaller step to be sure like dangle*=0.75; use this for both parallel and meridian angles.
If you want your counts instead then try:
meridians_count = (2.0*PI*r/tol)+1; // ceil or +1 just to be sure
parallels_count = 0.5*meridians_count;
It is still early here so I hope I did not make any silly math mistake (the easiest stuff is the worst for silly bugs).
Also take a look at few related QA's of mine:
Applying map of the earth texture a Sphere
Make a sphere with equidistant vertices
Sphere triangulation
[Edit1] well your new definition of tol changes everything
I see it like this:
sin(da/2) = (r-tol)/r
da = 2.0*asin((r-tol)/r)
If you convert to sphericalsurface than max difference is in center of uv grid cell which represents sqrt(2)*dadiagonal so try to use:
da = sqrt(2.0)*asin((r-tol)/r)
so your angle step should be a bit smaller than that ...
I need to find 4 points in Latitude/Longitude format surrounding a given center point and a resulting algorithm (if possible).
Known information:
Equal distances for each "bin" from center of point (Radar) outward.
Example = .54 nautical miles.
1 Degree beam width.
Center point of the "bin"
This image is in Polar coordinates (I think this is similar to Radial coordinates???):
I need to convert from Polar/Radial to Cartesian and I should be able to do that with this formula.
x = r × cos( θ )
y = r × sin( θ )
So now all I need to do is find the "bin" outline coordinates (4 corners) so I can draw a polygon in a Cartesian coordinate space.
I'm using Delphi/Pascal for coding, but I might be able to convert other languages if you have a sample algorithm.
Thanks for any suggestions or sample algorithms.
Regards,
Bryan
You need to convert everything to the same coordinate system and then impose the distance criteria as follows:
Convert your center point from geographic coordinates to polar coordinates to yield (rC, θC)
Convert your center point from polar to Cartesian coordinates using your equations yielding (xC, yC)
The corner points on the right side of the center points (xR, yR) satisfy the equation
(xR - xC)2 + (yR - yC)2 = D2
[rRcos(θC+0.5o) - xC]2 + [rRsin(θC+0.5o) - yC]2 = D2
where D=distance between the center point and corner points
Everything is known in the above equation except rR. This should yield a quadratic equation with two solutions which you can easily solve. Those are your two corner points on the right side.
Repeat step 3 with angle θC-0.5o to get the corner points on the left side.
If i have a point (x,y,z) how to project it on to a sphere(x0,y0,z0,radius) (on its surface).
My input will be the coordinates of point and sphere.
The output should be the coordinates of the projected point on sphere.
Just convert from cartesian to spherical coordinates?
For the simplest projection (along the line connecting the point to the center of the sphere):
Write the point in a coordinate system centered at the center of the sphere (x0,y0,z0):
P = (x',y',z') = (x - x0, y - y0, z - z0)
Compute the length of this vector:
|P| = sqrt(x'^2 + y'^2 + z'^2)
Scale the vector so that it has length equal to the radius of the sphere:
Q = (radius/|P|)*P
And change back to your original coordinate system to get the projection:
R = Q + (x0,y0,z0)
Basically you want to construct a line going through the spheres centre and the point. Then you intersect this line with the sphere and you have your projection point.
In greater detail:
Let p be the point, s the sphere's centre and r the radius then x = s + r*(p-s)/(norm(p-s)) where x is the point you are looking for. The implementation is left to you.
I agree that the spherical coordinate approach will work as well but is computationally more demanding. In the above formula the only non-trivial operation is the square root for the norm.
It works if you set the coordinates of the center of the sphere as origin of the system (x0, y0, z0). So you will have the coordinates of the point referred to that origin (Xp', Yp', Zp'), and converting the coordinates to polar, you discard the radius (distance between the center of the sphere and the point) and the angles will define the projection.
I have gone through all available study resources in the internet as much as possible, which are in form of simple equations, vectors or trigonometric equations.
I couldn't find the way of doing following thing:
Assuming Y is up in a 3D world.
I need to draw two 2D trajectories orthogonally (not the projections) for a 3D trajectory, say XY-plane for side view of the trajectory w.r.t. the trajectory itself and XZ-plane for top view for the same.
I have all the 3D points of the 3D trajectory, initial velocity, both the angles can be calculated by vector mathematics.
How should I proceed further?
refer:
Below a curve in different angles, which can loose its significance if projected along XY-plane. All I want is to convert the red curve along itself, the green curve along green curve and so on. and further how would I map side view to a plane. Top view is comparatively easy and done just by taking X and Z ordinates of each points.
I mean this the requirement. :)
I don't think I understand the question, but I'll answer my interpretation anyway.
You have a 3D trajectory described by a sequence of points p0, ..., pN. We are given an angle v for a plane P parallel to the Y-axis, and wish to compute the 2D coordinates (di, hi) of the points pi projected onto that plane, where hi is the height coordinate in the direction Y and di is the distance coordinate in the direction v. Assume p0 = (0, 0, 0) or else subtract p0 from all vectors.
Let pi = (xi, yi, zi). The height coordinate is hi = yi. Assume the angle v is given relative to the Z-axis. The vector for the direction v is then r = (sin(v), 0, cos(v)), and the distance coordinates becomes di = dot(pi, r).