Reconstruct boundaries and compute length in Paraview - gradient

I have a set of points on the unit sphere and a corresponding set of values being equal, for simplicity, to 0 and 1. Thus I'm constructing the characteristic function of a set on the sphere. Typically, I have several such sets, which form a partition of the sphere. An example is given in the figure.
I was wondering if paraview can find boundaries between the cells and compute the length and the curvature of the boundaries.
I read in a paper that using gradient reconstruction the guys managed to find the curvature of such contours. I imagine that if the curvature can be found, the length should be somewhat simpler. If the answer to the above question is yes, where should I look for the corresponding documentation?

For points on the sphere if they are build based on great-circle distance principle, it means all lines connecting points are of a shortest distance and plane goes through sphere center. In such case angle could be computed as arccos of scalar product.
R = 1;
angle = arccos(x1*x2 + y1*y2 + z1*z2);
length = R*angle;
And parametric line from p1 to p2 could be build using slerp interpolation.
slerp(t) = sin((1.0-t)*angle)/sin(angle)*p1 + sin(t*angle)/sin(angle)*p2;
where t is in [0...1] range
In such case curvature is 1/R for all great circle lines. That would be first thing I would try - try to match actual boundaries with those made from great-circle approach. If they match, that's the answer
Links
https://en.wikipedia.org/wiki/Great_circle
https://en.wikipedia.org/wiki/Great-circle_distance
https://en.wikipedia.org/wiki/Slerp
UPDATE
In case of non-great arcs I would propose following modification. Build great arc plane which goes through sphere center and on intersection with surface makes great arc between the points. Fix axis as a line going through those two points. Start rotating great arc plane along above mentioned axis till you get the exactly your arc of circle connecting two points. At this moment you could get rotation angle, compute your circle plane position and radius r, curvature as 1/r etc

Related

Calculate an elliptical arc start and end angles given two vectors

I am working on a program which draws shapes based on a cgm file input. I am trying to draw elliptical arc and it gives the opening portion in terms of a start and end vector from the center of the arc. I need help calculating the angle to the vector so I can draw.
I have been trying to use the standard atan2(y/x) but then I found it is valid for circles and not ellipses.
This image gives an example of what I'm trying to do. I am looking for angles A and B.
edit: This is related to my other question here. (Also note, this question is based on the math behind my problem while the other question was for programming help with qt.)
The wiki page on ellipses kind of shows why the math isn't working but I'm not sure how to implement it.
The angles A and B you were drawing in your picture in fact have nothing to do with the ellipse.
Just calculate once the angle between the x-axis and the line from origin to point (75,50). This is given by arctan(50/75) = 33.69°. And by symmetry, it is the same as the angle to point (75, -50).
Then, by simple trigonometry, for angle A you get A = 360° - 33.69°, whereas for B you get B= 180° + 33.69°.
Considering A, this is the same information that is obtained by atan2(-50, 75). However, the result of atan2 is in (i) in radians and (ii) in the range [-pi, pi]. You could add 2*pi and express it in angles and you get the same result as above.

Converting an ellipse into a polyline

I currently have several ellipses. These are defined by a centre point, and then two vectors, one point to the minimum axis and other to the maximum axis.
However, for the program I'm creating I need to be able to deal with these shapes as a polyline. I'm fairly sure there must be formula for generating a set of points from the available data that I have, but I'm unsure how to go about doing it.
Does anyone have any ideas of how to go about this?
Thanks.
(Under assumption that both vectors that represent ellipse axes are parllel to coordinate axes)
If you have a radial ray emanating from the centre of ellipsis at angle angle, then that ray intersects the ellipse at point
x = x_half_axis * cos(angle);
y = y_half_axis * sin(angle);
where x_half_axis and y_half_axis age just the lengths (magnitudes) of your half-axis vectors.
So, just choose some sufficiently small angle step delta. Sweep around your centre point through the entire [0...2*Pi] range with that step, beginning with 0 angle, then delta angle, then 2 * delta angle and so on. For each angle value the coordinates of the ellipse point will be given by the above formulas. That way you will generate your polygonal representation of the ellipse.
If your delta is relatively large (few points on the ellipse) then it should be chosen carefully to make sure your "elliptical polygon" closes nicely: 2*Pi should split into a whole number of delta steps. Albeit for small delta values it does not matter as much.
If your minimum-maximum axis vectors are not parallel to coordinate axes, your can still use the above approach and then transform the resultant points to the proper final position by applying the corresponding rotation transformation.
Fixed-delta angle stepping has some disadvantages though. It generates a denser sequence of polygonal points near the miminum axis of the ellipse (where the curvature is smaller) and a sparser sequence of points near the maximum axis (where the curvature is greater). This is actually the opposite of the desirable behavior: it is better to have higher point density in the regions of higher curvature.
If that is an issue for you, then you can update the algorithm to make it use variadic stepping. The angle delta should gradually decrease as we approach the maximum axis and increase as we approach the minimum axis.
Assuming the center at (Xc,Yc) and the axis vectors (Xm,Ym), (XM,YM) (these two should be orthogonal), the formula is
X = XM cos(t) + Xm sin(t) + Xc
Y = YM cos(t) + Ym sin(t) + Yc
with t in [0,2Pi].
To get a efficient distribution of the endpoints on the outline, I recommend to use the maximum deviation criterion applied recursively: to draw the arc corresponding to the range [t0,t2], try the midpoint value t1=(t0+t2)/2. If the corresponding points are such that the distance of P1 to the line P0P2 is below a constant threshold (such as one pixel), you can approximate the arc by the segment P0P1. Otherwise, repeat the operation for the arcs [t0,t1] and [t1,t2].
Preorder recursion allows you to emit the polyline vertexes in sequence.

Finding angle between two points in an image using OpenCV

I'm trying to find the angle between two points in an image. The angle is with reference to the centre line of the camera.
In this image the center point is along the center of the image (assumption, I still have to figure out how to actually calculate it) and I want to find the angle between the line connecting point 1 and the camera center and the line connecting the desired point and the camera center
Now I want to know two things about finding the angle
- Is it possible to know the angle if the distance is not known exactly (but can be estimated by a human at run time) Assuming both points lie in the same plane in the image
- If the points are not in the same plane, how should I handle the angle calculation?
It can be achieved by inner product.
If you are talking in 3D space so your x(vector) and y(vector) should be in the form [a,b,f](a and b are points) where f is the distance of image plane from the camera center and a and a are the corresponding coordinates in the camera frame.
If it is in 2D space, so you have to specify the origin of your frame and find a and b according to that frame and your x and y vectors are in the form [a,b].
It can be found by using this formula:
Angle between two rays
K is the camera matrix. x1 and x2 are the image points given in homogeneous form like [u,v,1] and d1 and d2 are the corresponding 3D points.
See Richard Hartley, Australian National University, Canberra, Andrew Zisserman, University of Oxford: “Multiple View Geometry in Computer Vision”, 2nd edition, p. 209 for more details.
Inverting the camera matrix is quite simple. See
https://www.imatest.com/support/docs/pre-5-2/geometric-calibration-deprecated/projective-camera/ for more details.

How can I tessellate the boundary of a point cloud?

I have a cloud of vertices. I'd like to tessellate a "shell" around the vertex cloud using only vertices in the cloud, such that the shell conforms roughly to the shape of the vertex cloud.
Is there an easy way to do this? I figured I could spherically parameterize the point cloud and then "walk" the outermost vertices to tessellate the cloud, but I'm not sure this will work.
I suppose it's acceptable to add vertices, but the general shape of the "shell" should match the shape of the vertex cloud.
I have an algorithm for you that works in the 2D case. It is tricky, but do-able to generalize it to 3D space. The basic idea is to start with a minimum-surface (triangle in 2D or tetrahedron in 3D), and split each edge (face) as you traverse the array of points.
2D algorithm (python. FULL SOURCE/DEMO HERE: http://pastebin.com/jmwUt3ES)
edit: this demo is fun to watch: http://pastebin.com/K0WpMyA3
def surface(pts):
center = pt_center(pts)
tx = -center[0]
ty = -center[1]
pts = translate_pts(pts, (tx, ty))
# tricky part: initialization
# initialize edges such that you have a triangle with the origin inside of it
# in 3D, this will be a tetrahedron.
ptA, ptB, ptC = get_center_triangle(pts)
print ptA, ptB, ptC
# tracking edges we've already included (triangles in 3D)
edges = [(ptA, ptB), (ptB, ptC), (ptC, ptA)]
# loop over all other points
pts.remove(ptA)
pts.remove(ptB)
pts.remove(ptC)
for pt in pts:
ptA = (0,0)
ptB = (0,0)
# find the edge that this point will be splitting
for (ptA, ptB) in edges:
if crossz(ptA, pt) > 0 and crossz(pt, ptB) > 0:
break
edges.remove((ptA, ptB))
edges.append((ptA, pt))
edges.append((pt, ptB))
# translate everything back
edges = [((ptA[0] - tx, ptA[1] - ty), (ptB[0] - tx, ptB[1] - ty)) for (ptA, ptB) in edges]
return edges
RESULT:
Generalizing to 3D
instead of edges, you have triangles.
initialization is a tetrahedron around the origin
finding the splitting face involves projecting a triangle, and checking if the pt is interior to that triangle
splitting involves adding 3 new faces whereas 2D was 2 new edges
need to be careful about orientation of the face (in my 2D code, I was easily able to guarantee A->B would be CCW orientation)
Depending on the size of your point cloud and speed requirements, you may need to be more clever about data structures for faster add/remove.
3D convex hull (convex hull algorithm for 3d surface z = f(x, y)).
Then for points on each of the largest faces search for the closest point on the cloud and re-triangulate that face to include the point.
Repeat until it is "close enough" based on largest distance from the nearest cloud point for each of the remaining faces, or on the size (length/are?) of the largest remaining face
I would think about a "metric" function f(x, y, z) that returns a scalar value for an arbitrary point in 3D space. This function should be constructed in a way to consider whether a given point (x, y, z) is "inside" or "outside" of a cloud. For instance, this can be a length of an average vector from (x, y, z) to every point in a cloud, or it can be a number of cloud points within a certain vicinity of (x, y, z). Choice of the function will affect the final result.
Having this f(x, y, z) you use the marching cubes algorithm to perform tessellation, basically constructing an iso-surface of f(x, y, z) for a certain value.
You should try 3d Delaunay Triangulation. This will tessellate the point cloud, while making sure that the tri mesh only has vertices from the point cloud. CGAL has a two implementations of triangulating the point cloud - delaunay and regular. The regular version triangulates the points using the idea described here.
You can use their implementation, if you're using C++. If not, you can still look at their code to implement it yourself (it is pretty complex though).
Sounds like you are looking for the "concave hull". This delivers a "reasonable" boundary around a set of points, "reasonable" meaning fitting the set up to a given tolerance. It is not a geometric property, like the convex hull, but a good approximation for a lot of "real world" problems, like finding a closely fitting boundary around a city.
You can find an implementation in the Point Cloud Library.

Drawing sections of a Bezier curve

I was writing code to approximate a quarter ellipse to a Bézier curve.
Now having done that, I am encountering trouble drawing sections of this curve.
I need some help choosing the control points.
Initially, I had taken the ratio of distance of control point to distance of start of curve as 0.51.
Edited:
pseudo code
import cairo [...]
ctx.moveto(0,y1)
ctx.curveto(0,y1/2,x1/2,0,x1,0)
This will result in an approximately elliptical curve from (0,y1) to (x1,0) with the ellipse center at (x1,y1).
Notice the parametric angle swept is pi/2.
If suppose I wish to draw it in sections more like a dashed pattern, then how do I do it? For example, from t = pi/6 to t = pi/3? How do I choose the control points?
To approximate a circle quarter using a single cubic arc what is normally done is making the middle point being exactly on the circle and using tangent starting and ending directions.
This is not formally the "best" approximation in any reasonable metric but is very easy to compute... for example the magic number for a circle quarter is 0.5522847498. See this page for some detail...
To draw an ellipse arc instead you can just stretch the control points of the circular arc (once again not something that would qualify mathematically as "best approximation").
The generic angle case
The best arc for a generic angle under this definition (i.e. having the middle point of the bezier being on the middle of the arc) can be computed using the following method...
1. The maximum height of a symmetrical cubic bezier arc is 3/4 H where H is the height of the control point
This should be clear considering how the middle point of a bezier cubic is computed with the De Casteljau's algorithm or my answer about explicit computation of a bezier curve; see also the following picture:
y_mid = ((0+H)/2 + (H+H)/2) / 2 = 3/4 H
2. The angle at the center for a circle cord is twice the angle at the base
See any elementary geometry text for a proof.
Finally naming L the distance between the extremes, S the (unknown) control arm of the symmetric Bezier, 2*alpha the angle of circle to approximate we can compute that
3. S = L (2/3) (1-cos(alpha)) / (sin(alpha)**2)
This follows from the above equations and from some computation; see the following picture for a description.
I think you should use the control points of the whole curve. One way to do this would be to determine a parametric equation version of bezier -- see How to find the mathematical function defining a bezier curve.
Next, figure out what part of 0 <= t <= 1 in the parametric equation the section defined by the angle p1/6 <= ө <= pi/3 represents and then run that range of values through it.
There are ways of computing each point along some kinds of parametrically-defined curves which is applicable here and ought to make the drawing of a dashed pattern fairly straight forward and fast.
This Link has a good explanation of Bezier Curves. It goes over the basic math principles, and also provides sample code.
Because Bezier Curves are typically implemented using a parametric equation, you can just draw line segments between each sample point. Your step size will affect the smoothness of your curve if you draw them in this way.