Perpendicular offset to a surface (triangular mesh) - geometry

I need to make a perpendicular (not vertical) offset to a surface. The surface is represented as Triangular Irregular Network (TIN, MESH). The condition is that triangle before and after the offset should be parallel, i.e., slope/aspect should be preserved.
Could anyone point me to algorithms/articles/ or any clues?

Related

Algorithm to calculate and display a ribbon on a 3D triangle mesh

I am looking for an algorithm for the following problem:
Given:
A 3D triangle mesh. The mesh represents a part of the surface of the earth.
A polyline (a connected series of line segments) whose vertices are always on an edge or on a vertex of a triangle of the mesh. The polyline represents the centerline of a road on the surface of the earth.
I need to calculate and display the road i.e. add half of the road's width on each side of the center line, calculate the resulting vertices in the corresponding triangles of the mesh, fill the area of the road and outline the sides of the road.
What is the simplest and/or most effective strategy to do this? How do I store the data of the road most efficiently?
I see 2 options here:
render thick polyline with road texture
While rendering polyline you need TBN matrix so use
polyline tangent as tangent
surface normal as normal
binormal=tangent x normal
shift actual point p position to
p0=p+d*binormal
p1=p-d*binormal
and render textured line (p0,p1). This approach is not precise match to surface mesh so you need to disable depth or use some sort of blending. Also on sharp turns it could miss some parts of a curve (in that case you can render rectangle or disc instead of line.
create the mesh by shifting polyline to sides by half road size
This produces mesh accurate road fit, but due to your limitations the shape of the road can be very distorted without mesh re-triangulation in some cases. I see it like this:
for each segment of road cast 2 lines shifted by half of road size (green,brown)
find their intersection (aqua dots) with shared edge of mesh with the current road control point (red dot)
obtain the average point (magenta dot) from the intersections and use that as road mesh vertex. In case one of the point is outside shared mesh ignore it. In case both intersections are outside shared edge find closest intersection with different edge.
As you can see this can lead to serious road thickness distortions in some cases (big differences between intersection points, or one of the intersection points is outside surface mesh edge).
If you need accurate road thickness then use the intersection of the casted lines as a road control point instead. To make it possible either use blending or disabling Depth while rendering or add this point to mesh of the surface by re-triangulating the surface mesh. Of coarse such action will also affect the road mesh and you need to iterate few times ...
Another way is use of blended texture for road (like sprites) and compute the texture coordinate for the control points. If the road is too thick then thin it by shifting the texture coordinate ... To make this work you need to select the most far intersection point instead of average ... Compute the real half size of the road and from that compute texture coordinate.
If you get rid of the limitation (for road mesh) that road vertex points are at surface mesh segments or vertexes then you can simply use the intersection of shifted lines alone. That will get rid of the thickness artifacts and simplify things a lot.

How can I calculate the Z value of triangles?

I am trying to implement a Z-buffer (depth buffer) for a polygon rasterization algorithm. All of my polygons are triangles and I understand that three points (x,y,z) that make up a triangle also form a plane. If I have the (x,y,z) values of the verices, how would I calculate the depth of every position on the face of the triangle?
In OpenGl or WebGl a z-buffer is applied just after rasterization i.e. for each pixel, not for each vertex of a triangle. In this case you need to save z-value for each pixel and then just get a pixel this max z-value. This is done automatically in pipeline.
If you wanna calculate a z-buffer just for vertices you need your own algorithm. For example just getting max z-value of triangle's vertices and sort triangles by this value.
Also check this link for more info.

Projected points on the 2_sphere

I am doing a project on the TSP on the surface of the sphere. I would like to illustrate the method uniformly distributing points to the surface of the sphere, i.e. filling a cube with uniform (x,y,z) points with the restriction that x^2+y^2+z^2 > 1 and then dividing each radius vector by it's magnitude. I can plot the points along with the sphere but how do I go about specifying a radial vector to each point in gnuplot? Also, how does one specify a line to run through the points in their order? (The chosen path).

How are polygon "sleeves" called and how are they calculated?

When a polygon gets rotated it skips all possible rotations in between the current and the desired situation. Here are 3 images illustrating what I mean:
This is the current polygon:
Rotating it 45 degrees (in clockwise direction) would result in:
The current polygon rotated by 45 degrees in clockwise direction, with all possible situations in between would result in:
How are these "sleeves" (in-between situations) actually called, and how are these "complete polygons" calculated/approximated based on the current polygon and desired angle of rotation?
In the CAD industry, we would call this operation a 2d sweep, or a 2d planar sweep; in this case a 2d planar rotational sweep. (Not to be confused with a sweep line algorithm.) The resulting area would be the 2d swept area or 2d swept face, and the outline called the 2d swept boundary.
A couple of papers on the topic can be found here:
Polygonal boundary approximation for a 2D general sweep based on envelope and boolean operations (2000) (another link, and a direct PDF Link.)
Approximate General Sweep Boundary of a 2D Curved Object (1993).
Your case of a 2d rotational sweep is not as general as the cases considered in these papers. If you think about sweeping just a single curve -- a line or an arc, say -- then the boundary curves of the swept area in 2d will as follows. Imagine sweeping the curve in 3d, where the curve is simultaneously extruded along the axis of rotation as it is rotated around the axis. In that case, the boundaries of your 2d sweep would be the boundaries of the 3d swept surface projected back to 2d plus the 3d silhouettes of the swept surface projected back into 2d, taking the axis of rotation as the view vector for silhouette creation.
Computing silhouettes of general surfaces is nontrivial, but for a rotational sweep + extrusion along the axis of rotation the silhouettes will be traced out by points where the tangent of the swept curve is parallel to the direction of rotation -- i.e., perpendicular to the radius vector drawn out from the center of rotation. Thus an algorithm to compute your 2d area might look like:
For each edge segment of the area to be rotationally swept,
Split the edge where the tangent becomes parallel to the direction of rotation.
Exclude any degenerate curves -- arcs that are coaxial with the axis of rotation.
For each split edge segment, form a 2d area comprised of the start position of the curve, the end position of the curve, and the start and end points connected by arcs. Since we split at the silhouette points, there should be no self intersections.
Do a 2d boolean of the 2d area in its start position, its end position, and the swept areas created in the first steps.

Calculate size of a circle from arcs?

How can I calculate the size of a circle from a set of arcs?
Specifically, I have this SVG path definition which draws a circle, I'm looking to work out its size.
<path clip-path="url(#SVGID_2_)" fill="#99C44C" d="M334.293,56.846c0-4.782,3.88-8.659,8.665-8.659c4.78,0,8.66,3.877,8.66,8.659
c0,4.783-3.88,8.661-8.66,8.661C338.173,65.507,334.293,61.629,334.293,56.846"/>
For your information, the circle is drawn in the 'd' attribute. M334.293,56.846 moves to this x,y position, then the c commands are curves.
Curves:
Draws a cubic Bézier curve from the current point to (x,y) using (x1,y1) as the control point at the beginning of the curve and (x2,y2) as the control point at the end of the curve. C (uppercase) indicates that absolute coordinates will follow; c (lowercase) indicates that relative coordinates will follow.
relative curves
c0-4.782,3.88-8.659,8.665-8.659
c4.78,0,8.66,3.877,8.66,8.659
c0,4.783-3.88,8.661-8.66,8.661
absolute curve
C338.173,65.507,334.293,61.629,334.293,56.846
At this juncture you have two possibilites:
You can treat the bezier curve as a circle (which is, as commented, wrong; it's just really circle-looking). To calculate the area, determine the radius and use π * r^2 as usual.
If you want to calculate generally the area enclosed by a path element; that requires some moderate calculus, and is not for the faint of heart.

Resources