Projections
The objective of this section is to cover geometric constructions using points and vectors. In particular, this section focuses on projections.
Point on Sphere
Provided with a sphere ( c, r )
, defined by its center point c
and radius r
, and a second point p
, determine the location of the point of q
projection from p
onto the sphere.
""" Inputs
"""
c = Point3d( cx, cy, cz )
p = Point3d( px, py, pz )
r = 2.0
Solution
Geometrically we can consider the projection as a translation from the point in space onto the sphere along the direction between the point and the sphere's center. Alternatively, we can consider moving from the sphere's center towards the point but no more than the sphere's radius. The later approach is actually very simple to compute as follows:
- Construct a vector
u
from the centerc
of the sphere to the point we wish to projectp
. - Normalize the vector
u
to retain its direction but set its length to1.0
. - Translate the center of the sphere
c
towardsu
scaled by the radius of the spherer
.
""" Outputs
"""
u = p - c
u.Unitize( )
q = c + u * r
Using the rhino / grasshopper geometry library requires constructing a Sphere
object and the using its ClosestPoint( )
method.
""" Outputs
"""
s = Sphere( c, r )
q = s.ClosestPoint( p )
Point on Line
Provided with a line ( o, u )
, defined by its origin o
and a unit direction u
, and a point p
, determine the location of the point of projection q
from p
onto the line.
""" Inputs
"""
o = Point3d( ox, oy, oz )
u = Vector3d( ux, uy, uz )
p = Point3d( px, py, pz )
Solution
This construction is based on the property of performing a dot product between two vectors one of which is unit-length. From trigonometry, the dot product gives the projected length of the non-unit vector on the unit vector which can use to translate the origin to the point of projection.
- Create a vector
v
from the line's origino
towards the point in spacep
. - Compute the projected length
d
ofv
ontou
using the dot product. - Translate the line's origin
o
along the line's direction scaled byd
.
""" Outputs
"""
v = p - o
d = u * v
q = o + u * d
Using the rhino / grasshopper geometry library requires constructing a Line
object and using the ClosestPoint( )
method. Note that the second parameter controls whether the line is considered finite or infinite.
""" Outputs
"""
l = Line( o, u )
q = l.ClosestPoint( p, False )
Point on Plane
Provided with a plane ( o, n )
defined by its origin point o
and the unit normal vector n
, and another point p
, determine the location of the point of projection q
from p
onto the plane.
""" Inputs
"""
o = Point3d( ox, oy, oz )
n = Vector3d( nx, ny, nz )
p = Point3d( px, py, pz )
Solution
The logic of this projection is exactly the same as projecting onto a line. It uses the 'projected length' property of the dot product. The only difference is that here we are moving from the point in space onto the plane. Therefore, we need to negate the result of the dot product.
- Create a vector
v
from the plane's origino
towards the point in spacep
. - Compute the projected length
d
ofv
onton
using the dot product. - Translate the point
p
against the plane's normaln
scaled byd
.
""" Outputs
"""
v = p - o
d = u * v
q = p - n * d
Using the rhino / grasshopper geometry library requires constructing a Plane
object and using the ClosestPoint( )
method.
""" Outputs
"""
P = Plane( o, n )
q = P.ClosestPoint( p )
Point on Circle
Provided with a circle ( c, n, r )
, defined by its center point c
, unit normal vector n
, and radius r
, and another point p
, determine the location of the point of projection q
from p
onto the circle.
""" Inputs
"""
r = 2.0
c = Point3d( cx, cy, cz )
n = Vector3d( nx, ny, nz )
p = Point3d( px, py, pz )
Solution
Since a circle is a planar curve and the point p
is not on the same plane, this requires two projections: first on the plane o = p - n * ( p - c ) * n
and next on the circle q = c + r * ( o - c ) / | o - c |
.
""" Outputs
"""
o = p - n * ( p - c ) * n
u = o - c; u.Unitize( )
q = c + r * u
Another way to think about this is by considering the plane spanned by the normal n
and the vector u = p - c
intersecting the circle. The vector w = n x u x n
expresses the projection of u
on the plane, thus the projection can be compute using q = c + r * w / |w|
.
""" Outputs
"""
w = Vector3d.CrossProduct(
Vector3d.CrossProduct(
n, p - c ), n )
w.Unitize( )
q = c + r * w
Point on a Cylinder
Provided with a cylinder ( o, u, r )
, defined its the origin point o
, axis direction u
, and radius r
, and another point, p
, determine the location of the point of projection q
from p
onto the cylinder.
""" Inputs
"""
r = 2.0
o = Point3d( ox, oy, oz )
u = Vector3d( ux, uy, uz )
p = Point3d( px, py, pz )
Solution
The projection point q
can be constructed by first projecting p
on the cylinder's axis producing point a
and then moving out of the cylinder towards the point in space, w = p - a
by distance equal to the radius, and therefore q = a + r * w / |w|
. Note that the cylinder's direction is assumed unit-length, otherwise it must be normalized.
""" Outputs
"""
v = p - o #-- Origin to Point
a = o + u * v * u #-- Projection on Axis
w = p - a #-- Orthogonal to Point
w.Unitize( ) #--
q = a + w * r #-- Point of Projection
Point on a Cone
Provided with a cone ( o, a, r )
, defined by two points of its axis ( o, a )
, where a
is its apex, o
is its base point where its radius is r
, and another point p
, determine the location of the point of projection q
from p
onto the cone.
""" Inputs
"""
r = 2.0
o = Point3d( ox, oy, oz )
a = Point3d( ax, ay, az )
u = Vector3d( ux, uy, uz )
p = Point3d( px, py, pz )
Solution
Finding the point of projection q
is a two step process: first the line of the intersection a -> b
between the cone and the plane spanned by its apex a
, origin o
and point p
is computed, followed by projecting the point p
onto the line q = a + x * ( p - a ) * x
, where x = ( b - a ) / | b - a |
. Therefore, computing the point b
requires some consideration.
There are several ways to approach this including basic trigonometry, surface-plane intersection and even rotation. However, there is simple solution if we consider that the point b
may be computed by translation from the cylinder's origin o
by distance r
towards a direction which is orthogonal to its axis and the normal of the plane.
""" Cylinder's Axis and Apex -> Point Vector
"""
u = o - a; u.Unitize( )
v = p - a
""" Plane's Normal and Orthogonal to Axis x Normal
"""
n = Vector3d.CrossProduct( u, v )
w = Vector3d.CrossProduct( n, u ) #-- order matters!
w.Unitize( )
""" Point on Generatrix and its Direction
"""
b = o + r * w
x = b - a; x.Unitize( )
""" Point of Projection
"""
q = a + x * v * x