This is the trouble code..
multresult := mult(mult(temp, quatview), conjugate(temp));
Full procedure
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
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;
and conjugate
function TForm2.conjugate( var quat:TQuaternion) :TQuaternion;
begin
quat.x := -quat.x;
quat.y := -quat.y;
quat.z := -quat.z;
result := quat;
end;
and if needed TQuaternion
type
TQuaternion = class
x: single;
y: single;
z: single;
w: single;
end;
any idea why i get this error and how to fix it?
The answer to the question you asked is that the parameters to mult should be const. You don't modify them (and you should not), so make them const. Then your code compiles.
In a similar vein, it's bad form for Conjugate to modify its input parameter. That makes the function horrid to use. Don't do that.
Consider this line:
multresult := mult(mult(temp, quatview), conjugate(temp) );
Since conjugate modifies temp, you'd better hope that the call to conjugate is made after the other use of temp. The language makes no such guarantee. So, cross your fingers!
One of the principles worth following with arithmetic code is that input parameters/operands should never be modified, and that functions always return new values. Follow this principle and you'll never fall into trap highlighted above. See the second part of my answer for an illustration.
However the code won't work even with these changes because you are not instantiating any instances of the TQuaternion class. Are you sure that it's not a record?
The real forward progress will come when you create a good quaternion type. This should be a value type since arithmetic operations are better suited to value types for a number of reasons.
In modern Delphi you want to use a record with operators. Here's a flavour of what you need, ready to extend as you need.
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;
With this type your multiplication call becomes:
multresult := temp*quatview*temp.Conjugate;
You'll surely want to write more operators and helper functions for this type.
It's really important to move the arithmetic functions into this type and out of your form. Don't use your high level GUI form class to implement low level arithmetic.
One final piece of advice. Your code has repeated mis-use of var parameters. I suggest you treat var parameters as things to be avoided. Try to write code without them if possible.
The mult
method declares the A
parameter as a var
so you must pass a variable to the method in order to work, like so.
multresult := mult(temp, quatview);
multresult := mult(multresult, conjugate(temp));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With