Assuming there are two closed curves, one of them is created by points on a counter-clockwise direction, while the other one is created on a clockwise direction. Let this clockwise curve be a hole inside the counter-clockwise curve.
Suppose we have a point place elsewhere in the graph along with the aforementioned curves, and we need to know if the point lies inside the closed curves or not, what shall we do? Also, we need to know if the point is inside the hole or not.
I have created a somewhat graphical pseudonym using Rhino and Grasshopper to demonstrate this situation. Look at the image below to see the flow.
By the way, the Con node has nothing to do with this flow so disregard it. Anyways, for your information, the Con mode, or the Containment node, checks the whereabouts of a point to a curve, and it returns one of the three values here (0 for outside, 1 for coincidence, 2 for inside). But this node does not recognize a closed curve being designated as a hole.
Exploding the curves give us three components: faces, edges and vertices. In this case, we only need vertices.
The two Nearest Line nodes are two same nodes I customized, and these nodes acquires the nearest segment by the point (N), and the closest point along that acquired line (Q). These two values are important for this process.
Get the endpoints of each segment, and produce a vector from those endpoints, thus
vector of the nearest line = endpoint (E) – startpoint (S)
We will also need to get the perpendicular vector with reference to the subject point, that is
perpendicular vector = point at (Q) – subject point
Get the cross product of these two vectors, and use this cross product to get the dot product of it with the normal vector (in this case, the Z node, or the Z-vector node).
Then we have to check if the dot product is greater than 0 or not. If the dot product is greater, we can say that the point is inside the closed curve.
On the contrary, when the point is outside the curve representing a hole, it returns true.
In my previous programming years, when determining the angle given three right sides of a right triangle, I always use arctangent (
Math.Atan2 in .NET). Arctangent is always available for me especially when the length of the hypotenuse of a right triangle is not given.
Until I came across with vectors.
Everyone knows that the output angle of the arctangent ranges between
PI/2. However, It cannot be equal to either
PI/2. Just looking at the graph of arctangent would be clear enough.
In linear algebra, say for example, two vectors are given, both from the origin but at different directions. In determining the angle between two vectors, many would think it will be
Angle = Arctangent (Cross Product of two vectors / Dot product of two vectors)
However, when these two vectors are perpendicular to each other, this is the point that the arctangent will fail. Why is that so? Getting the dot product of two perpendicular vectors will eventually lead to a value of zero, which will fail when used to divide a number.
With this in mind, many would think we have to set first a condition whether the angle will be
PI/2 when the computed dot product of these two vectors is zero. Then, we can determine if the angle is
PI/2 depending of the sign returned by the cross product of two vectors.
In addition to a lengthy code that will result with these conditions, we may sometimes want to determine the angle of two vectors when these vectors product an obtuse triangle, which is impossible using arctangent.
To comply with the above statement, we can use the formula below.
Angle = Arccosine (Dot product of two vectors / Product of lengths of two vectors)
Although there is a division involved here, vectors will always have lengths so producing a zero divisor will never happen, and so no failure in division. Also, the result of the arccosine is ranging from
PI, so you won’t need to make additional painstaking work just to come up with an angle greater than or equal to
PI/2 using arctangents.
Tip: To provide an angle that is greater than
PI (or less than
-PI), use the cross product and check whether the vector produced by the cross product is pointing upward or downward normal to the plane. Then adjusting the angle by this condition can be straightforward.