Я предполагаю, что вы имеете в виду следующий метод:
- (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 единиц не будут видны.
Таким образом, чтобы выполнить код, сначала матрицу проекции, которая устанавливает усечку, и матрицу просмотра камеры, которая просто поворачивает объект так, чтобы он был правильным по отношению к камере, умножаются вместе. Затем для каждого места интереса его местоположение умножается на матрицу viewProjection. Это спроектирует местоположение места интереса в виде усечения, используя поворот и перспективу.
Следующие две строки преобразуют преобразованное местоположение места в так называемые нормализованные координаты устройства. 4-компонентный вектор должен быть свернут в трехмерное пространство, это достигается путем проецирования его на плоскость 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
Успехов //
Итак, мы умножаем матрицу проекции и матрицу камеры просто для поворота объекта в режиме пропеллера? Это правильно? – Varyvol
матрица камеры вращает место в соответствии с текущим вращением устройства, в '- (void) onDisplayLink: (id) отправитель. матрица проекции проектирует местоположение в усечку, как описано выше. умножая эти матрицы вместе, два преобразования могут выполняться в одномерном векторном умножении в позиции мест. – Tark
Отлично, это все, что мне нужно. У меня осталось только одно сомнение: почему мы проверяем, находится ли место в кубе с боковой длиной 2 с началом [0, 0, 0]? Это из-за того, как создается матрица проекции или она всегда одна и та же, независимо от того, как создается матрица? – Varyvol