我有一个沿着我的视线倾斜一个角度的制服环。戒指的尺寸为:
9.5 : inner radius
10.5 : outer radius
-3 to 3 : height of the ring
环上有很多来源,我试图计算从每个来源绘制的线是否沿着我的方向穿过这个环。如果它通过环,它将通过该环显示多少路径长度(例如,通过环两次或一次或从不)。
我有从每个来源到我的视线的方向向量,我使用一个简单的向量加法沿着我的方向递增。
我的程序存在问题:
仅检查路径长度是否小于环的外半径。如何检查我的信号源是否通过了两个响铃?
任何帮助将不胜感激!!
我的节目:
/********************************************************************
xn, yn, zn : coordinates of the sources
ns_ux, ns_uy, ns_uz : unit vectors for these sources
ns : distance of a source from the sun
int_val : path length
********************************************************************/
int main(){
FILE *fp=NULL;
fp=fopen("Av_path.txt","w");
int k,number=9;
float step=0.02;
float ns_ux[number],ns_uy[number],ns_uz[number],xn[number], yn[number],zn[number],l[number],b[number],ns[number],int_val,x_comp,y_comp,z_comp,radial;
FILE* val= NULL;
val=fopen("novae_uniform_unitvectors.txt", "r");
for(k=0;k<=(number-1);k++){
fscanf(val,"%f %f %f %f %f %f %f %f %f", &xn[k], &yn[k], &zn[k], &ns_ux[k], &ns_uy[k], &ns_uz[k], &l[k], &b[k], &ns[k]);
float u=0.;
do {
u=u+step;
printf("%f\t%f\n" ,u,radial);
x_comp=xn[k]+u*ns_ux[k];
y_comp=yn[k]+u*ns_uy[k];
z_comp=zn[k]+u*ns_uz[k];
radial=pow((x_comp*x_comp+y_comp*y_comp+z_comp*z_comp),0.5);
}while (radial <10.5);
if(u >= 1.0 && z_comp >= -3.0 && z_comp <= 3.0){
int_val=1.0; // ring's width is only 1 unit
}
else if(u < 1.0 && z_comp >= -3.0 && z_comp <= 3.0) {
int_val=u-step;
}
else {
int_val=0.;
}
fprintf(fp, "%f\t%f\t%f\t%f\t%f\t%f\t%f\t%f\t%f\t%f\t%f\n",xn[k], yn[k], zn[k], ns[k], l[k], b[k], radial,z_comp,u,u/step, int_val);
}
return 0.;
}
答案 0 :(得分:0)
将文字与代码结合起来时遇到了一些麻烦。看一下代码,我看到(xn, yn, zn)
处的一个点和(ns_ux, ns_uy, ns_uz)
方向上从该点发出的光线。我认为你想知道光线与你的戒指相交的时间和地点。
目前你做了一些非常讨厌的循环来找到一个交叉点。让我们更优雅。您正在寻找一些u
sqrt(x_comp²+y_comp²+z_comp²)=10.5
。这是要求光线与球体相交的点,所以如果你想在这里使用圆柱体,你可能想要丢弃三个坐标中的一个。我现在会坚持使用球体,但这很容易适应。
对这个等式做的第一件事是将两边都对齐:x_comp²+y_comp²+z_comp²=10.5²
。现在,您可以将该平方和解释为向量v
与其自身的点积:v∙v = 10.5²
。但是,该向量v
实际上是位置n
加u
次的某些向量ns_u?
,我将其称为s
,因此您拥有(n + u*s)∙(n + u*s)=10.5²
}。现在你可以利用这样一个事实,即分布式定律可以应用于点积,因为它是双线性的。所以你也可以把它写成
(n∙n - 10.5²) + (2n∙s)u + (s∙s)u² = 0
这是u
中的二次方程式,您可以使用二次方程式求解。在代码中你有
nn = xn*xn + yn*yn + zn*zn;
ns = xn*sn_ux + yn*sn_uy + zn*sn_uz;
ss = sn_ux*sn_ux + sn_uy*sn_uy + sn_uz*sn_uz;
r = 10.5;
a = ss;
b = 2*ns;
c = nn - r*r;
d = b*b - 4*a*c;
if (d < 0) {
// doesn't intersect sphere of radius r at all, but passes outside.
} else if (d == 0) {
// tangential to sphere, numerically extremely unlikely
// so you might want to merge this case with the one below.
} else {
// two points of intersection, parametrized by u1 and u2.
sqrtd = sqrt(d);
u1 = (-b+sqrtd)/(2*a);
u2 = (-b-sqrtd)/(2*a);
}
上面与线与球体相交。如果您想要一条光线,那么您将自己局限于解决方案u≥0
。您可能希望对较小的半径执行相同的计算。在两个点中与较大球体相交但在较小点上不相交的光线仅穿过这两个球体之间的区域一次。所有这一切都假设是完整的领域;您仍然需要应用该厚度约束来查看光线在环的高度之外的位置。我无法提供更多细节,因为我还没有完全理解你在这方面的问题,但我希望上述内容能够帮助你自己解决这个问题。如果你想要一个圆柱而不是一个球体,只需从上面的计算中删除所有z
个组件。