我花了几个小时,但我最终开发了所有方程和 SVG 代码演示:http:
//jsfiddle.net/6b8oLhz0/9/
我使用过http://mathworld.wolfram.com/Ellipse.html仅给定方程,计算轴的中心、半径和旋转。代码中最有趣的部分可能是:
function ellipseBy3DCircle(circle){
var r=circle.radius;
var n=circle.normal;
var c=circle.center;
//Let (u,v) be a point of the Ellipse.
//Which point of the circle it represents?
//This 3-D point must have a form of (u*z,v*z,z) for some z,
//bacause it lays on a ray from observer (0,0,0) through (u,v,1) on the screen.
//A circle is an intersection of a plane with a sphere.
//So we have two conditions for our point :
//1) it has to belong to the plane given by the center and normal of the circle:
//(u*z-c.x)*n.x+ (v*z-c.y)*n.y + (z-c.z)*n.z = 0
//2) it has to belong to the sphere given by the center and radius
//(u*z-c.x)^2 + (v*z-c.y)^2 + (z-c.z)^2 = 0
//The first equation alows us to express z in terms of u,v and constants:
//z = (c.x*n.x+c.y*n.y+c.z*n.z) / (u*n.x+v*n.y+n.z)
// ^^^^^^^^^^^^ s ^^^^^^^^^ ^^^^ t(u,v) ^^^^
var s=c.x*n.x+c.y*n.y+c.z*n.z;
//t(u,v)=u*n.x+v*n.y+n.z
//The second equation gives us:
//zz(uu+vv+1)-2z(u*c.x+v*c.y+z*c.z)+c.x^2+c.y^2+c.z^2-r^2 = 0
// ^^^^^^^^ H ^^^^^^^^^
var H=c.x*c.x+c.y*c.y+c.z*c.z-r*r;
//Recall however, that z has u and v in denominator which makes it hard to solve/simplify.
//But z=s/t(u,v), so let us multiply both sides by t(u,v)^2 :
//ss*(uu+vv+1)-2*s*t(u,v)*(u*c.x+v*c.y+c.z)+t(u,v)^2*H=0
//ss*uu+ss*vv+ss-2*s*(u*n.x+v*n.y+n.z)*(u*c.x+v*c.y+c.z)+(u*n.x+v*n.y+n.z)*(u*n.x+v*n.y+n.z)*H=0
//By regrouping terms so as to match the ax^2+2bxy+cy^2+2dx+2fy+g = 0 formula, we get:
var A=s*s+H*n.x*n.x-2*s*n.x*c.x;
var B=H*n.x*n.y-s*n.x*c.y-s*n.y*c.x;
var C=s*s+H*n.y*n.y-2*s*n.y*c.y;
var D=H*n.x*n.z-s*n.x*c.z-s*n.z*c.x;
var F=H*n.y*n.z-s*n.y*c.z-s*n.z*c.y;
var G=s*s+H*n.z*n.z-2*s*n.z*c.z;
return ellipseByEquation(A,B,C,D,F,G);
}