Javascript 绘制正交投影的圆
我需要得到在正交空间中投影的圆的svg路径。 我想做的是创建一个具有以下参数的函数(在js中):Javascript 绘制正交投影的圆,javascript,svg,geometry,orthogonal,Javascript,Svg,Geometry,Orthogonal,我需要得到在正交空间中投影的圆的svg路径。 我想做的是创建一个具有以下参数的函数(在js中): 圆的位置 半径 圆圈平行于哪个面板 轴线倾角 这是我用来创建一个简单圆的函数(没有透视图) 我不想近似圆,创建数千个点并将它们全部投影,我希望有一条精确描述投影圆的路径 我能做什么?我正在从一个未发布的项目中提取一些东西,希望它对您有意义 假设你有两个三点元组,描述两个三角形,求出这两个三角形之间的变换矩阵他们可以这样描述包围一个圆的正方形: function arc_transform (tra
我能做什么?我正在从一个未发布的项目中提取一些东西,希望它对您有意义 假设你有两个三点元组,描述两个三角形,求出这两个三角形之间的变换矩阵他们可以这样描述包围一个圆的正方形:
function arc_transform (transform, arc) {
var co = Math.cos(arc.rotation/180*Math.PI),
si = Math.sin(arc.rotation/180*Math.PI);
var m = [
arc.rx * (transform.a * co + transform.c * si),
arc.rx * (transform.b * co + transform.d * si),
arc.ry * (transform.c * co - transform.a * si),
arc.ry * (transform.d * co - transform.b * si),
];
var A = (m[0] * m[0]) + (m[2] * m[2]),
B = 2 * (m[0] * m[1] + m[2] * m[3]),
C = (m[1] * m[1]) + (m[3] * m[3]),
K = Math.sqrt((A - C) * (A - C) + B * B);
if ((transform.a * transform.d) - (transform.b * transform.c) < 0) {
arc.sweep = !arc.sweep;
}
return {
rx: Math.sqrt(0.5 * (A + C + K)),
ry: Math.sqrt(0.5 * Math.max(0, A + C - K)),
rotation: Math.abs((A - C) / B) < 1e-6 ? 90 : Math.atan2(B, A - C)*90/Math.PI,
large: arc.large,
sweep: arc.sweep,
x: transform.a * arc.x + transform.c * arc.y + transform.e,
y: transform.b * arc.x + transform.d * arc.y + transform.f
};
};
从两个点列表生成变换矩阵:
var source = [s0, s1, s2]; // each point as coordinates {x, y}
var target = [t0, t1, t2];
function generate (source, target) {
var transform = [
{
a: 1, b: 0, c: 0, d: 1,
e: target[2].x,
f: target[2].y
},
{
a: 1, b: 0, c: 0, d: 1,
e: -source[2].x,
f: -source[2].y
}
];
source.forEach(point => {x: point.x - source[2].x, y: point.y - source[2].y});
target.forEach(point => {x: point.x - source[2].x, y: point.y - source[2].y});
var div = source[0].x * source[1].y - source[1].x * source[0].y;
var matrix = {
a: (target[0].x * source[1].y - target[1].x * source[0].y) / div,
b: (target[0].y * source[1].y - target[1].y * source[0].y) / div,
c: (target[1].x * source[0].x - target[0].x * source[1].x) / div,
d: (target[1].y * source[0].x - target[0].y * source[1].x) / div,
e: 0,
f: 0
};
transform.splice(1, 0, matrix);
return transform.reduce(function (m1, m2) {
return {
a: m1.a * m2.a + m1.c * m2.b,
b: m1.b * m2.a + m1.d * m2.b,
c: m1.a * m2.c + m1.c * m2.d,
d: m1.b * m2.c + m1.d * m2.d,
e: m1.a * m2.e + m1.c * m2.f + m1.e,
f: m1.b * m2.e + m1.d * m2.f + m1.f
}
}, { a: 1, b: 0, c: 0, d: 1, e: 0, f: 0 });
}
现在,如果您有一个absolutearc命令被描述为对象arc
{ rx, ry, rotation, large, sweep, x, y }
转换可以这样应用:
function arc_transform (transform, arc) {
var co = Math.cos(arc.rotation/180*Math.PI),
si = Math.sin(arc.rotation/180*Math.PI);
var m = [
arc.rx * (transform.a * co + transform.c * si),
arc.rx * (transform.b * co + transform.d * si),
arc.ry * (transform.c * co - transform.a * si),
arc.ry * (transform.d * co - transform.b * si),
];
var A = (m[0] * m[0]) + (m[2] * m[2]),
B = 2 * (m[0] * m[1] + m[2] * m[3]),
C = (m[1] * m[1]) + (m[3] * m[3]),
K = Math.sqrt((A - C) * (A - C) + B * B);
if ((transform.a * transform.d) - (transform.b * transform.c) < 0) {
arc.sweep = !arc.sweep;
}
return {
rx: Math.sqrt(0.5 * (A + C + K)),
ry: Math.sqrt(0.5 * Math.max(0, A + C - K)),
rotation: Math.abs((A - C) / B) < 1e-6 ? 90 : Math.atan2(B, A - C)*90/Math.PI,
large: arc.large,
sweep: arc.sweep,
x: transform.a * arc.x + transform.c * arc.y + transform.e,
y: transform.b * arc.x + transform.d * arc.y + transform.f
};
};
函数圆弧_变换(变换,圆弧){
var co=数学cos(圆弧旋转/180*Math.PI),
si=数学sin(圆弧旋转/180*Math.PI);
var m=[
arc.rx*(变换a*co+变换c*si),
arc.rx*(变换b*co+变换d*si),
arc.ry*(transform.c*co-transform.a*si),
arc.ry*(transform.d*co-transform.b*si),
];
变量A=(m[0]*m[0])+(m[2]*m[2]),
B=2*(m[0]*m[1]+m[2]*m[3]),
C=(m[1]*m[1])+(m[3]*m[3]),
K=数学sqrt((A-C)*(A-C)+B*B);
if((transform.a*transform.d)-(transform.b*transform.c)<0){
arc.sweep=!arc.sweep;
}
返回{
rx:Math.sqrt(0.5*(A+C+K)),
ry:Math.sqrt(0.5*Math.max(0,A+C-K)),
旋转:数学abs((A-C)/B)<1e-6?90:数学atan2(B,A-C)*90/Math.PI,
大的:弧,大的,
扫掠:圆弧扫掠,
x:transform.a*arc.x+transform.c*arc.y+transform.e,
y:变换.b*弧.x+变换.d*弧.y+变换.f
};
};
使用CSS 3d变换来变换所有形状”3.圆圈与“如何描述/定义这些面板?可能我没有正确理解您的用例,但使用?@RecencyEffect SVG变换不能进行非仿射投影,如果OP真的想这样做的话。他说“正交投影”。这些是仿射的,不是吗?(诚实的问题,我的数学知识不是很好)你能不能把变换矩阵应用到弧(或圆)元素上?@PeterCollingridge当然,但OP说“我想有一条精确描述投影圆的路径”。