I know that the curvature of a surface mesh is calculated using maximum (k1) and minimum (k2) values or so-called principal direction curvatures and then mean or Gaussian curvature are obtained.
I'm interested in curvature in a specific direction disregarding all other directions. I can obtain that if I sample the surface mesh, i.e., create cross-sections in that specific direction and then calculate the curvature of a curved line.
Is there a way to obtain curvature of a surface mesh in a specific direction?
Thank you for your help,
Marko
I know that the curvature of a surface mesh is calculated using maximum (k1) and minimum (k2) values or so-called principal direction curvatures and then mean or Gaussian curvature are obtained.
That is not exactly true, that the theoretical way to compute curvatures.
In the practice, mean (H) and Gaussian (G) curvatures on each vertex are computed first (using the Laplace-Beltrami of vertex positions, and adding angles around a vertex).
Then, the module of k1 and k2 are computed as 'k1 = H + sqrt(H^2-G)' and 'k2 = H - sqrt(H^2-G)'
Then the orientation of k1 and k2 by solving a least squares system of equations based on the Euler's formula over the curvature in the direction of the edges (which is known)
So you can use same approach: compute the curvature on the direction of each edge, and estimate the curvature in your desired direction by least squares.
Related
I am aiming to create the following (a directed arrow that connects two nodes) :
At the moment I have this (a quadratic bezier curve drawn from the center point of one node to the center of another):
(Note I have drawn the bezier above the nodes to show where it begins and ends)
I need a method - heuristic or otherwise - to calculate the point of intersection (circled in red, above) between the bezier curve and the node's (ellipse) circumference.
With this, I could calculate the angle between the node center and the point of intersection to draw the arrow head lines at the correct location and angle.
As a last resort, I could use the quadratic Bézier formula to generate a list of points that lie along the curve and also generate a list of points that lie on the circumference of the circle and use one of the two coordinates that have the least euclidian distance between each other as my intersection point. I'm hoping any answers can leverage geometry or whatever else to better solve it.
The general problem is uneasy as the intersection equation is quartic ((X(t)-Xc)² + (Y(t)-Yc)²=R²), where X and Y are quadratic polynomials). If you have a quartic solver handy you can use it but you'll have to select the right root.
A more reasonable approach is just to intersect the circle with the line segment between the control points. This is approximate but probably unnoticeable if the circle radius is small.
If you want more accuracy, perform one or two Newton's iterations from this point.
I am working with 2d surfaces embedded in 3d, with a discrete triangulation, and would like to calculate to principal curvature directions (eigenvectors of the curvature tensor). What I already know is summarised in the following post: How to get principal curvature of a given mesh?. Basically, they talk about fitting points to a quadratic polynomial, and then diagonalising the obtained quadratic form.
My question is, is there any faster way of finding the eigenvectors? I have to do this over and over again, hence the need for speed. It is easy to find out the eigenvalues of the curvature tensor, namely the Gaussian curvature (using angular deficits) and Mean curvature (using the Laplacian). Are there any existing simpler algorithms for the eigenvectors?
PS: I am working in Python, if that helps.
When you know an Eigenvalue e of a 3x3 matrix M, an Eigenvector is given by the cross product of two columns of M - e.I, which is low cost.
To avoid degenerate cases, it is better to choose the pair of columns that yields the longest vector, but this triples the cost.
To avoid quadratic surface fitting and estimate principal curvatures and directions in a point of triangular mesh, one can use vertex normals in addition to vertex coordinates as described in the article Estimating Curvatures and Their Derivatives on Triangle Meshes by Szymon Rusinkiewicz.
See this answer for more detail.
Some fast algorithms for working with polygons require the vertices of the polygon to have a specific order (clockwise or counter clockwise with respect to the polygon's plane normal).
To use those algorithms in 3D planar polygons (where all the points lie in a particular plane) one can perform a change of basis to a basis spanned by two orthogonal vectors that lie in the plane and a plane normal vector.
Is there a way to always find a basis in which the polygon vertices are always in counter clockwise (or clockwise) order?
Perhaps the best method is to compute the signed area of the polygon, and if it is negative, you know your vertices are clockwise; so reverse. If it is positive, your vertices are counterclockwise.
Search for "signed area of polygon." Here is one Mathematica link:
I would like to compute the mean and standard deviation of the areas of a set of Voronoi regions in 2D (if the region extends to infinity, I'll just clip it to the unit square).
However if possible I would like to do this computation from the Delaunay Triangulation without explicitly computing the Voronoi regions? Is this even possible, or is it better to just compute the Voronoi diagram explicitly?
In order to calculate the voronoi region of a vertex you need to iterate the 1-ring around it. Then the area of the region is defined as:
A = 1/8 * (sum for every adjacent vertex p_i) { (cot alpha_i + cot beta_i) * (p_i - c).Length² }
In the image you can see the whole voronoi region in light red. A part of it is shown in dark red. This is one of the parts accumulated by the sum. alpha and beta are the angles as visible in the image. c is the center vertex position. p_i is the opposite vertex_position. alpha, beta and p_i change while iterating. c keeps its value.
If you calculate those parts for every adjacent vertex, you get 8 times the area of the voronoi region.
I have a height map of NxN values.
I would like to find, given a point A (the red dot), whose x and y coordinates are given (and z is known from the data, so A is a vertex of the surface) a set of points that lie on the circumference of the circle with center in A and radius R that are a good approximation of a circular "cloth" (in grey) draped on the imaginary surface described by the data points.
The sampling, the reciprocal distances between the set of points that I am trying to find, doesn't need to be uniform, but still I would like to find at least all the points that are an intersection of the edges of the mesh with the circle at distance R from A.
How to find this set of points?
Is this a known problem?
(source: keplero.com)
-- edit
The assumption that Jan is using is right: the samples form a regular rectangular or square grid (in the X-Y plane) aligned with [0,0]. But I would like to take the displacement in the Z direction into account to compute the distance. you can see the height map as a terrain, and the algorithm I am looking for as the instructions to give to an explorer that, traveling just on paths of given latitude or longitude, mark the points that are at distance R from A. Walking distance, that is taking into account all the Z displacements done so far. The explorer climbs and go down in the valleys too.
The trivial algorithm for this would be something like this. We know that given R, the maximum displacement on the x and y axis corresponds to a completely flat surface. If there is no slope, the x,y points will all be in the bounding square Ax-R < x < Ax+r and Ay-R
At this point, it would start traveling to the close cells, since if the perimeter enters the edge of one cell of the grid, it also have to exit that cell.
I reckon this is going to be quite difficult to solve in an exact fashion, so I would suggest trying the straightforward approach of simulating the paths that your explorers would take on the surface.
Given your starting point A and a travel distance d, calculate a circle of points P on the XY plane that are d from A.
For each of the points p in P, intersect the line segment A-p with your grid so that you end up with a sequence of points where the explorer crosses from one grid square to the next, in the order that this would happen if the explorer were travelling from A. These points should then be given a z-coordinate by interpolation from your grid data.
You can thus advance through this point sequence and keep track of the distance travelled so far. Eventually the target distance will be reached - adjust p to be at this point.
P now contains the perimeter that you're looking for. Adjust the sample fidelity (size of P) according to your needs.
Just to clarify - You have a triangulated surface in 3d and, for a given starting vertex Vi in the mesh you would like to find the set of vertices U that are reachable via paths along the surface (i.e. geodesics) with length Li <= R.
One approach would be to transform this to a graph-based problem:
Form the weighted, undirected graph G(V,E), where V is the set of vertices in the triangulated surface mesh and E is the set of edges in this mesh. The edge weight should be the Euclidean (3d) length of each edge. This graph is a discrete distance map - the distance "along the surface" between each adjacent vertex in the mesh.
Run a variant of Dijkstra's algorithm from the starting vertex Vi, only expanding paths with length Li that satisfy the constraint Li <= R. The set of vertices visited U, will be those that can be reached by the shortest (geodesic) path with Li <= R.
The accuracy of this approach should be related to the resolution of the surface mesh - as long as the surface curvature within each element is not too high the Euclidean edge length should be a good approximation to the actual geodesic distance, if not, the surface mesh should be refined in that area.
Hope this helps.