球体/圆形位于位图中心。
这个方程式是什么?
球体/圆形位于位图中心。
这个方程式是什么?
我不太了解人们如何编写3D程序,所以我只提供纯数学知识,希望有用。
半径为1,以原点为中心的球体是满足以下条件的点的集合:
x2 + y2 + z2 = 1
我们想要找到一个在该球体上已知x和y坐标的点的三维坐标。因此,只需解出z:
z = ±sqrt(1 - x2 - y2)。
现在,让我们考虑一个从球体外指向外部的单位向量。它是一个单位球体,因此我们可以使用从原点到(x,y,z)的向量,即 <x,y,z>。
现在,我们想要在(x,y,z)处求球体的切平面方程,但这将使用其自己的x、y和z变量,因此我将使其在(x0,y0,z0)处切于球体。这很简单:
x0x + y0y + z0z = 1
希望这有所帮助。
(原帖作者):
你的意思是像这样:
const int R = 31, SZ = power_of_two(R*2);
std::vector<vec4_t> p;
for(int y=0; y<SZ; y++) {
for(int x=0; x<SZ; x++) {
const float rx = (float)(x-R)/R, ry = (float)(y-R)/R;
if(rx*rx+ry*ry > 1) { // outside sphere
p.push_back(vec4_t(0,0,0,0));
} else {
vec3_t normal(rx,sqrt(1.-rx*rx-ry*ry),ry);
p.push_back(vec4_t(normal,1));
}
}
}
如果我将法线视为颜色并将其绘制,它确实会产生一个漂亮的球形阴影效果;是这样吗?
(TZ)
很抱歉,我不熟悉 C++ 的这些方面。很长时间以前我使用过该语言,但最近没有使用。
double x = 2.0 * pixel_x / bitmap_size - 1.0;
double y = 2.0 * pixel_y / bitmap_size - 1.0;
double r2 = x*x + y*y;
if (r2 < 1)
{
// Inside the circle
double z = sqrt(1 - r2);
.. here the normal is (x, y, z) ...
}
显然,由于缺少维度,您只能假设所有点都在球的一半或类似位置,因此受到限制。除此之外,这很简单。
圆的中心具有正好朝向内部或外部的法线,垂直于绘制圆的平面。
圆边缘上的每个点都朝向中心,因此您可以计算出该点的法线。
对于位于中心和边缘之间的任何点,您使用距离中心的距离和一些简单的三角函数(我暂时无法想起)进行计算。在某些点上,lerp大致准确,但不完全符合您的需求,因为它是曲线。不过,这是一个简单的曲线,并且您知道开始和结束值,因此找出它们只需要一个简单的方程。
X * sin(a) + Y * cos(A)
,对吗? - ssube我想我明白你想做什么:为图像生成深度数据的网格。有点像对球进行光线追踪。
在这种情况下,你需要一个射线-球体相交测试:
http://www.siggraph.org/education/materials/HyperGraph/raytrace/rtinter1.htm
你的光线将是简单的垂直光线,基于你的U/V坐标(乘以2,因为你的球体直径为2)。这将给你球体正面的点。
从那里开始,按照下面的方法计算法线(点 - 原点
,半径已经是1个单位)。
从上面的链接中剪切而来:
你必须结合两个方程:
为此,计算你的光线(x *像素/宽度,y *像素/宽度,z: 1),然后:
将其代入二次方程:
检查判别式(B^2 - 4*C),如果有实根,则交点为:
表面法线为:
总结:
所以,既然我们谈论单位值和指向Z
的光线(没有x或y分量),我们可以将这些方程简化:
光线:
X0 = 2 * pixelX / width
Y0 = 2 * pixelY / height
Z0 = 0
Xd = 0
Yd = 0
Zd = 1
球体:
因素:
C
=(X0-1)^ 2 +(Y0-1)^ 2 +(0-1)^ 2-1
=(X0-1)^ 2 +(Y0-1)^ 2
判别式
=(-2)^ 2-4 * 1 * C
= 4-4 * C
从这里开始:
If discriminant < 0:
Z = ?, Normal = ?
Else:
t = (2 + (discriminant) ^ 1 / 2) / 2
If t < 0 (hopefully never or always the case)
t = -t
然后:
更进一步的推导:
直觉上看,C(X^2 + Y^2
)和平方根是这里最突出的数字。如果我对我的数学(特别是对和的指数进行变换)有更好的回忆,那么我敢打赌我可以将其推导到Tom Zych给你的内容。由于我不能,所以我会像上面那样留下它。