我假设你指的是以下方法:
- (void)drawRect:(CGRect)rect
{
if (placesOfInterestCoordinates == nil) {
return;
}
mat4f_t projectionCameraTransform;
multiplyMatrixAndMatrix(projectionCameraTransform, projectionTransform, cameraTransform);
int i = 0;
for (PlaceOfInterest *poi in [placesOfInterest objectEnumerator]) {
vec4f_t v;
multiplyMatrixAndVector(v, projectionCameraTransform, placesOfInterestCoordinates[i]);
float x = (v[0] / v[3] + 1.0f) * 0.5f;
float y = (v[1] / v[3] + 1.0f) * 0.5f;
if (v[2] < 0.0f) {
poi.view.center = CGPointMake(x*self.bounds.size.width, self.bounds.size.height-y*self.bounds.size.height);
poi.view.hidden = NO;
} else {
poi.view.hidden = YES;
}
i++;
}
}
这是对感兴趣的位置执行类似OpenGL的顶点变换,以检查它们是否在可视的视锥体中。视锥体在以下行中创建:
createProjectionMatrix(projectionTransform, 60.0f*DEGREES_TO_RADIANS, self.bounds.size.width*1.0f / self.bounds.size.height, 0.25f, 1000.0f)
这会设置一个60度视野、近裁剪平面为0.25和远裁剪平面为1000的锥体。任何距离超过1000个单位的感兴趣点都将不可见。
因此,为每个感兴趣的位置乘以视图投影矩阵。这将把感兴趣位置的位置投影到视图锥形体中,应用旋转和透视。
接下来的两行将地点的转换后的位置转换为所谓的规范化设备坐标。需要将4个分量向量缩减到3维空间,通过将其投影到平面w == 1上,通过除以向量的w分量v [3]来实现。然后可以通过检查其坐标是否位于边长为2且原点为[0,0,0]的立方体中,来确定该点是否在投影锥体内。在这种情况下,x和y坐标被偏差从范围[-1 1]到[0 1],以与UIKit坐标系相匹配,通过添加1并除以2来实现。
接下来,检查v [2]分量z是否大于0。这实际上是不正确的,因为它还没有被调整,应该检查它是否大于-1。这将检测感兴趣的位置是否在投影锥体的前半部分,如果是,则将对象视为可见并显示出来。
如果您不熟悉顶点投影和坐标系统,请注意这是一个具有相当陡峭学习曲线的重要主题。然而,在线上有很多相关材料,以下是一些入门链接:
http://www.falloutsoftware.com/tutorials/gl/gl0.htm
http://www.opengl.org/wiki/Vertex_Transformation
祝好运!//