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