# vector.p8

a simple and lightweight (in tokens) vector math library for PICO-8.

usage:

`load #vector_p8`

and save as such: vector.p8- remove all the demo code; it's in the second tab
`#include`

in any cart you want

## functions within:

> NOTE:

> vectors are just normal Lua tables with `x`

and `y`

fields, so you can pass any table that contains `x`

and `y`

to any of the functions and they will work regardless.

### creation and management

`vector(x,y)`

- the main function. `x`

and `y`

default to `0`

`v_polar(angle, length)`

- makes a new vector using polar coordinates

`v_rnd()`

- returns a normalized vector with a random direction

`v_copy(v)`

- returns a copy of `v`

`v_unpack(v)`

- returns the components of `v`

separately

`v_tostr(v)`

- turns a vector into a string, appropriate for both debugging and normal output. it looks like `[x, y]`

### actual math

`v_add(a,b)`

- returns `a`

+ `b`

`v_sub(a,b)`

- returns `a`

- `b`

`v_scale(v,n)`

- returns `v`

scaled by `n`

`v_mul(v,n)`

- alias for `v_scale`

`v_div(v,n)`

- returns `v`

scaled by the inverse of `n`

`v_dot(a,b)`

- returns the dot product of `a`

and `b`

`v_magsq(v)`

- returns the squared magnitude of `v`

`v_mag(v)`

- returns the magnitude of `v`

`v_distsq(a,b)`

- returns the squared distance between `a`

and `b`

`v_dist(a,b)`

- returns the distance between `a`

and `b`

`v_norm(v)`

- returns `v`

, normalized

`v_perp(v)`

- returns a vector clockwise-perpendicular to `v`

`v_proj(a,b)`

- returns the projection of `b`

onto `a`

`v_dir(a,b)`

- returns a normalized vector that points towards `b`

, with origin at `a`

.

### rotation related functions

`v_rot(v,t)`

- returns `v`

rotated by `t`

.

`v_angle(v)`

- returns the angle denoted by `v`

### miscellaneous

`v_lerp(a,b,t)`

- linearly interpolates from `a`

to `b`

by `t`

`v_flr(v)`

- returns `v`

, with all its components floored

## constants

> **WARNING!**

> because of the way Lua tables work, do **NOT** use compound assignments to alter a variable if you directly assign one of these constants to it. either copy the constant using `v_cpy`

and then assign that to the variable or use one of the functions within the library to manipulate it.

`v_right`

- rightwards pointing vector.

`v_left`

- leftwards pointing vector.

`v_up`

- upwards pointing vector. Y points downward in 2D so this vector points towards -Y.

`v_down`

- downwards pointing vector. Y points downward in 2D so this vector points towards +Y.

`v_one`

- identity vector. all components are set to 1.

`v_center`

- utility vector pointing towards the center of the screen, i.e. [64,64].

## changelog

### format: dd-mm-yyyy

v2.2 (02-10-2024):

- fixed undefined global call to
`v_dstsq`

in`v_dist`

(see v2.0 changelog) - added version number to cart title
- programmed a new demo! check the second tab in the editor (tab 1)

v2.1.1 (02-10-2024):

- accidentally switched x and y around in
`v_angle`

, sorry about that

v2.1 (02-10-2024):

- the calls to cos and sin in
`v_polar`

were swapped with each other - the formula for
`v_proj`

was taken from Wikipedia, and it projects b onto a, not a onto b; the docs were updated to reflect that

v2.0 (24-05-2024):

almost a 50% reduction on tokens, in exchange for various breaking changes:

- removed
`v_eq`

,`v_zero`

,`v_atwds`

,`v_isvec`

,`v_arr`

and`v_sprj`

- removed z component from all functions, the 3D constants and
`v_cross`

as in, this library no longer supports 3D math. sorry. it was oddly shoehorned in though, so I really wouldn't have relied on it that much. - added
`v_dir`

, taken from a mod of the library done by snale - optimized
`v_lerp`

,`v_sub`

and`v_rot`

`v_proj`

now uses the proper definition for vector projection- extended the names of some functions:
`v_cpy`

->`v_copy`

`v_unpck`

->`v_unpack`

`v_scl`

->`v_scale`

`v_ang`

->`v_angle`

`v_cntr`

->`v_center`

`v_dst`

->`v_dist`

`v_dstsq`

->`v_distsq`

v1.2.1 (11-03-2023):

- thought I had fixed all functions that used
`v_getd`

, but turns out one function I hadn't added to the docs,`v_flr`

, still used it - documented
`v_flr`

- improved explanation for
`v_atwds`

v1.2 (06-12-2022):

- fixed the math functions
`v_add`

,`v_sub`

,`v_scl`

,`v_div`

and`v_neg`

using the now-defunct`v_getd`

function

v1.1 (09-11-2022):

- removed all dimension related functions

Consequently, a parameter was added to v_tostr for it to know how to format the output - added
`v_sprj`

and`v_proj`

- renamed
`v_center`

to`v_cntr`

v1.0 (09-11-2022):

- initial release

oh yeah, right, the cart here has a demo, you gotta remove that code and then you can use the lib. I gotta put that in the post...

This is great, thank you!

Two questions:

- v_polar seems to invert x and y, shouldn't it be
`x=l*cos(a)`

and`y=l*sin(a)`

? - from my experiments, it looks like v_proj is projecting b on a, instead of a on b (as stated in the description)

It's been a while since I studied trig, so I may have gotten both completely wrong :)

funnily enough, you're right on both :)

v_polar is like that because when I wrote this library I wasn't aware sin and cos weren't interchangeable, so I used them in either order, and I guess I just forgot about it

and for v_proj, I guess I'll just swap a and b in the description

I'll push a single minor update to fix both of these, thanks for pointing out both errors!

I'm using your lib in my game and it's saving me a lot of time.

Hope you don't mind if I keep posting minor issues as I find them, sorry in advance for the spam:

`v_lerp`

calls`v_scl`

instead of`v_scale`

I also added three functions that I needed, feel free to add them if you like'em

function v_limit(v,n) local mgsq=v_magsq(v) if mgsq > n*n then return v_scale(v_div(v,sqrt(mgsq)),n) end return v end function v_bounce(v,n,br) --https://gamedev.stackexchange.com/a/35537 return v_sub(v,v_mul(n,(1+br)*v_dot(v,n))) end v_reflect=v_bounce function v_grow(v,n) local vm=v_mag(v) local norm=v_div(v,vm) return v_mul(norm,vm+n) end |

[Please log in to post a comment]