Skip to content

Latest commit

History

1,094 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

basics - vector

GitHub package versionnpm versionlicense

main action pipelinebeta action pipelineRenovate

Quality Gate StatusCoverageCode Smells

This library provides 3D Vector in js including arithmetic operator overloading (+ - * / % **).

Normally vector implementations in javascript handle arithmetic operation by methods aVec.multiply(bVec).substract(dVec). Other languages provide operator overloading, that coders can create Vector class which can handle operation similar to number handling aVec * bVec - dVec.

This library gives javascript coders a way to handle operators with a single statement () => aVec * bVec - dVec. The calculation can be combined with numbers () => aVec * bVec * 4 - dVec - 1.5. Vector objects can be create with number new Vector(5, 6, 7) or directly with assigned statement new Vector(() => 5 * 30 + 2).

Implementation details

// typical implementation of vector in jsconstvec=aVec.multiply(bVec).multiply(4).substract(dVec).substract(1.5);// better readable, but much more complicatedconstvec=newVec(aVec.x*bVec.x*4-dVec.x-1.5,aVec.y*bVec.y*4-dVec.y-1.5,aVec.z*bVec.z*4-dVec.z-1.5);// inspired by smart array handling// first version of calling assigned function three timesconstvec=oldCalc(aVec,bVec,dVec,(aVec,bVec,dVec)=>aVec*bVec*4-dVec-1.5);// final version with overwritten valueOf() methodconstvec=calc(()=>aVec*bVec*4-dVec-1.5);

Javascript has this one peculiarity called valueOf() this method is designed for primitive handling (numbers and strings) when handling arithmetic operations. Every class can overwrite this method to give it special behavior. This Vector class calls the assigned statement three times for x, y and z. Comparable to trigger arithmetic operation manually for every axis.

Internally the valueOf() implementation returns x in first call, y in second call and z in last call, these results are put into an new Vector object and can be reused further.

Usage

load via hmtl

<scripttype="text/javascript"
src="https://unpkg.com/@js-basics/vector/build/iife"
></script>
const{ calc, vector, victor, point, ipoint }=basics.vector;

load via npm

$ npm i @js-basics/vector

import{calc,vector,victor,point,ipoint}from"@js-basics/vector";

working with Vector classes

create vector by numbers

constpos=vector(5,6,7);constdir=vector(1,0,0);console.log(debug`pos:${pos}, dir: ${dir}`);// pos: { x: 5, y: 6, z: 7 } dir: { x: 1, y: 0, z: 0 }

create vector by calculating other vectors and number

constoffsetA=vector(()=>dir*30+pos);console.log(debug`offsetA: ${offsetA}`);// offsetA: { x: 35, y: 6, z: 7 }

calculate cross product

constdir1=vector(0,1,0);constdir2=vector(-1,0,1);constcross=dir1.cross(dir2);console.log(debug`cross: ${cross}`);// cross: { x: 1, y: 0, z: 1 }

directly normalize the cross product

constcrossNorm=dir1.crossNormalize(dir2);console.log(debug`crossNorm: ${crossNorm}`);// crossNorm: { x: 0.7071, y: 0, z: 0.7071 }

cross product handling works also with operator handling

constcrossNormCalc=vector(()=>dir1.crossNormalize(dir2)*50);console.log(debug`crossNormCalc: ${crossNormCalc}`);// crossNormCalc: { x: 35.36, y: 0, z: 35.36 }

normalize with arithmetic only

constnorm=vector(()=>offsetA/offsetA.length);console.log(debug`norm: ${norm}`);// norm: { x: 0.967, y: 0.1658, z: 0.1934 }

mutable 3D vector called Vector

constv1=vector(5,6,7);v1.x=27;console.log(debug`v1: ${v1}`);// v1: { x: 27, y: 6, z: 7 }v1.calc(p=>(p+1)*12);console.log(debug`v1: ${v1}`);// v1: { x: 336, y: 84, z: 96 }

immutable 3D vector called Victor

behaves exactly like Vector but code cant change its x, y and z axes.

constv2=victor(5,6,7);try{v2.x=27;}catch(error){console.log(`error: ${error}`);// error: Error: set x() not implemented}

mutable 2D vector called Point

constp1=point(5,6);p1.x=27;console.log(debug`p1: ${p1}`);// p1: { x: 27, y: 6 }p1.calc(p=>(p+1)*12);console.log(debug`v1: ${v1}`);// p1: { x: 336, y: 84 }

immutable 2D vector called IPoint

behaves exactly like Point but code cant change its x and y axes.

constp2=ipoint(5,6);try{p2.x=27;}catch(error){console.log('error:',error.toString());// error: Error: set x() not implemented}

creating vector inside calculation

works fine thanks to caching in factory function.

// creating vector inside calculation works fine,// thanks to caching in factory functionconstinlineVec=victor(()=>victor(25,30,0)/2);console.log(debug`inlineVec: ${inlineVec}`);// inlineVec: { x: 12.5, y: 15, z: 0 }

mixing 2D and 3D space

// mix 2D and 3D spaceconstfrom2d=victor(()=>point(25,30)/2);constfrom3d=ipoint(()=>from2d.xy*2);console.log(debug`from2d: ${from2d}`);console.log(debug`from3d: ${from3d}`);// from2d: { x: 12.5, y: 15, z: 0 }// from3d: { x: 25, y: 30 }

Not another vector lib

You are happy with your current vector library and definitely don’t want to change 1000 lines of code already written in your projects. Then you can only use the valueOf extension and the calc function.

working with Operator class

load via hmtl

<scripttype="text/javascript"
src="https://unpkg.com/@js-basics/vector/build/iife/operator.js"
></script>
const{ cachedValueOf, cachedFactory, operatorCalc }=basics.vector.operator;

load via npm

$ npm i @js-basics/vector

import{cachedValueOf,cachedFactory,operatorCalc}from"@js-basics/vector/operator";

override valueOf in own class

classTuple{constructor(x,y,z){this.x=x;this.y=y;this.z=z;}}cachedValueOf(Tuple);

write own factory function

consttuple=(()=>{consttupleFactory=cachedFactory(Tuple);return(x,y,z)=>{if(typeofx==='function'){returnoperatorCalc(x,newTuple());}returntupleFactory(x,y,z);};})();constt1=tuple(3,4,5);constt2=tuple(6,7,8);constt=tuple(()=>t1+t2*2);console.log(`t: ${JSON.stringify(t)}`);// t: {"x":15,"y":18,"z":21}

Predefined adapters

existing operator overloading for game engines or other vector libraries

About

This library provides 3D Vector in js including arithmetic operator overloading (+ - * / % **).

Topics

Resources

Stars

14 stars

Watchers

3 watching

Forks

Releases

Packages

Used by

Contributors

Languages