Move anchor, point and transform to JS

This commit is contained in:
be5invis 2020-06-19 04:46:00 -07:00
parent c442ad2b93
commit 1dff622a7d
16 changed files with 160 additions and 152 deletions

View file

@ -2,7 +2,6 @@ import '../support/glyph' as Glyph
import '../support/point' as Point
import '../support/spiro-kit' as spirokit
import '../support/boole-kit' as BooleKit
import '../support/transform' as : Transform && [object [transformPoint tp] [unTransform utp] inverse]
import '../support/anchor' as Anchor
import '../support/monotonic-interpolate' as smoothreg

View file

@ -1,6 +1,6 @@
$$include '../meta/macros.ptl'
import '../support/transform' as : Transform && [object [transformPoint tp] [unTransform utp] inverse]
import '../support/transform' as Transform
import [mix linreg clamp fallback] from '../support/utils'
import [Cv AnyDerivingCv] from '../support/gr'
@ -124,7 +124,7 @@ glyph-block CommonShapes : begin
corner r d
close [lambda : begin [set this.angles 4] [set this.fairGizmo currentGlyph.gizmo]]
if transformShiftOnly : begin
local {.x mx1 .y my1} [tp globalTransform {.x mx .y my}]
local {.x mx1 .y my1} : globalTransform.apply {.x mx .y my}
apply-transform : Translate (mx1 - mx) (my1 - my)
define [Ring u d l r transformShiftOnly] : create-glyph : glyph-construction
@ -143,7 +143,7 @@ glyph-block CommonShapes : begin
arcvh
close [lambda : begin [set this.angles 4] [set this.fairGizmo currentGlyph.gizmo]]
if transformShiftOnly : begin
local {.x mx1 .y my1} [tp globalTransform {.x mx .y my}]
local {.x mx1 .y my1} : globalTransform.apply {.x mx .y my}
apply-transform : Translate (mx1 - mx) (my1 - my)
define [RingAt x y r] : Ring (y + r) (y - r) (x - r) (x + r)
define [DotAt x y r] : Ring (y + r) (y - r) (x - r) (x + r) true
@ -165,7 +165,7 @@ glyph-block CommonShapes : begin
arcvh
close [lambda : begin [set this.angles 4] [set this.fairGizmo currentGlyph.gizmo]]
if transformShiftOnly : begin
local {.x mx1 .y my1} [tp globalTransform {.x mx .y my}]
local {.x mx1 .y my1} : globalTransform.apply {.x mx .y my}
apply-transform : Translate (mx1 - mx) (my1 - my)
define [RingStrokeAt x y r s] : RingStroke (y + r) (y - r) (x - r) (x + r) s
define [DotStrokeAt x y r s] : RingStroke (y + r) (y - r) (x - r) (x + r) s true
@ -182,7 +182,7 @@ glyph-block CommonShapes : begin
g4 r my
close [lambda : begin [set this.angles 4] [set this.fairGizmo currentGlyph.gizmo]]
if transformShiftOnly : begin
local {.x mx1 .y my1} [tp globalTransform {.x mx .y my}]
local {.x mx1 .y my1} : globalTransform.apply {.x mx .y my}
apply-transform : Translate (mx1 - mx) (my1 - my)
define [CircleRingAt x y r] : CircleRing (y + r) (y - r) (x - r) (x + r)
define [CircleDotAt x y r] : CircleRing (y + r) (y - r) (x - r) (x + r) true
@ -786,8 +786,8 @@ glyph-block CommonShapes : begin
local giz this.gizmo
local g : create-glyph : glyph-construction
set this.gizmo : Translate 0 0
local {.x xo .y yo} : tp [Transform.Id] {.x x1 .y y1}
local {.x xt .y yt} : tp [Transform.Id] {.x x2 .y y2}
local {.x xo .y yo} : [Transform.Id].apply {.x x1 .y y1}
local {.x xt .y yt} : [Transform.Id].apply {.x x2 .y y2}
local mag : Math.hypot (yo - yt) (xo - xt)
include [G mag]
apply-transform : Rotate : Math.atan2 (yo - yt) (xo - xt)

View file

@ -4,7 +4,6 @@
$$include '../meta/macros.ptl'
import '../support/transform' as : Transform && [object [transformPoint tp] [unTransform utp] inverse]
import [mix linreg clamp fallback] from '../support/utils'
import [designParameters] from '../meta/aesthetics'
import [Dotless DoNotDeriveVariants] from "../support/gr"
@ -4706,7 +4705,7 @@ glyph-block Letter-Latin-Lower-T : begin
sketch # tltail
include MarkSet.if
include : refer-glyph 't.standard'
local attach : utp currentGlyph.gizmo [query-glyph 't.standard'].baseAnchors.bottomright
local attach : currentGlyph.gizmo.unapply [query-glyph 't.standard'].baseAnchors.bottomright
include : VBarRight attach.x 0 attach.y
include : VerticalHook (attach.x - HalfStroke * HVContrast) 0 (-HookX) Hook
save 'tltail' 0x1AB
@ -4856,7 +4855,7 @@ glyph-block Letter-Latin-S : begin
sketch # srtail
include MarkSet.p
local stroke : [sStroke].call currentGlyph
local start : utp currentGlyph.gizmo stroke.lhsKnots.(stroke.lhsKnots.length - 1)
local start : currentGlyph.gizmo.unapply stroke.lhsKnots.(stroke.lhsKnots.length - 1)
include : create-glyph : glyph-construction
local sw : adviceBlackness2 2.875 2 XH
@ -4873,7 +4872,7 @@ glyph-block Letter-Latin-S : begin
include MarkSet.if
local stroke : [SStroke].call currentGlyph
local start : utp currentGlyph.gizmo stroke.lhsKnots.(stroke.lhsKnots.length - 1)
local start : currentGlyph.gizmo.unapply stroke.lhsKnots.(stroke.lhsKnots.length - 1)
local sw : adviceBlackness2 2.875 2 CAP
include : dispiro
@ -4889,7 +4888,7 @@ glyph-block Letter-Latin-S : begin
include MarkSet.p
local stroke : [sStroke].call currentGlyph
local start : utp currentGlyph.gizmo stroke.lhsKnots.(stroke.lhsKnots.length - 1)
local start : currentGlyph.gizmo.unapply stroke.lhsKnots.(stroke.lhsKnots.length - 1)
local sw : adviceBlackness2 2.875 2 XH
include : dispiro

View file

@ -1,6 +1,5 @@
$$include '../meta/macros.ptl'
import '../support/transform' as : Transform && [object [transformPoint tp] [unTransform utp] inverse]
import [mix linreg clamp fallback] from '../support/utils'
import [designParameters] from '../meta/aesthetics'
import [AnyCv getGrMesh] from "../support/gr"
@ -343,7 +342,7 @@ glyph-block Numbers : begin
hookend O
g4 SB (Hook * top / CAP)
local fiveStroke : FiveStroke.call currentGlyph
local firstKnot : utp currentGlyph.gizmo fiveStroke.rhsKnots.(fiveStroke.rhsKnots.length - 1)
local firstKnot : currentGlyph.gizmo.unapply fiveStroke.rhsKnots.(fiveStroke.rhsKnots.length - 1)
include : VBarRight firstKnot.x firstKnot.y top
include : HBarTop xleft xright top
if SLAB : begin

View file

@ -1,6 +1,5 @@
$$include '../meta/macros.ptl'
import '../support/transform' as : Transform && [object [transformPoint tp]]
import [curveToContour OffsetCurve] from '../support/curve-util'
import [mix linreg clamp fallback] from '../support/utils'
import [designParameters] from '../meta/aesthetics'
@ -221,10 +220,10 @@ glyph-block Overmarks : begin
local tildeWave : [linreg hsvhThin 2.925 hsvhHeav 2.375 hsvh] * [linreg defaultHvc 1 4.35 1.1 hvc]
local tildeWaveX 0.51
define z1 : tp currentGlyph.gizmo : object [x leftEnd] [y tbot]
define z2 : tp currentGlyph.gizmo : object [x : mix leftEnd rightEnd tildeWaveX] [y : mix tbot ttop tildeWave]
define z3 : tp currentGlyph.gizmo : object [x : mix leftEnd rightEnd (1 - tildeWaveX)] [y : mix tbot ttop (1 - tildeWave)]
define z4 : tp currentGlyph.gizmo : object [x rightEnd] [y ttop]
define z1 : currentGlyph.gizmo.apply : object [x leftEnd] [y tbot]
define z2 : currentGlyph.gizmo.apply : object [x : mix leftEnd rightEnd tildeWaveX] [y : mix tbot ttop tildeWave]
define z3 : currentGlyph.gizmo.apply : object [x : mix leftEnd rightEnd (1 - tildeWaveX)] [y : mix tbot ttop (1 - tildeWave)]
define z4 : currentGlyph.gizmo.apply : object [x rightEnd] [y ttop]
define bone : new Arcs.Bez3 z1 z2 z3 z4
define inner : curveToContour [new OffsetCurve bone (+hs) HVContrast] 32

View file

@ -1,7 +1,7 @@
###### GEOMETRIC SHAPES
$$include '../meta/macros.ptl'
import '../support/transform' as : Transform && [object [transformPoint tp] [unTransform utp] inverse]
import '../support/transform' as Transform
import [mix linreg clamp fallback] from '../support/utils'
import [designParameters] from '../meta/aesthetics'

View file

@ -1,7 +1,6 @@
###### GEOMETRIC SHAPES
$$include '../meta/macros.ptl'
import '../support/transform' as : Transform && [object [transformPoint tp] [unTransform utp] inverse]
import [mix linreg clamp fallback] from '../support/utils'
import [designParameters] from '../meta/aesthetics'

View file

@ -1,5 +1,5 @@
import '../support/point' as Point
import '../support/transform' as : Transform && [object [transformPoint tp] [unTransform utp] inverse]
import '../support/transform' as Transform
import [mix linreg clamp fallback] from '../support/utils'
import '../support/anchor' as Anchor

16
support/anchor.js Normal file
View file

@ -0,0 +1,16 @@
"use strict";
module.exports = class Anchor {
constructor(x, y) {
this.x = x;
this.y = y;
}
transform(tfm) {
return Anchor.transform(tfm, this);
}
static transform(tfm, a) {
const x = a.x * tfm.xx + a.y * tfm.yx + tfm.x;
const y = a.x * tfm.xy + a.y * tfm.yy + tfm.y;
return new Anchor(x, y);
}
};

View file

@ -1,11 +0,0 @@
export all : class Anchor
public [new x y ] : begin
set this.x x
set this.y y
static [transform tfm a] : begin
local x : a.x * tfm.xx + a.y * tfm.yx + tfm.x
local y : a.x * tfm.xy + a.y * tfm.yy + tfm.y
return : new Anchor x y
public [transform tfm] : Anchor.transform tfm this

73
support/point.js Normal file
View file

@ -0,0 +1,73 @@
"use strict";
const { z } = require("typo-geom");
module.exports = class Point {
constructor(x, y, on, cubic) {
this.x = x;
this.y = y;
this.on = on;
this.cubic = cubic;
}
add(z2) {
return this.addScale(1, z2);
}
addScale(scale, z2) {
return new Point(this.x + scale * z2.x, this.y + scale * z2.y, this.on, this.cubic);
}
mix(scale, z2) {
return new Point(
this.x + scale * (z2.x - this.x),
this.y + scale * (z2.y - this.y),
this.on,
this.cubic
);
}
scale(t) {
return new Point(t * this.x, t * this.y, this.on, this.cubic);
}
round(d) {
return new Point(
Math.round(d * this.x) / d,
Math.round(d * this.y) / d,
this.on,
this.cubic
);
}
static from(z, on, cubic) {
return new Point(z.x || 0, z.y || 0, on, cubic);
}
static cornerFrom(z) {
return new Point(z.x || 0, z.y || 0, true, false);
}
static offFrom(z) {
return new Point(z.x || 0, z.y || 0, false, false);
}
static cubicOffFrom(z) {
return new Point(z.x || 0, z.y || 0, false, true);
}
static cornerFromXY(x, y) {
return new Point(x || 0, y || 0, true, false);
}
static offFromXY(x, y) {
return new Point(x || 0, y || 0, false, false);
}
static cubicOffFromXY(x, y) {
return new Point(x || 0, y || 0, false, true);
}
static transformed(tfm, z) {
return Point.transformedXY(tfm, z.x, z.y, z.on, z.cubic);
}
static transformedXY(tfm, x, y, on, cubic) {
return new Point(
x * tfm.xx + y * tfm.yx + tfm.x || 0,
x * tfm.xy + y * tfm.yy + tfm.y || 0,
on,
cubic
);
}
static translated(z, dx, dy) {
return new Point(z.x + dx || 0, z.y + dy || 0, z.on, z.cubic);
}
};

View file

@ -1,71 +0,0 @@
export all : class Point
public [new x y on cubic subdivided] : begin
this.x = x
this.y = y
this.on = on || false
this.cubic = cubic || false
this.subdivided = subdivided || false
public [add z2] : new Point
this.x + z2.x
this.y + z2.y
* this.on
* this.cubic
* this.subdivided
public [addScale scale z2] : new Point
this.x + scale * z2.x
this.y + scale * z2.y
* this.on
* this.cubic
* this.subdivided
public [mix scale z2] : new Point
this.x + scale * (z2.x - this.x)
this.y + scale * (z2.y - this.y)
* this.on
* this.cubic
* this.subdivided
public [scale t] : new Point
t * this.x
t * this.y
* this.on
* this.cubic
* this.subdivided
public [round d] : new Point
[Math.round (this.x * d)] / d
[Math.round (this.y * d)] / d
* this.on
* this.cubic
* this.subdivided
static [from z on cubic subdivided] : new Point
* z.x
* z.y
* on
* cubic
* subdivided
static [cornerFrom z] : new Point (z.x || 0) (z.y || 0) true false false
static [offFrom z] : new Point (z.x || 0) (z.y || 0) false false false
static [cubicOffFrom z] : new Point (z.x || 0) (z.y || 0) false true false
static [cornerFromXY x y] : new Point (x || 0) (y || 0) true false false
static [offFromXY x y] : new Point (x || 0) (y || 0) false false false
static [cubicOffFromXY x y] : new Point (x || 0) (y || 0) false true false
static [transformed tfm z] : new Point
* z.x * tfm.xx + z.y * tfm.yx + tfm.x
* z.x * tfm.xy + z.y * tfm.yy + tfm.y
* z.on
* z.cubic
* z.subdivided
static [transformedXY tfm x y on cubic subdivided] : new Point
* x * tfm.xx + y * tfm.yx + tfm.x
* x * tfm.xy + y * tfm.yy + tfm.y
* on
* cubic
* subdivided
static [translated z dx dy] : new Point ((z.x || 0) + dx) ((z.y || 0) + dy) z.on z.cubic z.subdivided

View file

@ -1,5 +1,5 @@
import './monotonic-interpolate' as smooth
import './transform' as : Transform && [object [transformPoint tp] [unTransform utp] inverse]
import './transform' as Transform
import './point' as Point
define [fallback] : for [local j 0] (j < arguments.length) [inc j] : if (arguments.(j) !== nothing) : return arguments.(j)
@ -125,18 +125,18 @@ class SpiroExpansionContext
local jAfter (j + 1)
while this.controlKnots.(jAfter).unimportant : inc jAfter
local knotBefore : utp this.gizmo this.controlKnots.(jBefore)
local knotAfter : utp this.gizmo this.controlKnots.(jAfter)
local ref : utp this.gizmo knot
local lhsBefore : utp this.gizmo lhs.(jBefore)
local lhsAfter : utp this.gizmo lhs.(jAfter)
local rhsBefore : utp this.gizmo rhs.(jBefore)
local rhsAfter : utp this.gizmo rhs.(jAfter)
local knotBefore : this.gizmo.unapply this.controlKnots.(jBefore)
local knotAfter : this.gizmo.unapply this.controlKnots.(jAfter)
local ref : this.gizmo.unapply knot
local lhsBefore : this.gizmo.unapply lhs.(jBefore)
local lhsAfter : this.gizmo.unapply lhs.(jAfter)
local rhsBefore : this.gizmo.unapply rhs.(jBefore)
local rhsAfter : this.gizmo.unapply rhs.(jAfter)
local kLHS : tp this.gizmo : object
local kLHS : this.gizmo.apply : object
x : linreg knotBefore.x lhsBefore.x knotAfter.x lhsAfter.x ref.x
y : linreg knotBefore.y lhsBefore.y knotAfter.y lhsAfter.y ref.y
local kRHS : tp this.gizmo : object
local kRHS : this.gizmo.apply : object
x : linreg knotBefore.x rhsBefore.x knotAfter.x rhsAfter.x ref.x
y : linreg knotBefore.y rhsBefore.y knotAfter.y rhsAfter.y ref.y

43
support/transform.js Normal file
View file

@ -0,0 +1,43 @@
"use strict";
module.exports = class Transform {
constructor(xx, yx, xy, yy, x, y) {
this.xx = xx;
this.yx = yx;
this.xy = xy;
this.yy = yy;
this.x = x;
this.y = y;
}
static Id() {
return new Transform(1, 0, 0, 1, 0, 0);
}
apply(pt) {
return {
x: pt.x * this.xx + pt.y * this.yx + this.x,
y: pt.x * this.xy + pt.y * this.yy + this.y
};
}
unapply(pt) {
const xx = pt.x - this.x;
const yy = pt.y - this.y;
const denom = this.xx * this.yy - this.xy * this.yx;
return {
x: (xx * this.yy - yy * this.yx) / denom,
y: (yy * this.xx - xx * this.xy) / denom
};
}
inverse() {
const denom = this.xx * this.yy - this.xy * this.yx;
return new Transform(
this.yy / denom,
-this.yx / denom,
-this.xy / denom,
this.xx / denom,
-(this.x * this.yy - this.y * this.yx) / denom,
-(-this.x * this.xy + this.y * this.xx) / denom
);
}
};

View file

@ -1,36 +0,0 @@
import './point' as Point
export all : class Transform
public [new xx yx xy yy x y] : begin
this.xx = xx
this.yx = yx
this.xy = xy
this.yy = yy
this.x = x
this.y = y
public [inverse] : Transform.inverse this
static [Id] : new Transform 1 0 0 1 0 0
static [transformPoint tfm pt] : new Point
* pt.x * tfm.xx + pt.y * tfm.yx + tfm.x
* pt.x * tfm.xy + pt.y * tfm.yy + tfm.y
* pt.on
* pt.cubic
* pt.subdivided
static [inverse tfm] : begin
local denom : tfm.xx * tfm.yy - tfm.xy * tfm.yx
return : new Transform
* tfm.yy / denom; * -tfm.yx / denom
* -tfm.xy / denom; * tfm.xx / denom
* -(tfm.x * tfm.yy - tfm.y * tfm.yx) / denom
* -(-tfm.x * tfm.xy + tfm.y * tfm.xx) / denom
static [unTransform tfm pt] : begin
local xx : pt.x - tfm.x
local yy : pt.y - tfm.y
local denom : tfm.xx * tfm.yy - tfm.xy * tfm.yx
return : new Point
* (xx * tfm.yy - yy * tfm.yx) / denom
* (yy * tfm.xx - xx * tfm.xy) / denom
* pt.on
* pt.cubic
* pt.subdivided

View file

@ -1,5 +1,4 @@
import './anchor' as Anchor
import './transform' as : Transform && [object [transformPoint tp] [unTransform utp] inverse]
export : define [mix a b p] : a + (b - a) * p
export : define [ratio l r m] : if [l === r] 0 ((m - l) / (r - l))