Skip to content

Commit

Permalink
Diagram, Vector: create separate Transform class to hold transfom fun…
Browse files Browse the repository at this point in the history
…ctions
  • Loading branch information
ray-pH committed Sep 23, 2023
1 parent 5556107 commit de98f4c
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 107 deletions.
106 changes: 9 additions & 97 deletions src/diagram.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Vector2 } from './vector.js';
import { Vector2, Transform } from './vector.js';

function assert(condition : boolean, message : string) : void {
if (!condition) {
Expand Down Expand Up @@ -345,16 +345,7 @@ export class Diagram {
* @param v vector to translate
*/
public translate(v : Vector2) : Diagram {
let newd : Diagram = this.copy();
// recursively translate all children
for (let c in newd.children) {
newd.children[c] = newd.children[c].translate(v);
}
// translate paths
if (newd.path != undefined) newd.path = newd.path.translate(v);
// translate origin
newd.origin = newd.origin.add(v);
return newd;
return this.transform(Transform.translate(v));
}

/**
Expand All @@ -363,8 +354,7 @@ export class Diagram {
*/
public position(v : Vector2 = new Vector2(0,0)) : Diagram {
let dv = v.sub(this.origin)
let newd = this.translate(dv);
return newd;
return this.translate(dv);
}

/**
Expand All @@ -373,21 +363,8 @@ export class Diagram {
* @param pivot pivot point, if left undefined, rotate around the origin
*/
public rotate(angle : number, pivot : Vector2 | undefined = undefined) : Diagram {
let newd : Diagram = this.copy();

if (pivot == undefined) { pivot = newd.origin; }

// rotate all children
for (let c in newd.children) {
newd.children[c] = newd.children[c].rotate(angle, pivot);
}
// rotate path
if (newd.path != undefined) newd.path = newd.path.rotate(angle, pivot);

// rotate origin
newd.origin = newd.origin.sub(pivot).rotate(angle).add(pivot);

return newd;
if (pivot == undefined) { pivot = this.origin; }
return this.transform(Transform.rotate(angle, pivot));
}

/**
Expand All @@ -396,30 +373,16 @@ export class Diagram {
* @param origin origin point, if left undefined, scale around the origin
*/
public scale(scale : Vector2, origin? : Vector2) : Diagram {
let newd : Diagram = this.copy();
if (origin == undefined) { origin = newd.origin; }
// scale all children
newd.children = newd.children.map(c => c.scale(scale, origin));
// scale path
if (newd.path != undefined) newd.path = newd.path.scale(scale, origin);
// scale origin
newd.origin = newd.origin.sub(origin).mul(scale).add(origin);
return newd;
if (origin == undefined) { origin = this.origin; }
return this.transform(Transform.scale(scale, origin));
}

/**
* Reflect the diagram over a point
* @param p point to reflect over
*/
public reflect_over_point(p : Vector2) {
let newd : Diagram = this.copy();
// reflect all children
newd.children = newd.children.map(c => c.reflect_over_point(p));
// reflect path
if (newd.path != undefined) newd.path = newd.path.reflect_over_point(p);
// reflect origin
newd.origin = newd.origin.reflect_over_point(p);
return newd;
return this.transform(Transform.reflect_over_point(p));
}

/**
Expand All @@ -428,14 +391,7 @@ export class Diagram {
* @param p2 point on the line
*/
public reflect_over_line(p1 : Vector2, p2 : Vector2) {
let newd : Diagram = this.copy();
// reflect all children
newd.children = newd.children.map(c => c.reflect_over_line(p1, p2));
// reflect path
if (newd.path != undefined) newd.path = newd.path.reflect_over_line(p1, p2);
// reflect origin
newd.origin = newd.origin.reflect_over_line(p1, p2);
return newd;
return this.transform(Transform.reflect_over_line(p1, p2));
}

/**
Expand Down Expand Up @@ -791,50 +747,6 @@ export class Path {
newp.points = newp.points.map(p => transform_function(p));
return newp;
}

/**
* Translate the path by a vector
* @param v vector to translate
*/
public translate(v : Vector2) : Path {
return this.transform(p => p.add(v));
}

/**
* Rotate the path by an angle around a pivot
* @param angle angle to rotate
* @param pivot pivot point
*/
public rotate(angle : number, pivot : Vector2) : Path {
return this.transform(p => p.sub(pivot).rotate(angle).add(pivot));
}

/**
* Scale the path by a scale around a origin
* @param scale scale to scale (x, y)
* @param origin origin point
*/
public scale(scale : Vector2, origin : Vector2) : Path {
return this.transform(p => p.sub(origin).mul(scale).add(origin));
}

/**
* Reflect the path over a point
* @param p point to reflect over
*/
public reflect_over_point(p : Vector2) {
return this.transform(p0 => p0.reflect_over_point(p));
}

/**
* Reflect the path over a line given by two points
* @param p1 point on the line
* @param p2 point on the line
*/
public reflect_over_line(p1 : Vector2, p2 : Vector2) {
return this.transform(p => p.reflect_over_line(p1, p2));
}

}

/**
Expand Down
36 changes: 26 additions & 10 deletions src/vector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,16 +42,6 @@ export class Vector2 {
let len = this.length();
return new Vector2(this.x / len, this.y / len);
}
reflect_over_point(p : Vector2) : Vector2{
return this.sub(p).rotate(Math.PI).add(p);
}
reflect_over_line(p1 : Vector2, p2 : Vector2) : Vector2 {
let v = p2.sub(p1);
let n = v.rotate(Math.PI / 2).normalize();
let d = n.dot(this.sub(p1));
let q = this.sub(n.scale(2*d));
return q;
}
copy() : Vector2 {
return new Vector2(this.x, this.y);
}
Expand All @@ -72,3 +62,29 @@ export function V2(x : number, y : number) : Vector2 {
export function Vdir(angle : number) : Vector2 {
return new Vector2(Math.cos(angle), Math.sin(angle));
}


// transformation functions
type TransformFunc = (p : Vector2) => Vector2;
export class Transform {
static translate(v : Vector2) : TransformFunc {
return (p : Vector2) => p.add(v);
}
static rotate(angle : number, pivot : Vector2) : TransformFunc {
return (p : Vector2) => p.sub(pivot).rotate(angle).add(pivot);
}
static scale(scale : Vector2, origin : Vector2) : TransformFunc {
return (p : Vector2) => p.sub(origin).mul(scale).add(origin);
}
static reflect_over_point(q : Vector2) : TransformFunc {
return (p : Vector2) => p.sub(q).rotate(Math.PI).add(q);
}
static reflect_over_line(p1 : Vector2, p2 : Vector2) : TransformFunc {
let v = p2.sub(p1);
let n = v.rotate(Math.PI / 2).normalize();
return (p : Vector2) => {
let d = n.dot(p.sub(p1));
return p.sub(n.scale(2*d));
}
}
};

0 comments on commit de98f4c

Please sign in to comment.