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

### 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. ### 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. ##### A demo of scale and reflect transformation. The blue 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 :)

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
p = p
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.