# 游戏开发基础(十五)

1 给定所点击的屏幕点s，求出它在投影窗口中的对应点p
2 计算拾取射线，即自坐标原点发出且通过点p的那条射线
3 将拾取射线和物体模型变换至同一坐标系中
4 进行物体/射线的相交判断，相交物体即为用户所拾取的屏幕对象

2/Width     0         0         0
0       -Height/2     0         0
[ 0           0       MaxZ-MinZ   0   ]
X+Width/2   Y+Height/2   MinZ       1

sx = px(Width/2) + X + Width/2
sy = py(Height/2) + Y + Height/2

px = (2sx -2X-Width)/Width
py = (-2sy + 2Y + Height)/Height

px = 2*sx/Width -1
py = 2*sy/Width +1
pz = 1

px = (2x/viewporWidth -1)(1/P00)
py = (2y/viewporHeight +1)(1/P11)
pz = 1

u = p-p0 = (px,py,1) - (0,0,0) = p

d3d::Ray CalcPickingRay(int x,int y)
{
float px = 0.0f;
float py = 0.0f;

D3DVIEWPORT9 vp;
Device->GetViewport(&vp);

D3DXMATRIX proj;
Device->GetTransfrom(D3DTS_PROJECTION,&proj);

px = (((2.0f*x)/vp.Width)-1.0f)/proj(0,0);
py = (((-2.0f*y)/vp.Height)+1.0f)/proj(1,1);

d3d::Ray ray;
ray._origin    = D3DXVECTOR3(0.0f,0.0f,0.0f);
ray._direction = D3DXVECTOR3(px,py,1.0f);

return ray;
}

Ray结构:
struct Ray
{
D3DXVECTOR3 _origin;
D3DXVECTOR3 _direction;
};

void TransformRay(d3d::Ray* ray,D3DXMATRIX * T)
{
//transform the ray's origin ,w = 1
D3DXVec3TransformCoord(
&ray->_origin,
&ray->_origin,
T);
// transfrom the ray's direction ,w = 0
D3DXVec3TransformNormal(
&ray->_direction,
&ray->_direction,
T);
// normalize the direction
D3DXVec3Normalize(&ray->_direction,&ray->_direction);
}

D3DXVec3TransformCoord和D3DXVec3TransformNormal均以3D向量作为其参数，注意，D3DXVec3TransformCoord参数第4个分量应理解为w = 1,而是用D3DXVec3TransformNormal时，参数第4个分量应理解为w = 0 ，所以，用D3DXVec3TransformCoord来实现点变换，用D3DXVec3TransformNormal实现向量变换

|| p -c || - r = 0

||p(t) -c|| -r = 0
||p0 + tu -c || -r = 0

At*t +Bt +C = 0;

t0 = (-B +squrt(B*B-4AC))/2A, t1 = (-B -squrt(B*B-4AC))/2A

bool RaySphereIntTest(d3d::Ray* ray,d3d::BoundingSphere* sphere)
{

D3DXVECTOR3 v = ray ->_origin-sphere->_center;
float b = 2.0f * D3DXVec3Dot(&ray->_direction,&v);

// find the discriminant
float discriminant = (b*b) - (4.0f*c);

// test for imaginary number
float discriminant = (b*b) - (4.0f*c);

// test for imaginary number
if(discriminant < 0.0f)
return false ;

discriminant = sqrtf(discriminant )

float s0  = (-b + discriminant) /2.0f;
float s1  = (-b - discriminant) /2.0f;

//if a solution is >= 0,then we intersected the sphere
if (s0 >= 0.0f || s1 >= 0.0f)
return true;

return false;
}

struct BoundingSphere
{
BoundingSphere();
D3DXVECTOR3 _center;
};

• 本文已收录于以下专栏：

## Direct 3D和XNA游戏开发基础（C#语言版）（奋斗的小鸟）_PDF 电子书

• tjoy2005
• 2013年10月11日 19:32
• 1534

## 游戏编程之十五 DirectDraw 的基本知识

DirectDraw 游戏编程基础(2) 游戏使计算机的发展超越了晶体管时代              例程1(DDEX1):DirectDraw 的基本知识 在使用 Dir...
• zhangchen124
• 2016年06月22日 21:32
• 699

## 15数码问题

15数码问题 1878年，美国最伟大的谜题专家"Sam Loyd发明了15数码谜题。这个谜题由一个正方形盒子和15个编号为1，2，...，15的正方形滑块组成，每个滑块的边长是盒子边长的1/4，因此...
• jiyanfeng1
• 2013年01月27日 10:55
• 3981

## [从头读历史] 第280节 诗经目录以及十五国风的地域分布

• mwsister
• 2016年07月01日 14:40
• 670

## Android开发入门——推箱子游戏开发实战（十五，终结）

• yedouble
• 2017年07月03日 13:24
• 593

## 15个数字由大到小排序

• abcd12fg34567
• 2016年04月03日 14:14
• 212

## [UVA10181]十五数码解题报告

• TA201314
• 2015年05月05日 21:44
• 1261

## uva 10181 - 15-Puzzle Problem 十五数码 IDA*

• yan_____
• 2012年11月24日 12:45
• 2330

## USB开发基础：USB命令（请求）和USB描述符

• kevinhg
• 2010年10月01日 00:16
• 3773

## 【基础】web开发基础知识

• my_God_sky
• 2016年01月19日 18:23
• 1071

举报原因： 您举报文章：游戏开发基础(十五) 色情 政治 抄袭 广告 招聘 骂人 其他 (最多只允许输入30个字)