# Wie Transform3D für PosPathInterpolator bestimmen



## aze (28. Jul 2010)

Hi Ich hab ein paar Probleme mit den PosPathInterpolator. Ich möchte mithilfe dieses Interpolators verschiedene Flächen in Y-Richtung verschieben.

Erstmal die Frage:Ist RotPosPathInterpolator dafür richtig?Ich verstehe nämlich nicht wo der Unterschied zwischen PosInterpolator,PathInterpolator und RotPathInterpolator ist.Welcher Interpolator ist für was gedacht ?

Zum anderen weiss ich nicht was man als Transform3d im Konstruktor einbauen muss.Ich möchte nämlich folgende Transformation einbauen:


```
Transform3D newT3D = new Transform3D();
            if (n < JawsConst.TEETH_COUNT / 2) {
                newT3D.set(new Vector3d(0, YChange, 0));

            } else {
                newT3D.set(new Vector3d(0, (YChange * -1.0f), 0));

            }

            Transform3D oldT3D = new Transform3D();
            getToothTransformGroup(n).getTransform(oldT3D);


            oldT3D.mul(newT3D);
            getToothTransformGroup(n).setTransform(oldT3D);
```


----------



## truesoul (28. Jul 2010)

Mit PosInterpolator ist es nur mögliche auf der X-Achse Objekte zu "verschieben" .

Mit PathInterpolator kann man ein ganzes Array hinterlegen , das er dann "ab arbeitet" sprich :
Schrittweise die Transfromationendurchführt.
-> Das ist eher das was du suchst.

Mit RotPathInterpolator hier kann man Positionen und Rotationswinkel definieren.
Die er dann ebenfall "ab arbeitet".
Der Konstruktor enthält zwei Arrays aus Quat4f und Point3f.

Es gibt aber auch genug beispiele für Interpolatoren im Netz. Oder auch java3d API

Und dein zweites anliegen ist mir ein wenig unklar ? 
Im welchen Konstruktor willst du was machen?


----------



## aze (28. Jul 2010)

truesoul hat gesagt.:


> Und dein zweites anliegen ist mir ein wenig unklar ?
> Im welchen Konstruktor willst du was machen?



In dem vom RotPosPathInterpolator.Der Konstruktor lautet doch:


```
public RotPosPathInterpolator(Alpha alpha,
                              TransformGroup target,
                              Transform3D axisOfTransform,
                              float[] knots,
                              Quat4f[] quats,
                              Point3f[] positions)
```

Ich habe die nötigen Punkte(Parameter positions) berechent und man sieht auch eine Animation ,die korrekt abläuft.Wenn man dann aber später weitere Animationen durchführt merkt man das nichts dauerhaft tarnsformiert wurde.Deswegen denke ich man müsste die Transformation(Translation an der Y Ychse) im Parameter axisofTransform wiedergeben oder sehe ich das falsch ?


----------



## truesoul (28. Jul 2010)

Ja so lautet der Konstruktor.

Relevante Methoden von RotPosPathInterpolator


aze hat gesagt.:


> Deswegen denke ich man müsste die Transformation(Translation an der Y Ychse) im Parameter axisofTransform wiedergeben oder sehe ich das falsch ?




```
setTransformAxis( Transform3D );
setTarget( TransformGroup );
setPathArrays( ... , ... , ....);
```
usw...

Willst du eine Animation zeigen oder nur Transformieren?


----------



## aze (28. Jul 2010)

truesoul hat gesagt.:


> Willst du eine Animation zeigen oder nur Transformieren?



Ich will beides.Die Animation soll gezeigt werden(also das Verschieben entlang der Y Achse) und die Transformation soll stattfinden(bei mir ist es so dass die Animation sichtbar ist,aber wenn ich anschließend weitere Tarnsformationen vornehme sieht man das nichts transformiert wurde.Das Model befindet sich noch im alten Zustand)


----------



## truesoul (29. Jul 2010)

Hallo aze, 

also eigentlich hast du alle wichtigen Daten um dann auch nach der Animation die Transformation zu speichern.

Hier mal ein Beispiel:


```
public BranchGroup createAnimation()
    {
        BranchGroup branchGroup = new BranchGroup();
        TransformGroup transformGroup = new TransformGroup();
        TransformGroup transformGroupRotation = new TransformGroup();
        Transform3D d3 = new Transform3D();
        BoundingSphere bigBounds = new BoundingSphere(new Point3d(), 1000);
        float [] knots = {0 , 1};
        Quat4f quats[] = {new Quat4f(1f, 0f, 1f, (float)Math.toRadians(20)) , new Quat4f(1f, 0f, 1f, (float)Math.toRadians(-40))};
        Point3f points[] = {new Point3f(0.9f, 0.0f, 0.0f) , new Point3f(0.2f, 0.3f, 0.0f)};

        transformGroup.addChild(transformGroupRotation);
        transformGroupRotation.addChild(new ColorCube(0.4));
        transformGroupRotation.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);

        RotPosPathInterpolator rot = new RotPosPathInterpolator(new Alpha(1, 1000), transformGroupRotation, d3, knots, quats, points);
        rot.setSchedulingBounds(bigBounds);

        branchGroup.addChild(rot);
        branchGroup.addChild(transformGroup);
        branchGroup.compile();
        return branchGroup;
    }
```

und hier der Endpunkt von der Animation:


```
public BranchGroup createTransformation()
    {
        BranchGroup branchGroup = new BranchGroup();
        TransformGroup transformGroup = new TransformGroup();
        TransformGroup transformGroupRotation = new TransformGroup();
        Transform3D d3 = new Transform3D();
        BoundingSphere bigBounds = new BoundingSphere(new Point3d(), 1000);
        Point3f p = new Point3f(0.2f, 0.3f, 0.0f);
        Quat4f quats = new Quat4f(1f, 0f, 1f, (float)Math.toRadians(-40));
        
        d3.setTranslation(new Vector3f(p.getX(), p.getY(), p.getZ()));
        d3.setRotation(quats);
        transformGroup.setTransform(d3);
        
        
        transformGroup.addChild(transformGroupRotation);
        transformGroupRotation.addChild(new ColorCube(0.4));

        branchGroup.addChild(transformGroup);
        branchGroup.compile();
        return branchGroup;
    }
```

Also nachdem die Animation abgelaufen ist und der am Endpunkt angekommen ist , führe doch die Transformation vom Endpunkt auf das Objekt aus.

1. Animation Startet
2. Animation ist am Endpunkt angelangt
3. Transformation auf das Objekt (vom Endpunkt der Animation) anwenden
4. Fertig ! 

Das ist aber auch nur eine Art an die ich ran gehn würde.
Es gibt sicherlich andere und bessere Wege 

P.S
Ich habe auch eine Anwendung geschrieben wo komplexe Animationen ausgeführt werden, und habe mir eine eigene Interpolatorklasse geschrieben mit funktionen die ich benötigte. Dazu gehörte auch das er die Transformation sich merkt.


----------



## aze (29. Jul 2010)

Hey Danke für die ausführliche Antwort.Ich werde es mal mit deinen "Kochrezept" ausprobieren.

Die selbstgeschriebene Interpolatorklasse , die du erwähnt hast, würde mich interessieren.Falls du noch den Code hast würde ich den gerne sehen.

Schöne Grüße

Aze


----------



## truesoul (30. Jul 2010)

Ich zeige dir gerne wie in ganz GROB angestellt habe.


```
import javax.vecmath.Vector3d;
public class MyInterpolator extends Thread{

    public MyInterpolator( double startPosition[] ,double endPosition[] , TransformGroup transformObjekt , double speed )
    {
        // Arraystelle 0 == X Koordinaten
        // Arraystelle 1 == Y Koordinaten
        // Arraystelle 2 == Z Koordinaten
        this.counter = startPosition;
        this.endPosition = endPosition;
        this.transformObjekt = transformObjekt;
        this.speed = speed;
    }

    @Override
    public void run()
    {
        while(!stop)
        {
            startInterpolaration();
            try
            {
                Thread.sleep(10); 
            }catch(InterruptedException e){}
        }
    }

    public void stopProcess()
    {
        stop = true;
    }

    private void startInterpolaration()
    {
        t.setScale(0.0003);
        
        if(counter[0] < endPosition [0])
        {
            counter[0] += speed;
            t.setTranslation(new Vector3d( counter[0]/100, counter[1]/100,counter[2]/100 ));
        }
        
        if(counter[1] < endPosition [1])
        {
            counter[1] += speed;
            t.setTranslation(new Vector3d( counter[0]/100, counter[1]/100,counter[2]/100 ));
        }
        
        if(counter[2] < endPosition [2])
        {
            counter[2] += speed;
            t.setTranslation(new Vector3d( counter[0]/100, counter[1]/100,counter[2]/100 ));
        }
        
        transformObjekt.setTransform(t);

        if(counter[0] >= endPosition[0] && counter[1] >= endPosition[1] && counter[2] >= endPosition[2] )
            stop = true;

    }

    // Variablen deklaration
    private boolean stop = false;
    private double counter [];
    private double endPosition [];
    private TransformGroup transformObjekt;
    private double speed;
    private Transform3D t = new Transform3D();
}
```

Dazu muss gesagt werden , das dieser Code nur als Beispiel dient.

Man hat ein Anfangspunkte X,Y und Z  und natürlich die Endpunkte, dann zählt man für jeden Durchlauf den zähler hoch ( zaehler += speed ) und setzt setTranslation( x , y , z ) und letztendlich setTransform( ... ) ;

Natürlich muss man den Code so ändern das man da eine Rotation mit einbaut , die Transformation auch in den Negativen Bereich funktioniert sprich new Vector3f( -2 , 2 , 10 ) .
Aber somit hat man eine Transformation und Animation zugleich.

Wie man dann von der neuen Position wieder die Animation startet und die neue Position berücksichtigt kannst du dir ja überlegen.

Ich hoffe ich konnte dir helfen


----------



## aze (3. Aug 2010)

Heissen Dank


----------

