A Pt
represents a point in space, or more technically, an n-dimensional vector. You may also think of a Pt
as an array of numeric values, a set of weights, or an arrow coming from the origin point (0,0,0...).
You can create a Pt
in many different ways:
// defaults to (0,0)
new Pt()
// from a series of parameters, array, or object
new Pt( 1, 2, 3, 4 )
new Pt( [1,2,3] )
new Pt( {x:0, y:1, z:2, w:3} )
new Pt( anotherPt )
Pt.make( 5, 0 ) // same as new Pt(0,0,0,0,0)
Here's a simple demo visualizing a Pt, which moves with your mouse/touch.
Since Pt
is a subclass of javascript's Float32Array
, it means you may use all the Float32Array
features on a Pt
too. For example:
p[0]
p.fill( 0, 1, 2 )
p.reduce( (a,b) => Math.max(a,b), 0 );
Note that Float32Array doesn't allow some common Array functions like push()
and pop()
. If you need to grow or shrink the Pt's dimensions, either create a new one or use $concat
and $take
.
You can update a Pt's values by using to
function, or accessing the .x
, .y
, .z
, .w
properties.
p.to( 1, 2, 3 )
p.to( anotherPt )
p.w = p.x + p.z
Pt provides basic functions for calculating vectors and matrices. But don't worry if you are not familiar with linear algebra. To start, think of it as methods to do calculations on arrays of values, like adding or multiplying them.
let pt = new Pt( 10, 10 )
pt.add( 1, 2 ) // pt is now (11, 12)
pt.divide( 2 ) // divide each value by 2
pt.multiply( {x: 2, y: 1} )
pt.subtract( anotherPt ).multiply( 5 ).add( [1,2,3] )
The above functions like add
will update the values of pt
instance. If you want to get the results as a new Pt, use $add
instead. If a function's name starts with $
, it indicates that its return value will be a new Pt.
let p1 = pt.$add( 1,2,3 );
let p2 = pt.$multiply( 5 ).add( 1,2,3 )
There are other basic vector operations like unit
(get a normalized vector), magnitude
(get its distance from origin), dot
(find dot product), $project
(find its projection vector). Check the docs on Pt
for a full list.
Since a Pt can be thought of as an arrow from origin, you can find its angle with angle
function. You can also find the angle between two Pts with angleBetween
function. A related function toAngle
lets you move a Pt by specifying a target angle.
pt.angle()
pt.angle(Const.yz) // get the angle of axis y-z
pt.angleBetween( anotherPt )
pt.toAngle( Math.PI/2 )
Geom.toRadian
and Geom.toDegree
functions to convert between degrees and radian.If you have used Illustrator or other graphics software before, you probably know the operations to rotate or scale a shape. Pt also provides these transformation functions:
pt.scale( 0.5 )
pt.rotate2D( Math.PI/3 )
pt.shear2D( [0.3, 1.2] )
pt.reflect2D( [p1, p2] )
If you want to transform from a specific anchor point instead of at (0,0), provide an anchor as the second parameter:
pt.scale( 0.5, anchorPt )
pt.rotate( Math.PI/3, anchorPt )
Take a look at the Geom
class which also provides many functions to help with geometry and transformations.
You may use all of Float32Array's functions (eg, slice
, map
) with Pt. Some additional ones in Pt like $concat
, $take
make it simpler to work with TypedArray. Take a look at "Op" section to see how you can write your own functions to work with Pt easily.
// Use $concat and $take to grow and shrink a TypedArray
let p1 = new Pt(1, 2, 3).$concat( 4, 5 ); // becomes Pt(1,2,3,4,5)
// Use op -- see how it works in Op section
p1.op( Line.collinear );
Creating and cloning
new Pt()
new Pt( 1, 2, 3, 4 )
new Pt( [1,2,3] )
new Pt( {x:0, y:1, z:2, w:3} )
new Pt( anotherPt )
Pt.make( 5, 0 ) // same as new Pt(0,0,0,0,0)
pt.clone()
Getting and setting values
p[1]
p[2] = p[0]
p.x = p.y+1
p.to( 1, 2, 3 )
p.id = "p01"
Calculating
p.equals( p2, 0.00001 )
p.$ceil().floor().round()
p.abs()
p.maxValue() - p.minValue()
p.$min( p2 ).$max( p3 )
Vector math
p.add( 1,2 ).subtract( p2 ).multiply( 10 ).divide( 2 )
p.$add( 1,2 ) // $-prefix means getting result as a new Pt
p.angle()
p.angleBetween( p2 )
p.dot( p2 )
p.$cross( p2 )
p.$project( p2 )
p.magnitude()
p.magnitudeSq() // magnitude squared
p.unit() // unit vector
Transforming
p.scale(0.5).rotate2D( Const.half_pi )
p.shear2D( 0.2 ).reflect2D( line )
p.toAngle( Math.PI/3, 100 )
Working with array values
p.reduce( (a,b) => Math.max(a,b), 0 ) // can use all Float32Array functions
p.$take("xz")
p.$concat( 10, 100 )
p.toArray() // convert Float32Array to Array
Check out the full documentation too.