Pt

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...).

Creating a Pt

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.

js:pt_create

Here the red dot is the last position of your mouse/touch as a Pt. The black lines are the distances from the origin (top-left corner), which is equivalent to the Pt's position. The red line represents another way to think of this Pt -- as a vector, as an arrow from the origin of this space.

Float32Array

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.

Updating values

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

Vector math

Pt provides basic functions for calculating vectors and matrices. But don't worry if you are not familiar wtih linear algrebra. 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, using $add etc 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.

Angles

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 )
* Note that all angles are specified in radian, where 180 degrees = π radian. (Imagine half-circle is like 180 degrees.) You can use Geom.toRadian and Geom.toDegree functions to convert between degrees and radian.

js:pt_angle

The above demo uses some basic vector operations and angle functions.

Transformations

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.

js:pt_reflect

A demo of scale and reflect transformation. The red line's length changes the scale, while its angle specifies the reflection. Take a look at the source code to see how easy this it :)

Roll your own

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 );

Cheat sheet

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.