Given this simple setup:
Node Tree
Viewport Preview
How can I align the planes instances such that the y axis of each plane is parallel to the curve, and the x axis of the planes are parallel to the ground plane (x and Y axis)?
I've tried various combinations with "Align Eular to Vector" node, but as soon as the curve does not face a specific axis the planes get tilted and the alignment to ground plane is lost.
any suggestions?
So after some research I found a solution to my own question. I'm posting it in case anyone else needs to find this out.
Note that I'm not a mathematician and there might be a shorter solution (or specific nodes that I'm not aware of that can perform some of the steps). Also note that this is a solution for instances on a straight line which is what I was aiming for, I didn't test this setup on a curved line but my guess is that it will not work.
For that you'll need to perform step 3 for every point or something like that.
Ok here we go:
Generate instances on a line with the instance on point node.
Auto orient the instances on the z axis with the align Euler to vector node based on the normal of the line.
Calculate a vector between 2 points on the line (which point is not important since the line is straight but the order of the subtraction does!). To calculate the vector from point 1 to point 2 you'll have to subtract point 1 from point 2 (like so: point 2 - point 1).
Calculate the angle between the new vector and the vector of the ground plane [0,0,1]. to do that use this formula:
θ = arccosine ( dot product/ ( length(v1) * length(v2) ) ).
Calculate the complementary angle which is 90 degrees - θ
*** convert 90 to radians of course
rotate the instances on x axis by the result value.
Node Tree
Result
If there is a shorter/easier solution, let me know.
I am trying to draw a star on a sphere. To determine the points belonging to the star I need to count the number of halfspaces that the points on the sphere belong to out of the 5 halfspaces defined by alternating points of the regular pentagon drawn on the x-y plane. My problem is determining the equations of those planes. I know 2 points, 2 alternating points of hexagons: (v0, v2), (v0, v3), (v1, v3), (v1, v4), (v2, v4). Assuming all planes are parallel to the z-axis, it seems to me intuitively this is enough info to find the plane equation, but my math is a little rusty and cannot do it. Appreciate any leads of how to calculate the equations or pointing out the flaw in my assumption...
If you're going to draw a star an a sphere, it will probably look better if the arcs are geodesics. That makes it easier for you, since the planes that define those arcs (by intersecting the sphere) will then all pass through the sphere's center.
Finding those planes is easy, too. You just take the cross product of the vectors from the center to any two points to find the normal. If the sphere's center is at (0,0,0), you don't need anything else.
My app captures the shape of a room by having the user point a camera at floor corners, and then doing a bunch of math, eventually ending up with a polygon.
The assumption is that the walls are straight (not curved). The majority of the corners are formed by walls at right angles to each other, but in some cases might not be.
Depending on how accurately the user points the camera, the (x,y) coordinates I derive for the corner might be beyond the actual corner, or in front of the actual camera, or, less likely, to the left or right. Obviously, in this case, when I connect the dots, I get weird parallelogram or rhomboid shapes. See example.
I am looking for a program or algorithm to normalize or regularize these shapes, provided we know which corners are supposed to be right angles.
My initial attempt involved finding segments which had angles which were "close" to each other, adjust them all to the same angle, and then recalculate the vertices. However, this algorithm proved to be unstable.
My current thinking is to find angles which are most obtuse (as would be caused by a point mistakenly placed beyond the actual corner), or most acute (as would be caused by a point mistakenly placed in front of the actual corner), and find the corner point which would make it a right angle. The problem, however, is that such as adjustment could have side-effects on other corners, such as making them even further away from right angles. I sense I need some kind of algorithm which takes all the information and optimizes/solves it at once--is this a kind of linear programming problem?--but I am stuck.
There is not a unique solution.
For example, take the perpendicular from the middle point of an edge to the two neighboring edges. This will give you two new corners.
Or take the perpendicular from the end point of an edge to other edges.
Or compute the average of angles in the end points of an edge. Use this average and the middle point of the edge to compute new corners.
Or...
To get the most faithful compliance, capture (or calculate) distances from each corner to the other three. Build triangles with those distances. Then use the average of the coordinates you compute for a corner from 2 or 3 triangles.
Resulting angles will not be exactly 90 degrees, but the polygon will represent the room fairly.
Standard convex hull algorithms will not work with (longitude, latitude)-points, because standard algorithms assume you want the hull of a set of Cartesian points. Latitude-longitude points are not Cartesian, because longitude "wraps around" at the anti-meridian (+/- 180 degrees). I.e., two degrees east of longitude 179 is -179.
So if your set of points happens to straddle the anti-meridian, you will compute spurious hulls that stretch all the way around the world incorrectly.
Any suggestions for tricks I could apply with a standard convex hull algorithm to correct for this, or pointers to proper "geospherical" hull algorithms?
Now that I think on it, there are more interesting cases to consider than straddling the anti-merdian. Consider a "band" of points that encircle the earth -- its convex hull would have no east/west bounds. Or even further, what is the convex hull of {(0,0), (0, 90), (0, -90), (90, 0), (-90, 0), (180, 0)}? -- it would seem to contain the entire surface of the earth, so which points are on its perimeter?
Standard convex hull algorithms are not defeated by the wrapping-around of the coordinates on the surface of the Earth but by a more fundamental problem. The surface of a sphere (let's forget the not-quite-sphericity of the Earth) is not a Euclidean space so Euclidean geometry doesn't work, and convex hull routines which assume that the underlying space is Euclidean (show me one which doesn't, please) won't work.
The surface of the sphere conforms to the concepts of an elliptic geometry where lines are great circles and antipodal points are considered the same point. You've already started to experience the issues arising from trying to apply a Euclidean concept of convexity to an elliptic space.
One approach open to you would be to adopt the definitions of geodesic convexity and implement a geodesic convex hull routine. That looks quite hairy. And it may not produce results which conform to your (generally Euclidean) expectations. In many cases, for 3 arbitrary points, the convex hull turns out to be the entire surface of the sphere.
Another approach, one adopted by navigators and cartographers through the ages, would be to project part of the surface of the sphere (a part containing all your points) into Euclidean space (which is the subject of map projections and I won't bother you with references to the extensive literature thereon) and to figure out the convex hull of the projected points. Project the area you are interested in onto the plane and adjust the coordinates so that they do not wrap around; for example, if you were interested in France you might adjust all longitudes by adding 30deg so that the whole country was coordinated by +ve numbers.
While I'm writing, the idea proposed in #Li-aung Yip's answer, of using a 3D convex hull algorithm, strikes me as misguided. The 3D convex hull of the set of surface points will include points, edges and faces which lie inside the sphere. These literally do not exist on the 2D surface of the sphere and only change your difficulties from wrestling with the not-quite-right concept in 2D to quite-wrong in 3D. Further, I learned from the Wikipedia article I referenced that a closed hemisphere (ie one which includes its 'equator') is not convex in the geometry of the surface of the sphere.
Instead of considering your data as latitude-longitude data, could you instead consider it in 3D space and apply a 3D convex hull algorithm? You may be able to then find the 2D convex hull you desire by analysing the 3D convex hull.
This returns you to well-travelled algorithms for cartesian convex hulls (albeit in three dimensions) and has no issues with wrap around of the coordinates.
Alternately, there's this paper: Computing the Convex Hull of a Simple Polygon on the Sphere (1996) which seems to deal with some of the same issues that you're dealing with (coordinate wrap-around, etc.)
If all your points are within a hemisphere (that is, if you can find a cut plane through the center of the Earth that puts them all on one side), then you can do a central a.k.a. gnomic a.k.a. gnomonic projection from the center of the Earth to a plane parallel to the cut plane. Then all great circles become straight lines in the projection, and so a convex hull in the projection will map back to a correct convex hull on the Earth. You can see how wrong lat/lon points are by looking at the latitude lines in the "Gnomonic Projection" section here (notice that the longitude lines remain straight).
(Treating the Earth as a sphere still isn't quite right, but it's a good second approximation. I don't think points on a true least-distance path across a more realistic Earth (say WGS84) generally lie on a plane through the center. Maybe pretending they do gives you a better approximation than what you get with a sphere.)
FutureNerd:
You are absolutely correct. I had to solve the exact same problem as Maxy-B for my application. As a first iteration, I just treated (lng,lat) as (x,y) and ran a standard 2D algorithm. This worked fine as long as nobody looked too close, because all my data were in the contiguous U.S. As a second iteration, though, I used your approach and proved the concept.
The points MUST be in the same hemisphere. As it turns out, choosing this hemisphere is non-trivial (it's not just the points' center, as I had initially guessed.) To illustrate, consider the following four points: (0,0), (-60,0), (+60,0) along the equator, and (0,90) the north pole. However you choose to define "center", their center lies on the north pole by symmetry and all four points are in the Northern Hemisphere. However, consider replacing the fourth point with, say (-19, 64) iceland. Now their center is NOT on the north pole, but asymmetrically drawn toward iceland. However, all four points are still in the Northern Hemisphere. Further, the Northern Hemisphere, as uniquely defined by the North Pole, is the ONLY hemisphere they share. So calculating this "pole" becomes algorithmic, not algebraic.
See my repository for the Python code:
https://github.com/VictorDavis/GeoConvexHull
This question has been answered a while ago, but I would like to sum up the results of my research.
The spherical convex hull is basically defined only for non-antipodal points. Supposing all the points are on the same hemisphere, you can compute their convex hull in two main ways:
Project the points to a plane using gnomonic/central projection and apply a planar convex hull algorithm. See Lin-Lin Chen, T. C. Woo, "Computational Geometry on the Sphere With Application to Automated Machining" (1992). If the points are on a known hemisphere, you can hard-code on which plane to project the points unto.
Adapt planar convex hull algorithms to the sphere. See C. Grima and A. Marquez, "Computational Geometry on Surfaces: Performing Computational Geometry on the Cylinder, the Sphere, the Torus, and the Cone", Springer (2002). This reference seems to give a similar method to the abstract referenced by Li-aung Yip above.
For reference, in Python I am working on an implementation of my own, which currently works only for points on the Northern hemisphere.
See also this question on Math Overflow.
All edges of a spherical convex hull can be viewed/treated as great circles (seminally, all edges of a convex hull in euclidean space can be treated as lines (rather than a line segment)). Each one of these great circles cuts the sphere into two hemispheres. You could thus conceive each great circle as a constraint. A point that is within the convex hull will be on each of the hemispheres defined by each constraint.
Each edge of the original polygon is a candidate edge of the convex hull. To verify if it is indeed an edge of the convex hull, you'd simply need to verify if all nodes of the polygon are on the hemisphere defined by the great circle that goes through the two nodes of the edge in question. However, we'd still need to create new edges that surpass the concave nodes of the polygon.
But lets rather shortcut / brute-forces this:
Draw a great circle between every pair of nodes in the polygon. Do this in both directions (i.e. the great circle connecting A to B and the great circle connecting B to A). For a polygon with N nodes, you will thus end up with N^2 great circle. Each one of these great circles is a candidate constraint (i.e. a candidate edge of the convex polygon). Some of these great circles will overlap with the edges of the original polygon, but most won't. Now, remember again: each great circle is a constraint that constrains the sphere to one hemisphere. Now verify if all nodes of the original polygon satisfy the constraint (i.e. if all nodes are on the hemisphere defined by the great circle). If yes, then this great circle is an edge of the convex hull. If, however a single node of the original polygon does not satisfy the constraint, then it isn't and you can discard this great circle.
The beauty of this is that once you converted your latitudes and longitudes into cartesian vectors pointing onto the unit sphere, it really just requires dot products and cross products
- You find the great circle that passes through two points on a sphere by its cross product
- A point is on the hemisphere defined by a great circle if the dot product of the great circle and the point is greater (or equal) to 0.
So even for polygons with a large number of edges, this brute force method should work just fine.
Suppose you have an arbitrary closed curve (endpoint returns relatively close to first point) generated through a bunch of dataset coordinates, how do you find the centerpoint and the boundaries of the resulting shape?
There are two possible interpretations (perhaps more) for your question.
The first one was already addressed by #AakashM, and we may depict it in the following plot:
Where the red square is the "boundary".
I'll cite #AakashM here, because I understand his remark VERY important:"(I note that for you to have a closed curve, you need the endpoint to be not just 'close to', but coincident with the first point)"
As for the centerpoint, you have at least two "natural ways" for calculating it with this definitions:
Centerpoint = Middle Point of the Red Square
Centerpoint = { Mean of x coordinates of your curve, Mean of y coordinates of your curve}
Both of them may serve as a center point, but the results will be different.
The other way of dealing with the problem is finding the Convex Hull of your curve, as depicted below:
If you google for it, you will find algorithms for finding the Convex Hull, a nice introduction is here.
Again, you have two "natural ways for calculating the centerpoint:
Centerpoint = { Mean of x coordinates of your curve, Mean of y coordinates of your curve}
Centerpoint = { Mean of x coordinates of the CH points, Mean of y coordinates of the CH points}
HTH!
(I note that for you to have a closed curve, you need the endpoint to be not just 'close to', but coincident with the first point)
If by 'centerpoint' you mean center of mass, and you are assuming uniform density, then this question has what you want.
If by 'boundaries' you mean bounding rectangle with sides parallel to the axes, you just need the minimum and maximum x and y values on the curve.
If either of those aren't what you mean, please say...
For the boundaries, you can refer to the answers given by #belisarius and #AakashM.
As for centerpoint, you want "center of mass". Good 'ol Wikipedia has explanations and recipes at http://en.wikipedia.org/wiki/Center_of_mass and http://en.wikipedia.org/wiki/Centroid.
In general, you get a different result calculating the centroid than calculating the average of the vertices. This difference will be pronounced if the vertices are not uniformly distributed.