这是故障代码..
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,conjugate(temp)); camera1.Position.x := multresult.x; camera1.Position.y := multresult.y; camera1.Position.z := multresult.z; end;
多功能
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;
解决方法
你问的问题的答案是mult的参数应该是const.你不修改它们(你不应该),所以把它们变成const.然后你的代码编译.
类似地,Conjugate修改其输入参数是不好的形式.这使得功能可怕使用.不要那样做.
考虑这一行:
multresult := mult(mult(temp,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表单类来实现低级算术.