2013-08-18 21 views
7

Bu hata kodu bir ..sabit nesne var parametre olarak kabul edilemez

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

Tam prosedür

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; 

fazla fonksiyon

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; 

ve konjugat

function TForm2.conjugate(var quat:TQuaternion) :TQuaternion; 
    begin 
    quat.x := -quat.x; 
    quat.y := -quat.y; 
    quat.z := -quat.z; 
    result := quat; 
    end; 
ben bu hatayı alıyorum ve nasıl bunu düzeltmek için neden

ve eğer

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

TQuaternion

bir fikrin gerekli?

cevap

13

Sorduğunuz soruya verilen yanıt, çoklu parametrelerin const olması gerektiğidir. Onları değiştirmezsin (ve yapmamalısın), bu yüzden onları yap. Sonra kodun derler.

Benzer şekilde, Konjugat'ın giriş parametresini değiştirmesi kötü bir biçimdir. Bu, işlevi kullanmak için korkunç yapar. Bunu yapma. eşlenik temp değiştirir yana

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

, daha iyi konjugat çağrı sıcaklığında diğer kullanımdan sonra yapılır umut ediyorum:

bu satırı düşünün. Dil böyle bir garanti vermez. Yani, parmaklarını çapraz!

Aritmetik kodla izlemeye değer ilkelerden biri, giriş parametrelerinin/işlenenlerin hiçbir zaman değiştirilmemesi ve bu işlevlerin her zaman yeni değerlerini döndürmesidir. Bu prensibi izleyin ve asla yukarıda vurgulanan tuzağa düşmeyeceksiniz. Bir örnek için cevabımın ikinci bölümüne bakın. Bu kod, TQuaternion sınıfının herhangi bir örneğini başlatmıyor olduğunuzdan, ancak bu kodla çalışmayacaktır, ancak bu kod çalışmayacaktır. Bir kayıt olmadığından emin misin?


İyi bir quaternion türü oluşturduğunuzda, gerçek ileriye dönük ilerleme gerçekleşecektir. Bu, aritmetik işlemlerin çeşitli nedenlerle türlere değer vermek için daha uygun olduğu için bir değer türü olmalıdır.

Modern Delphi'de operatörlerle bir kayıt kullanmak istersiniz. İhtiyacınız olana kadar uzanmaya hazır, ihtiyacınız olan bir lezzet. senin çarpma çağrı olur Bu tür

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; 

Bu tip operatörler ve yardımcı işlevler daha yazmak istiyorum kesinlikle edeceğiz.

Bu türü içine ve formun dışarı aritmetik işlevleri taşımak için gerçekten çok önemli. Düşük seviye aritmetiğini uygulamak için yüksek seviye GUI form sınıfınızı kullanmayın.

Son bir öneri. Kodunuz, var parametrelerinin yanlış kullanımını tekrarladı. Var parametrelerin önlenmesi gereken şeyler olarak değerlendirmenizi öneririm. Mümkünse onlardan kod yazmayı deneyin.

+0

Teşekkürler, harika tavsiye. Bunu tekrar deneyeceğim ve kullanacağım ... şu andan itibaren firemonkey kamera ile nasıl kullanılacağını öğrenmem gerekiyor .. FMX'in pozisyonu (x, y, z) ve döndürme (x, y, z) opengl'in görünümünü (positionx, y, z, viewx, y, z, upx, y, z) bulabildiğim örnekler. –

5

mult yöntemi A parametresini var olarak bildirir, böylece çalışmak için yönteme bir değişken iletmeniz gerekir.

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

sayesinde bence –

+1

@GlenMorse eğer çünkü bir derleme hatası ** var ** olarak parametreyi beyan .. ben bunu bölmek olduğunu bilmiyordum. Bu vardan kurtulmaya çalışın ve iyi olacak –

+5

Bu cevabın problemin biraz sığ bir analizi olduğunu düşünüyorum. Evet, bu değişiklik kodun derlenmesini sağlayacaktır. Fakat daha sonra birçok problemle uğraşıyorsunuz. Ve o zaman bile, burada önerilen çözüm zayıftır çünkü üstesinden gelinmesi gereken ilk hata, bir var parametresinin hatalı kullanılmasıdır. Hangi yinelenen bir tema gibi görünüyor. –

İlgili konular