Пересечение линии / луча не работает должным образом - PullRequest
0 голосов
/ 30 ноября 2011

Я работаю над созданием трассировщика лучей. Вы знаете, для удовольствия. Пока что все идет по плану, но как только я начал преобразовывать свои тестовые сферы, все пошло не так.

Фундаментальной концепцией является использование одной из стандартных форм в качестве источника, преобразование лучей камеры в пространство объекта, а затем пересечение.

Пока сфера идентична в пространстве объектов и мировом пространстве, она работает как положено, но как только сферы масштабируются, нормали и точки пересечения становятся дикими.

Я ломал голову и перебирал этот код снова и снова, но я просто не могу найти ошибку. Буду благодарен за свежие глаза.

@implementation RTSphere

- (CGFloat)intersectsRay:(RTRay *)worldRay atPoint:(RTVector *)intersection normal:(RTVector *)normal material:(RTMaterial **)material {
  RTRay *objectRay = [worldRay rayByTransformingByMatrix:self.inverseTransformation];

  RTVector D = objectRay.direction;
  RTVector O = objectRay.start;

  CGFloat A, B, C;

  A = RTVectorDotProduct(D, D);
  B = 2 * RTVectorDotProduct(D,O);
  C = RTVectorDotProduct(O, O) - 0.25;

  CGFloat BB4AC = B * B - 4 * A * C;

  if (BB4AC < 0.0) {
    return -1.0;
  }

  CGFloat t0 = (-B - sqrt(BB4AC)) / 2 * A;
  CGFloat t1 = (-B + sqrt(BB4AC)) / 2 * A;

  if (t0 > t1) {
    CGFloat tmp = t0;
    t0 = t1;
    t1 = tmp;
  }

  if (t1 < 0.0) {
    return -1.0;
  }

  CGFloat t;

  if (t0 < 0.0) {
    t = t1;
  } else {
    t = t0;
  }

  if (material) {
    *material = self.material;
  }

  if (intersection) {
    RTVector isect_o = RTVectorAddition(objectRay.start, RTVectorMultiply(objectRay.direction, t));

    *intersection = RTVectorMatrixMultiply(isect_o, self.transformation);

    if (normal) {
      RTVector normal_o = RTVectorSubtraction(isect_o, RTMakeVector(0.0, 0.0, 0.0));
      RTVector normal_w = RTVectorUnit(RTVectorMatrixMultiply(normal_o, self.transformationForNormal));

      *normal = normal_w;
    }
  }

  return t;
}

@end

Почему нормали и точки пересечения не переводятся в мировое пространство, как ожидалось?

Редактировать: Я умеренно уверен, что мои векторные и матричные функции математически надежны; и я думаю, что это в основном ошибка метода, но я понимаю, что могу ошибаться.

1 Ответ

1 голос
/ 01 декабря 2011

Здесь много "RT * кода" здесь "за кулисами", и мы не знаем, как это правильно, поэтому я бы хотел убедиться, что у вас есть хорошие модульные тесты этих математических функций.Из моего опыта управления преобразованиями я бы больше всего подозревал, что это rayByTransformingByMatrix: или значение inverseTransformation.Я обнаружил, что очень легко ошибиться, когда вы комбинируете преобразования.Вращение и масштабирование - это не то же самое, что вращение и масштабирование.

В какой момент у вас это не получается?Вы уверены, что objectRay само по себе правильно?(Если это не так, то остальные функции не имеют значения.) Опять же, юнит-тест - ваш друг.Вы должны вручную рассчитать несколько ситуаций, а затем написать модульные тесты, чтобы убедиться, что ваши методы возвращают правильные ответы.

...