Skip to content

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:

  1. Construct a vector u from the center c of the sphere to the point we wish to project p.
  2. Normalize the vector u to retain its direction but set its length to 1.0.
  3. Translate the center of the sphere c towards u scaled by the radius of the sphere r.
""" 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.

  1. Create a vector v from the line's origin o towards the point in space p.
  2. Compute the projected length d of v onto u using the dot product.
  3. Translate the line's origin o along the line's direction scaled by d.
""" 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.

  1. Create a vector v from the plane's origin o towards the point in space p.
  2. Compute the projected length d of v onto n using the dot product.
  3. Translate the point p against the plane's normal n scaled by d.
""" 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