Постоянный объект не может быть передан как параметр var

это код неисправности..

multresult := mult(mult(temp, quatview), conjugate(temp));

полный порядок

procedure TForm2.RotateCamera(var angle: Single; x: Single; y: Single; z: Single);
var
    temp, QuatView, multResult : TQuaternion;
begin
    temp.x := x * sin(Angle/2);
    temp.y := y * sin(Angle/2);
    temp.z := z * sin(Angle/2);
    temp.w := cos(Angle/2);

    quatview.x := camera1.Position.x;
    quatview.y := camera1.Position.y;
    quatview.z := camera1.Position.z;
    quatview.w := 0;

    multresult := mult(mult(temp, quatview), conjugate(temp));

    camera1.Position.x := multresult.x;
    camera1.Position.y := multresult.y;
    camera1.Position.z := multresult.z;
end;

функция mult

function TForm2.mult(var A: TQuaternion; B: TQuaternion) :TQuaternion;
 var
   c : TQuaternion;
begin
  C.x := A.w*B.x + A.x*B.w + A.y*B.z - A.z*B.y;
  C.y := A.w*B.y - A.x*B.z + A.y*B.w + A.z*B.x;
  C.z := A.w*B.z + A.x*B.y - A.y*B.x + A.z*B.w;
  C.w := A.w*B.w - A.x*B.x - A.y*B.y - A.z*B.z;
result := C;
End;

и конъюгата

 function TForm2.conjugate( var quat:TQuaternion) :TQuaternion;
  begin
     quat.x := -quat.x;
     quat.y := -quat.y;
     quat.z := -quat.z;
     result := quat;
  end;

и при необходимости TQuaternion

type
  TQuaternion = class
    x: single;
    y: single;
    z: single;
    w: single;
  end;

любая идея, почему я получаю эту ошибку и как ее исправить?

2 ответов


ответ на заданный вами вопрос заключается в том, что параметры для mult должны быть const. Вы не изменяете их (и вы не должны), поэтому сделайте их const. Затем ваш код компилируется.

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

рассмотрим эту строку:

multresult := mult(mult(temp, quatview), conjugate(temp) );

поскольку конъюгат изменяет temp, вам лучше надеяться, что вызов конъюгата будет сделан после другого использование temp. Язык не дает такой гарантии. Так что, скрестите пальцы!

один из принципов, который стоит следовать с арифметическим кодом, заключается в том, что входные параметры/операнды никогда не должны изменяться, и что функции всегда возвращают новая значения. Следуйте этому принципу, и вы никогда не попадете в ловушку, выделенную выше. См. вторую часть моего ответа для иллюстрации.

однако код не будет работать даже с этими изменениями, потому что вы не создание экземпляра любых экземпляров класса TQuaternion. Вы уверены, что это не рекорд?


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

в современных Delphi вы хотите использовать запись с операторами. Вот аромат того, что вам нужно, готов расширить, как вам нужно.

type
  TQuaternion = record
    x: single;
    y: single;
    z: single;
    w: single;
    function Conjugate: TQuaternion;
    class operator Multiply(const A, B: TQuaternion): TQuaternion;
  end;

function TQuaternion.Conjugate: TQuaternion;
begin
  Result.x := -x;
  Result.y := -y;
  Result.z := -z;
  Result.w := w;
end;

class operator TQuaternion.Multiply(const A, B: TQuaternion): TQuaternion;
begin
  Result.x := A.w*B.x + A.x*B.w + A.y*B.z - A.z*B.y;
  Result.y := A.w*B.y - A.x*B.z + A.y*B.w + A.z*B.x;
  Result.z := A.w*B.z + A.x*B.y - A.y*B.x + A.z*B.w;
  Result.w := A.w*B.w - A.x*B.x - A.y*B.y - A.z*B.z;
end;

С этим типом ваш умножение вызова становится:

 multresult := temp*quatview*temp.Conjugate;

вы наверняка захотите написать больше операторов и вспомогательных функций для этого типа.

очень важно переместить арифметические функции в этот тип и из вашей формы. Не используйте класс формы GUI высокого уровня для реализации арифметики низкого уровня.

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


на mult метод декларирует