首先定义Ray类,包含起始点,方向字段,属性,各构造函数。定义Sphere类,包含球心,半径字段,属性,各构造函数。并编写代码测试写的上述类是否正确。
Ray类代码如下:
class Ray
{
Point3D _origin;
Vector3D _direction;
internal Point3D Origin { get => _origin; set => _origin = value; }
internal Vector3D Direction { get => _direction; set => _direction = value; }
//构造函数
//构造函数一
public Ray()
{
_origin = new Point3D();
_direction = new Vector3D();
}
//构造函数二
public Ray(Point3D point3D,Vector3D vector)
{
_origin = point3D;
_direction = vector;
}
}
Sphere类代码如下:
class Sphere
{
Point3D _center;
double _radius;
public double Radius { get => _radius; set => _radius = value; }
internal Point3D Center { get => _center; set => _center = value; }
//构造函数
//构造函数一
public Sphere()
{
_center = new Point3D();
_radius = 1.0;
}
//构造函数二
public Sphere(Point3D point ,double r)
{
_center = point;
_radius = r;
}
}
然后就是查询资料,推导出光线与球体求交的公式,以下是推导过程:
因为
(
P
(
t
)
−
C
)
∗
(
P
(
t
)
−
C
)
−
r
2
=
0
,
(P(t)-C)*(P(t)-C)-r^2=0 ,
(P(t)−C)∗(P(t)−C)−r2=0,
P
(
t
)
=
O
+
t
∗
d
,
P(t)=O+t*d ,
P(t)=O+t∗d,
所以
(
O
+
t
∗
d
−
C
)
∗
(
O
+
t
∗
d
−
C
)
−
r
2
=
0.
(O+t*d-C)*(O+t*d-C)-r^2=0 .
(O+t∗d−C)∗(O+t∗d−C)−r2=0.
所以
t
2
∗
d
∗
d
+
t
2
∗
(
d
∗
(
O
−
C
)
)
+
(
O
−
C
)
∗
(
O
−
C
)
−
r
2
=
0.
t^2*d*d+t^2*(d*(O-C))+(O-C)*(O-C)-r^2=0 .
t2∗d∗d+t2∗(d∗(O−C))+(O−C)∗(O−C)−r2=0.
最后得出:
a
=
d
∗
d
,
b
=
2
∗
(
d
∗
(
O
−
C
)
)
,
c
=
(
O
−
C
)
∗
(
O
−
C
)
−
r
2
a=d*d, b=2*(d*(O-C)), c=(O-C)*(O-C)-r^2
a=d∗d,b=2∗(d∗(O−C)),c=(O−C)∗(O−C)−r2
第三步:利用题目2得到的信息,Ray类中编写bool Hit(Sphere s)方法,该方法用于判断一条光线是否与球体相交。
同样,以上只是个人的思考,如果有什么问题希望大家多多指出来(・(ェ)・)