将SVG转换为Three.js路径
尝试使用上演示的示例SVG解析代码。它不正确支持“a”路径命令。我已经在中找到了一些更正,也做了一些我自己的参考,但仍然出现了错误 下面是一个显示原始SVG的示例 由于stack需要这里的代码,因此这是错误解析和解释A和A路径的代码:将SVG转换为Three.js路径,svg,three.js,Svg,Three.js,尝试使用上演示的示例SVG解析代码。它不正确支持“a”路径命令。我已经在中找到了一些更正,也做了一些我自己的参考,但仍然出现了错误 下面是一个显示原始SVG的示例 由于stack需要这里的代码,因此这是错误解析和解释A和A路径的代码: // - elliptical arc case "A": case "a": rx = eatNum(); ry = eat
// - elliptical arc
case "A":
case "a":
rx = eatNum();
ry = eatNum();
xar = eatNum() * DEGS_TO_RADS;
laf = eatNum(); //large arc flag
sf = eatNum(); //sweep flag
nx = eatNum();
ny = eatNum();
if (activeCmd == "a") {
// relative
nx += x;
ny += y;
}
if(rx != 0 && ry != 0) {
console.debug(
"Read arc params: rx=" + rx + ", ry=" + ry + ", xar=" + xar + ", laf=" + laf + ", sf=" + sf + ", nx=" + nx + ", ny=" + ny
);
//might need to bring this back if absellipse doesn't work
//if (rx !== ry)
// console.warn("Forcing elliptical arc to be a circular one :(", rx, ry);
// SVG implementation notes does all the math for us! woo!
// http://www.w3.org/TR/SVG/implnote.html#ArcImplementationNotes
// step1, using x1 as x1'
x1 = Math.cos(xar) * (x - nx) / 2 + Math.sin(xar) * (y - ny) / 2;
y1 = -Math.sin(xar) * (x - nx) / 2 + Math.cos(xar) * (y - ny) / 2;
// step 2, using x2 as cx'
console.debug( "TMP x1=" + x1 + ", y1=" + y1 + ", (rx*rx * y1*y1 + ry*ry * x1*x1)=" + (rx * rx * y1 * y1 + ry * ry * x1 * x1) + ", (rx*rx * ry*ry - rx*rx * y1*y1 - ry*ry * x1*x1)=" + (rx * rx * ry * ry - rx * rx * y1 * y1 - ry * ry * x1 * x1));
var norm = Math.sqrt(
Math.abs(
(rx * rx * ry * ry - rx * rx * y1 * y1 - ry * ry * x1 * x1) /
(rx * rx * y1 * y1 + ry * ry * x1 * x1)
)
);
if (laf === sf) norm = -norm;
x2 = norm * rx * y1 / ry;
y2 = norm * -ry * x1 / rx;
console.debug("TMP norm=" + norm + ", x2=" + x2 + ", y2=" + y2);
// step 3
cx = Math.cos(xar) * x2 - Math.sin(xar) * y2 + (x + nx) / 2;
cy = Math.sin(xar) * x2 + Math.cos(xar) * y2 + (y + ny) / 2;
console.debug("TMP cx=" + cx + ", cy=" + cy);
var u = new THREE.Vector2(1, 0),
v = new THREE.Vector2((x1 - x2) / rx, (y1 - y2) / ry);
var startAng = Math.acos(u.dot(v) / u.length() / v.length());
if (u.x * v.y - u.y * v.x < 0) startAng = -startAng;
// we can reuse 'v' from start angle as our 'u' for delta angle
u.x = (-x1 - x2) / rx;
u.y = (-y1 - y2) / ry;
var deltaAng = Math.acos(v.dot(u) / v.length() / u.length());
// This normalization ends up making our curves fail to triangulate...
if (u.x * v.y - u.y * v.x < 0) deltaAng = -deltaAng;
if (!sf && deltaAng > 0) deltaAng -= Math.PI * 2;
if (sf && deltaAng < 0) deltaAng += Math.PI * 2;
console.debug(
"Building arc from values: cx=" + cx + ", cy=" + cy + ", startAng=" + startAng + ", deltaAng=" + deltaAng + ", endAng=" + (startAng + deltaAng) + ", sweepFlag=" + sf );
// path.absarc(cx, cy, rx, startAng, startAng + deltaAng, sf);
path.absellipse(cx, cy, rx, ry, startAng, startAng + deltaAng, sf);
} else {
path.lineTo(nx, ny);
}
您仍然可以使用SVGLoader加载SVG并检索ShapePath对象数组。然后,您可以使用这些形状创建挤出缓冲几何体。它实际上与
webgl\u loader\u svg.html中的工作流程相同,只需使用挤出BufferGeometry,您仍然可以使用SVGLoader加载svg并检索ShapePath对象数组。然后,您可以使用这些形状创建挤出缓冲几何体。它实际上与webgl\u loader\u svg.html中的工作流程相同,只需使用ExtrudeBufferGeometry查看或将svg文件拖放到屏幕上;谢谢,@WestLangley,但是我想要我的2d形状的3d拉伸。您仍然可以使用SVGLoader
加载SVG并检索ShapePath
对象数组。然后可以使用这些形状创建挤出缓冲几何体。实际上,这与webgl\u loader\u svg.html中的工作流程相同,只是ExtrudeBufferGeometry
。哇,真希望我早就问过了。这很有效。请在Mugen87写一个答案。工作版本:顺便说一句:不错的代码笔!:)查看或将svg文件拖放到屏幕上;谢谢,@WestLangley,但是我想要我的2d形状的3d拉伸。您仍然可以使用SVGLoader
加载SVG并检索ShapePath
对象数组。然后可以使用这些形状创建挤出缓冲几何体。实际上,这与webgl\u loader\u svg.html中的工作流程相同,只是ExtrudeBufferGeometry
。哇,真希望我早就问过了。这很有效。请在Mugen87写一个答案。工作版本:顺便说一句:不错的代码笔!:)
THREE.ShapePath.prototype.absarc = function( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) {
this.currentPath.absarc(aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise);
};
THREE.ShapePath.prototype.absellipse = function( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise ) {
this.currentPath.absellipse( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise );
};