Do a better job of cubic-to-quadratic conversion
This commit is contained in:
parent
2aba5fdcfc
commit
4c772433b0
|
@ -22,33 +22,40 @@ export class PathSegment {
|
||||||
for (let i = 1; i < segment.length; i += 2)
|
for (let i = 1; i < segment.length; i += 2)
|
||||||
points.push(new Point2D(parseFloat(segment[i]), parseFloat(segment[i + 1])));
|
points.push(new Point2D(parseFloat(segment[i]), parseFloat(segment[i + 1])));
|
||||||
this.points = points;
|
this.points = points;
|
||||||
//console.log("PathSegment, segment=", segment, "points=", points);
|
|
||||||
this.command = segment[0];
|
this.command = segment[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
to(): Point2D | null {
|
to(): Point2D | null {
|
||||||
return this.points[this.points.length - 1];
|
return this.points[this.points.length - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
toStringPieces(): string[] {
|
||||||
|
const pieces = [this.command];
|
||||||
|
for (const point of this.points) {
|
||||||
|
pieces.push(" " + point.x);
|
||||||
|
pieces.push(" " + point.y);
|
||||||
|
}
|
||||||
|
return pieces;
|
||||||
|
}
|
||||||
|
|
||||||
|
toString(): string {
|
||||||
|
return this.toStringPieces().join(" ");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function flattenPath(path: SVGPath): SVGPath {
|
export function flattenPath(path: SVGPath): SVGPath {
|
||||||
return path.unshort().abs().iterate(segment => {
|
let lastPoint: Point2D | null = null;
|
||||||
if (segment[0] === 'C') {
|
return path.unshort().abs().iterate(segmentPieces => {
|
||||||
const ctrl0 = new Point2D(parseFloat(segment[segment.length - 6]),
|
let segment = new PathSegment(segmentPieces);
|
||||||
parseFloat(segment[segment.length - 5]));
|
if (segment.command === 'C' && lastPoint != null) {
|
||||||
const ctrl1 = new Point2D(parseFloat(segment[segment.length - 4]),
|
const ctrl10 = segment.points[0].scale(3.0).sub(lastPoint).scale(0.5);
|
||||||
parseFloat(segment[segment.length - 3]));
|
const ctrl11 = segment.points[1].scale(3.0).sub(segment.points[2]).scale(0.5);
|
||||||
const to = new Point2D(parseFloat(segment[segment.length - 2]),
|
const to = segment.points[2];
|
||||||
parseFloat(segment[segment.length - 1]));
|
const ctrl = ctrl10.lerp(ctrl11, 0.5);
|
||||||
const ctrl = new Point2D(0.5 * (ctrl0.x + ctrl1.x), 0.5 * (ctrl0.y + ctrl1.y));
|
segment = new PathSegment(['Q', "" + ctrl.x, "" + ctrl.y, "" + to.x, "" + to.y]);
|
||||||
return [['Q', "" + ctrl.x, "" + ctrl.y, "" + to.x, "" + to.y]];
|
|
||||||
}
|
}
|
||||||
if (segment[0] === 'A') {
|
lastPoint = segment.to();
|
||||||
const to = new Point2D(parseFloat(segment[segment.length - 2]),
|
return [segment.toStringPieces()];
|
||||||
parseFloat(segment[segment.length - 1]));
|
|
||||||
return [['L', "" + to.x, "" + to.y]];
|
|
||||||
}
|
|
||||||
return [segment];
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ const parseColor: (color: string) => any = require('parse-color');
|
||||||
const SVG_NS: string = "http://www.w3.org/2000/svg";
|
const SVG_NS: string = "http://www.w3.org/2000/svg";
|
||||||
|
|
||||||
const STENCIL_FRAMEBUFFER_SIZE: Size2D = {
|
const STENCIL_FRAMEBUFFER_SIZE: Size2D = {
|
||||||
width: TILE_SIZE.width * 256,
|
width: TILE_SIZE.width * 128,
|
||||||
height: TILE_SIZE.height * 256,
|
height: TILE_SIZE.height * 256,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -286,9 +286,8 @@ class App {
|
||||||
gl.drawArraysInstanced(gl.TRIANGLE_FAN, 0, 4, unwrapNull(this.primitiveCount));
|
gl.drawArraysInstanced(gl.TRIANGLE_FAN, 0, 4, unwrapNull(this.primitiveCount));
|
||||||
gl.disable(gl.BLEND);
|
gl.disable(gl.BLEND);
|
||||||
|
|
||||||
/*
|
|
||||||
// Read back stencil and dump it.
|
// Read back stencil and dump it.
|
||||||
const totalStencilFramebufferSize = STENCIL_FRAMEBUFFER_SIZE.width *
|
/*const totalStencilFramebufferSize = STENCIL_FRAMEBUFFER_SIZE.width *
|
||||||
STENCIL_FRAMEBUFFER_SIZE.height * 4;
|
STENCIL_FRAMEBUFFER_SIZE.height * 4;
|
||||||
const stencilData = new Float32Array(totalStencilFramebufferSize);
|
const stencilData = new Float32Array(totalStencilFramebufferSize);
|
||||||
gl.readPixels(0, 0,
|
gl.readPixels(0, 0,
|
||||||
|
@ -578,7 +577,6 @@ class Scene {
|
||||||
outline.stroke(strokeWidth * GLOBAL_TRANSFORM.a);
|
outline.stroke(strokeWidth * GLOBAL_TRANSFORM.a);
|
||||||
const strokedPathString = outline.toSVGPathString();
|
const strokedPathString = outline.toSVGPathString();
|
||||||
path = SVGPath(strokedPathString);
|
path = SVGPath(strokedPathString);
|
||||||
console.log(path.toString());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
paths.push(path);
|
paths.push(path);
|
||||||
|
|
Loading…
Reference in New Issue