Help with vectors/compile and optional parameters #492
-
I have a function like this: export function deltaFrom(start?: number, end?: number, delta?: number) {
return delta ?? (start ?? 0) - (end ?? 1);
} How would it be possible to use function deltaFrom(out: Vec | null, start?: Vec, end?: Vec, delta?: Vec): Vec |
Beta Was this translation helpful? Give feedback.
Replies: 4 comments 2 replies
-
Similarly, how would I make generic and optimized vector operations for this type with interface Line {
a: Vec;
b: Vec;
}
function pointOnLine(s: Line, u: number) {...} |
Beta Was this translation helpful? Give feedback.
-
Hi @nonphoto - apologies that the code generation parts of that package are not really documented, so far they were really mainly intended for internal use only and therefore also don't have the nicest API. You could use this like so: import type { MultiVecOp, ReadonlyVec, Vec } from "./api";
import { defHofOp } from "./compile/emit";
function $deltaFrom(start?: number, end?: number, delta?: number) {
return delta ?? (start ?? 0) - (end ?? 1);
}
type DeltaFrom = (
out?: Vec,
start?: ReadonlyVec,
end?: ReadonlyVec,
delta?: number
) => Vec;
export const [deltaFrom, deltaFrom2, deltaFrom3, deltaFrom4] = defHofOp<
MultiVecOp<DeltaFrom>,
DeltaFrom
>(
// your actual function to apply componentwise
$deltaFrom,
// template function for computing a single vector component
([o, a, b]) => `${o}=op(${a},${b},n);`,
// function args (here with defaults)
"o,a=[],b=[],n",
// function args (names only)
"o,a,b,n"
); This results then in: // 2D version
deltaFrom.impl(2).toString()
// '(o,a=[],b=[],n)=>{!o && (o=a);o[0]=op(a[0],b[0],n);o[1]=op(a[1],b[1],n);return o;}'
// 3D version
deltaFrom.impl(3).toString()
// '(o,a=[],b=[],n)=>{!o && (o=a);o[0]=op(a[0],b[0],n);o[1]=op(a[1],b[1],n);o[2]=op(a[2],b[2],n);return o;}'
// generic
deltaFrom.impl(0).toString()
// '(o,a=[],b=[],n)=>{!o && (o=a);for(let i=a.length;--i>=0;) {o[i]=op(a[i],b[i],n);}return o;}' Btw. I just updated the internal code gen to correctly handle cases where the To your second question: This function is supposed to compute the point at parametric position import { mixN } from "@thi.ng/vectors";
const pointOnLine = ({a, b}: Line, u: number) => mixN([], a, b, u); Hope that helps! |
Beta Was this translation helpful? Give feedback.
-
Thanks! This makes a lot of sense. My only concern is that it would be nice to be able to do this without creating any new arrays in the function args param: For the second question: my example was more about working with structs with vectors in them (I didn't consider that there might be a interface Spring {
start: number;
end: number;
damping: number;
stiffness: number;
}
positionAt(s: Spring, t: number) {
... // Very long!
} I want to make a vectorized version of this interface VectorSpring {
start: Vec;
end: Vec;
damping: number;
stiffness: number
}
function positionAt(s: VectorSpring, t: number) {...}
function positionAt2(s: VectorSpring, t: number) {...}
function positionAt3(s: VectorSpring, t: number) {...}
function positionAt4(s: VectorSpring, t: number) {...} It wouldn't make sense to implement these using the existing vector ops. Now that I'm seeing what actually gets generated from |
Beta Was this translation helpful? Give feedback.
-
The empty arrays as default values are only created if the respective args are not given and I only did that because the way you wrote your scalar For your struct-based use case, I agree that import { VEC2, VEC3, type VecAPI, type Vec, type ReadonlyVec } from "@thi.ng/vectors";
const GRAVITY2 = [0, 9.8]; // -Y up axis
const GRAVITY3 = [0, -9.8, 0]; // +Y up axis
class Particle {
force: Vec;
// all VecAPI impls provide size-optimized vec ops
constructor(public vec: VecAPI, public pos: Vec, public gravity: Vec) {
this.force = vec.zeroes();
}
addForce(f: ReadonlyVec, dt: number) {
this.vec.maddN(this.force, f, dt, this.force);
}
updatePos() {
// destructure if you're using multiple vec ops...
const { add, setN } = this.vec;
add(null, this.pos, this.force);
setN(this.force, 0);
}
}
// factory function for 2D particles
const particle2 = (pos: Vec, gravity: Vec = GRAVITY2) => new Particle(VEC2, pos, gravity);
// factory function for 3D particles
const particle3 = (pos: Vec, gravity: Vec = GRAVITY3) => new Particle(VEC3, pos, gravity); |
Beta Was this translation helpful? Give feedback.
Hi @nonphoto - apologies that the code generation parts of that package are not really documented, so far they were really mainly intended for internal use only and therefore also don't have the nicest API. You could use this like so: