JAVA3D Rotation um einen bestimmten Punkt

Status
Nicht offen für weitere Antworten.

Chrissy09

Mitglied
Hallo zusammen,

da ich ein Java3D-Newbie bin, hoffe ich dass ihr mir bei meinem Problem weiterhelfen könnt.
Also ich bin gerade dabei Zauberwürfel in JAVA3D zu programmieren.
Ich habe den Würfel schon soweit fertig.
Jetzt fehlen allerdings noch die Rotationen der einzelnen Seiten.

Bei mir hat jeder kleine Würfel (3x3x3) seine eigene TransformGroup.
Jetzt möchte ich irgendwie den Drehpunkt für jeden Würfelteil bestimmen, so dass ich den Würfelteil um den Mittelpunkt (x) drehen kann:
OOO
OXO
OOO

Ich weiß, dass da allgemein so geht, dass man den Punkt um den man drehen will auf 0,0,0 verschiebt, dann dreht und dann wieder zurückschiebt.

Allerdings soll die Drehung nicht direkt sichtbar sein, sondern es soll eine Interaktion bzw. Animation sein.
Also dass der Benutzer z.B. eine Taste drückt und dann nicht der Würfel in die Position springt wie es sein soll, sondern dass sich die Würfelseite langsam (sichtbar) um den Mittelpunkt dreht.

Ich hoffe es ist verständlich was ich meine.
Hoffentlich kann mir jemand helfen...ich weiß echt nicht weiter.

Danke schonmal!!!
 

Marco13

Top Contributor
Das schwierigste dabei wird das, was in dem lapidaren Beisatz steht: "...wie es sein soll" - also, sich das ganze so bedienen zu lassen, dass man einfach z.B. durch Klicken+Ziehen irgendwo eine "intuitiv passende" Drehung erreicht ist nicht ganz trivial.
Zur "langsamen Rotation" kannst du dir mal die Klassen "Alpha" und "RotationInterpolator" ansehen...
 

Chrissy09

Mitglied
Also das mit der Bedienung habe ich schon einige Ideen, die soweit auch funktionieren.

Es geht mir nur um die Drehung.
Ich hab mich die Klasse Alpha und RotationInterpolator schon angesehen...
hatte da auch schon was ausprobiert. aber ich habe nicht rausbekommen, ob bzw. wie man da einen Mittelpunkt wählen kann um den gedreht wird. -.-

Also mein Quelltext sieht so aus:

Java:
....
Transform3D axisRot = new Transform3D();
//für jeden Teilwürfel (insgesamt 9):
//Hole ich mir die TransformGroup
TransformGroup cubePart = (TransformGroup) tg.getChild(0); 

//dann mache ich folgendes:
Alpha timer = new Alpha(1, 10000);
/*Für x,y,z setze ich die Werte, so dass ich von dem jeweiligen Teilwürfel zu dem Punkt komme, um den ich drehen will... allerdings weiß ich nicht, was ich mit dem Winkel machen soll...Kann mir das jemand sagen?*/
AxisAngle4d rot = new AxisAngle4d(x,y,z,Math.toRadians(-90.0));
axisRot.set(rot);

RotationInterpolator rotInterp = new RotationInterpolator(timer,cubePart);
rotInterp.setMaximumAngle((float)Math.toRadians(90.0));
rotInterp.setMinimumAngle((float)Math.toRadians(0.0));
rotInterp.setSchedulingBounds(new BoundingSphere());
rotInterp.setAxisOfRotation(axisRot);

cubePart.setTransform(axisRot);

Ich habe das ganze jetzt nur mal für eine Seite getestet..
Und das Ergebnis sieht so aus, dass alles falsch gedreht wird. Also die äußeren Würfel oben und unten stehen komplett schief usw. (siehe Bild)

Hat jemand einen Tipp für mich?
 
Zuletzt bearbeitet:

Developer_X

Top Contributor
Schau dir mal dies an:

Das kannst du am besten an einem kleinen selbstgemachtem sonnensystem lernen.
Also
im Punkt 0 0 0 gibt es einen Sphere.
Diese TransformGroup am Punkt 0 0 heißt Sun.

JEtzt kannst du eine TransformGroup namens Earth erstellen, und sie hinstellen wo hin du willst, also sagen wir mal 0 0 5.
Dann musst du die TransformGroup Sun die TransformGroup Earth adden lassen.
Wenn du jetzt die TransformGroup Sun rotierst, dreht sich die TransformGroup Earth um die TransformGroup Sun.
Im Code sieht dass dann so aus:
Java:
public BranchGroup build_3D_World()
{
BranchGroup X = new BranchGroup();

Transform3D sun = new Transform3D();
sun.rotX(Math.toRadians(20));
sun.setTranslation(new Vector3f(0,0,0));
TransformGroup Sun = new TransformGroup();
Sun.setTransform(sun);
Sun.addChild(new Sphere());
X.addChild(Sun);

Transform3D earth = new Tranform3D();
earth.setTranslation(new Vector3f(0,0,5));
TransformGroup Earth = new TransformGroup();
Earth.setTransform(earth);
Earth.addChild(new Sphere());
Sun.addChild(Earth);

add_lights(X);

return X;
}
	public void add_lights(BranchGroup X)
	{
        Color3f lightColor = new Color3f(1f,.6f,1f);
        AmbientLight ambientLight= new AmbientLight(lightColor);
        ambientLight.setInfluencingBounds(bounds);
        X.addChild(ambientLight);
        DirectionalLight directionalLight = new DirectionalLight();
        directionalLight.setColor(lightColor);
        directionalLight.setInfluencingBounds(bounds);
        X.addChild(directionalLight);     
	}

Verstehst du das?
 

Marco13

Top Contributor
Hm... das ist nicht sooo einfach (dass ich das jetzt in der Mittagspause mal kurz hinschreiben könnte), und mir ist nicht ganz klar, wie du x,y,z setzt, aber ... ein paar spontane, UNVERBINDLICHE(!) Gedanken:

Die Position/Bewegung eines Segmentes besteht aus einer Translation zur "Ausgangslage", und einer Rotation, aber diese Rotation besteht zu jedem Zeitpunkt aus der Hintereinanderausführung mehrerer Rotationen, und einzelne Teile dieser Hintereinanderausführung sollen animiert sein. Eine Überlegung wäre, das ganze wirklich im Sinne eines "Datenmodells" zu beschreiben. Also keine Transformationsmatrizen in TransformGroups zu speichern, sondern nur irgendeinen Array von Winkeln, oder noch allgemeiner: Eine Abfolge von "Rotationsbefehlen". Sowas bräuchte man spätestes für einen "Solver", oder schon wenn man nur erkennen will, dass der Würfel fertig gelöst ist. Diese Winkel oder Befehle könnten dann immer "on the fly" in die jeweiligen Matrizen umgerechnet werden - aber da müßte man sich GENAU überlegen, wie dieses Modell aussehen könnte.... auch wenn es da sicher schon 1000e Ansätze im Web gibt.

Aber back to reality :) Ich nehme an, das Problem liegt wirklich bei
"Für x,y,z setze ich die Werte, so dass ich von dem jeweiligen Teilwürfel zu dem Punkt komme, um den ich drehen will...
Für ein AxisAngle übergibt man ja keinen Punkt, sondern eine Rotationsachse - und das ist bei dir IMMER nur die X- Y- oder Z-Achse. Und du willst ja auch nicht jeden Teilwürfel um seinen Mittelpunkt drehen. Die Rotation findet immer um den Ursprung statt.

Der Versuch, das in einer Pseudo-Szenegraphstruktur anzudeuten:
Java:
// TransformGroups, die die AUSGANGSLAGE jedes Segments beschreiben
// (Dort hängen direkt die Segmente dran!)

// Für das Segment rechts oben vorne (Right Top Front)
positionRTF = TransformGroup(1,1,1) 
positionRTF.add(segmentRTF);

// Für das Segment rechts oben mitte
positionRTM = TransformGroup(1,1,0) 
positionRTM.add(segmentRTM);

...

// Jedes einzelne Segment kann aus seiner Ausgangslage raus rotiert werden
// Deswegen eine Rotations-Transformgroup für jedes Segment, und 
// AN dieser rotations-TG hängen die positions-TGs

rotationRTF = TransformGroup() 
rotationRTF.addChild(positionRTF);

rotationRTM = TransformGroup() 
rotationRTM.addChild(positionRTM);

...

In Wirklichkeit würde man das natürlich irgendwie geschickter schreiben, und nicht mit 81 Variablen mit so abstrusen Namen... :autsch: ;) Wie man Rotationen auf einen bestehenden Würfel anwenden könnte (d.h. wie man rausfindet, welche Segmente durch eine Rotation betroffen sind) muss man sich auch überlegen, aber vielleicht hast du das ja schon.

Java:
// Wenn jetzt die rechte Seite des würfels um 90° gedreht werden soll, könnte
// man das GANZ GROB vielleicht so machen:

// Die Rotation ausrechnen:
Vector3f xAxis = new Vector3f(1,0,0);
AxisAngle4f axisAngle = new AxisAngle4f(xAxis, angle);
Transform3D rotation = new Transform3D(axisAngle);

// Die Rotation auf alle betroffenen Segmente anwenden:
for (Segment s : affectedSegments)
{
    TransformGroup tg = rotationTransformGroupFor(s);
    Transform3D oldRotation = tg.getTransform();
    Transform3D newRotation = rotation.mul(oldRotation);
    tg.setTransform(newRotation);
}

Um die Animation da rein zu bringen würde ich jetzt kaum eine andere Möglichkeit sehen, als 9 RotationInterpolators zu erstellen - andernfalls müßte man noch eine TransformGroup dazwischenschalten, die nur die Animation übernimmt (das könnte fummelig werden). Den RotationInterpolator würde man im Pseudocode-Beispiel oben dann jeweils auf die "newRotation" andwenden.

So. Mittagspause. :)
 

Chrissy09

Mitglied
Zu DeveloperX:

also wenn ich so ein Sonnensystem habe und ich habe als Baum dargestellt

....-----------TransformGroup Sun-----------------------TransformGroup Earth

also sun.add(earth) sozusagen.
Dann dachte ich, dass es so ist, dass wenn man zur sun-TG sagt: dreh dich um X Grad, dass dann alles was an SUN dranhängt..also in dem Fall die Sonne und alles was drunter hängt...also auch TG Earth und die Erde gedreht wird.
Lieg ich mit der Annahme falsch?

zu Marco:
Danke für die Tipps, ich werd mal ein bisschen rumprobieren und dann mich dann nochmal melden wenn es nicht klappt.
 

Chrissy09

Mitglied
Aaaalso...ich nochmal.
Wenn ich nun folgendes verwende:
Java:
                    AxisAngle4d rot = new AxisAngle4d(0.0,0.0,1.0,Math.toRadians(-90.0));

dann dreht sich jeder kleine Würfel einzeln um -90° allerdings ist das ja nicht das was ich will, weil als rotationszentrum der mittelpunkt von jedem kleinen würfel genommen wird.
Ich will aber dass der mittelpunkt vom mittleren Würfel (X) genommen wird:
O O O
O X O
O O O

Wie bekomm ich das hin?

Bzw. wenn ich sage :
Java:
rotInterp.setMaximumAngle((float)Math.toRadians(90.0));
rotInterp.setMinimumAngle((float)Math.toRadians(0.0));
Was genau bewirkt das?
Weil im Moment springt das Ereignis, also nix dreht sich langsam. Sondern einfach zack und die Würfel sind gedreht.

Ich glaube ich versteh das ganze irgendwie falsch ^^

Helft mir bitte.
 

Marco13

Top Contributor
Mit der ersten Antwort hast du die Frage aus der zweiten Antwort ja schon beantwortet ;)
Also ja: In diesem Beispiel würde die Rotation auf die Sonne angewendet werden, UND auf alles, was an der Sonne hängt.

Deswegen irritiert mich die zweite Frage: Wenn deine Szenegraphstruktur so ist
Code:
root
    transformFürWürfel
        rotationFürSegment000
            translationFürSegment000
                segment000
        rotationFürSegment001
            translationFürSegment001
                segment001
        ...
dann sollten sich die Segment, wenn die Rotation auf die TGs "rotationFürSegmentXXX" angewendet werden, NICHT um ihr Zentrum, sondern um das Zentrum des gesamten Würfels drehen - immer verschoben um ihre Ausgangslage.

Oder anders gesagt: Hängt an der
TransformGroup cubePart = (TransformGroup) tg.getChild(0);
die du dir da holst NUR das Segment, oder eine TransformGroup für die Translation (an der dann das Segment hängt)?


EDIT: Wegen RotationInterpolator: Es gibt da Konstruktoren mit mehr Parametern (sowohl für den Interpolator als auch für das Alpha) - bei denen, die du benutzt, ist (mir, ohne nachlesen) erstmal nicht klar, welche Werte dort standardmäßig für die anderen Parameter angenommen werden...
 
Zuletzt bearbeitet:

Chrissy09

Mitglied
also die struktur sieht folgendermaßen aus:
Java:
root
    TG_cube
        //und dann für jedes Segment:
            TG1_segment000
                  //via new TG(Transform3d)
                  Translation standard(startzustand)
                  TG2_segment000 (cubepart)
                         //via setTransform 
                         gewünschte Rotation für Drehung //das was ich eigentlich will
                         segment000
            TG1_segment001
                  //via new TG(Transform3d)
                  Translation standard(startzustand)
                  TG2_segment001
                         segment001
                              usw....

Ich hatte mal 2 TG's pro segement gemacht, da ich dachte, dass man immer nur entweder translation oder rotation speichern kann..aber anscheinend geht das beides.. Bin wie gesagt noch Newbie.

und das TG cubepart wäre dann immer das TG2 für jedes segment.
Wenn ich via setTransform bei einer TG ein Transform3d setze...ist das dann so als wäre das Transform3d ein Child von der TG ?
 
Zuletzt bearbeitet:

Developer_X

Top Contributor
Zu DeveloperX:

also wenn ich so ein Sonnensystem habe und ich habe als Baum dargestellt

....-----------TransformGroup Sun-----------------------TransformGroup Earth

also sun.add(earth) sozusagen.
Dann dachte ich, dass es so ist, dass wenn man zur sun-TG sagt: dreh dich um X Grad, dass dann alles was an SUN dranhängt..also in dem Fall die Sonne und alles was drunter hängt...also auch TG Earth und die Erde gedreht wird.
Lieg ich mit der Annahme falsch?

QUOTE]

Du liegst mit der annahme richtig.

Ich hab als 3D Anfänger früher auch mal ein Sonnensystem gebastelt, nach diesem Schema, du kannst auch ein paar gruppen, zum beispiel moon an die earth hängen^^.
 

Chrissy09

Mitglied
okay. Wenn ich das schonmal nicht falsch verstanden habe. Wo genau liegt dann mein Fehler,dass immer nur um den Mittelpunkt der Teilwürfel gedreht wird?
 

Developer_X

Top Contributor
das ist nicht 1 würfel, sondern dass sind 3*3*3 Würfel.
UNd du hast nur die würfel, die an den ecken sind, gedreht.
Du musst das ganze große, also die TransformGroup die alle Würfel added, drehen.
 

Chrissy09

Mitglied
Ja aber ich will ja nicht alle würfel drehen, sondern nur die auf der Vorderseite zB. Halt immer nur eine Seite. So wie bei Rubiks Cube normalerweise auch. Dass ich wenn ich 3*3*3 hab
und ich sag jetzt mal hinten unten links ist 0,0,0
Dann will ich die Teilwürfel 002, 012, 022, 102, 112, 122, 202, 212, 222 drehen.
Und NUR die. nicht alle. Wie krieg ich das hin?


Im Moment sieht das ganze folgendermaßen aus:
siehe Bild
 
Zuletzt bearbeitet:

Marco13

Top Contributor
Wie gesagt: Du rotierst um die Mittelpunkte der Würfel, weil deine Szenegraphstruktur "falsch" ist (bzw. die Rotation auf die falschen Knoten angewendet wird).

Um mal zu Potte zu kommen...
Code:
// From http://www.java2s.com/Code/Java/3D/HelloJava3Dbaltrendersasinglerotatedcube.htm
// Extended for http://www.java-forum.org/spiele-multimedia-programmierung/89915-java3d-rotation-um-bestimmten-punkt.html


import java.applet.Applet;
import java.awt.*;
import java.awt.Frame;

import javax.media.j3d.BranchGroup;
import javax.media.j3d.Canvas3D;
import javax.media.j3d.Transform3D;
import javax.media.j3d.TransformGroup;
import javax.vecmath.*;
import com.sun.j3d.utils.applet.MainFrame;
import com.sun.j3d.utils.geometry.ColorCube;
import com.sun.j3d.utils.universe.SimpleUniverse;

//   HelloJava3Dbalt renders a single, rotated cube.

public class HelloJava3Dbalt extends Applet {


  private TransformGroup translation[][][] = new TransformGroup[3][3][3];
  private TransformGroup rotation[][][] = new TransformGroup[3][3][3];

  private void createSegment(BranchGroup node, int x, int y, int z)
  {

      translation[x][y][z] = new TransformGroup();
      float dx = -1.0f + x;
      float dy = -1.0f + y;
      float dz = -1.0f + z;
      Transform3D t = new Transform3D();
      t.setTranslation(new Vector3f(dx,dy,dz));
      translation[x][y][z].setTransform(t);
      translation[x][y][z].addChild(new ColorCube(0.45f));

      rotation[x][y][z] = new TransformGroup();

      rotation[x][y][z].addChild(translation[x][y][z]);
      node.addChild(rotation[x][y][z]);


  }

  private void rotateSegmentsAtY(int y, float angleDeg)
  {
    AxisAngle4d rot = new AxisAngle4d(0.0,1.0,0.0,Math.toRadians(angleDeg));
    Transform3D t = new Transform3D();
    t.setRotation(rot);

    for (int x=0; x<3; x++)
    {
        for (int z=0; z<3; z++)
        {
            rotation[x][y][z].setTransform(t);
        }
    }
  }



  public BranchGroup createSceneGraph() {
    // Create the root of the branch graph
    BranchGroup objRoot = new BranchGroup();

    for (int x=0; x<3; x++)
    {
        for (int y=0; y<3; y++)
        {
            for (int z=0; z<3; z++)
            {
                createSegment(objRoot, x, y, z);
            }
        }
    }

    rotateSegmentsAtY(0,10);
    rotateSegmentsAtY(1,20);
    rotateSegmentsAtY(2,30);

    objRoot.compile();

    return objRoot;
  } // end of CreateSceneGraph method of HelloJava3Dbalt

  // Create a simple scene and attach it to the virtual universe

  public HelloJava3Dbalt() {
    setLayout(new BorderLayout());
    GraphicsConfiguration config =
       SimpleUniverse.getPreferredConfiguration();

    Canvas3D canvas3D = new Canvas3D(config);
    add("Center", canvas3D);

    BranchGroup scene = createSceneGraph();

    // SimpleUniverse is a Convenience Utility class
    SimpleUniverse simpleU = new SimpleUniverse(canvas3D);

    // This will move the ViewPlatform back a bit so the
    // objects in the scene can be viewed.

    Transform3D t = new Transform3D();
    t.setTranslation(new Vector3f(0,0,10));
    simpleU.getViewingPlatform().getViewPlatformTransform().setTransform(t);

    //simpleU.getViewingPlatform().setNominalViewingTransform();

    simpleU.addBranchGraph(scene);
  } // end of HelloJava3Db (constructor)

  //  The following allows this to be run as an application
  //  as well as an applet

  public static void main(String[] args) {
    Frame frame = new MainFrame(new HelloJava3Dbalt(), 256, 256);
  } // end of main (method of HelloJava3Dbalt)

} // end of class HelloJava3Dbalt
 

Chrissy09

Mitglied
Super. Die Rotation funktioniert schonmal richtig.
Vielen Dank.

Allerdings habe ich noch ein Problem damit, dass es eine Animaiton sein soll, die sozusagen auf Knopfdruck gestartet wird.
Ich hätte jetzt einfach einen RotationsInterpolator auf Knopfdruck erstellt und diesen in den Szenegraph eingefügt.
Allerdings geht das ja zur Laufzeit so nicht.

Wie mache ich das dann anders?
 

Marco13

Top Contributor
Man könnte, wenn man wollte, was mit dem RotationInterpolator dengeln - ein eigener Thread ist aber vmtl. einfacher
Java:
// From [url=http://www.java2s.com/Code/Java/3D/HelloJava3Dbaltrendersasinglerotatedcube.htm]HelloJava3Dbalt renders a single, rotated cube : Cube3DJava[/url]
// Extended for [url]http://www.java-forum.org/spiele-multimedia-programmierung/89915-java3d-rotation-um-bestimmten-punkt.html[/url]


import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.awt.Frame;

import javax.media.j3d.BranchGroup;
import javax.media.j3d.Canvas3D;
import javax.media.j3d.Transform3D;
import javax.media.j3d.TransformGroup;
import javax.vecmath.*;
import com.sun.j3d.utils.applet.MainFrame;
import com.sun.j3d.utils.geometry.ColorCube;
import com.sun.j3d.utils.universe.SimpleUniverse;

//   HelloJava3Dbalt renders a single, rotated cube.

public class HelloJava3Dbalt extends Applet {


  private TransformGroup translation[][][] = new TransformGroup[3][3][3];
  private TransformGroup rotation[][][] = new TransformGroup[3][3][3];

  private void createSegment(BranchGroup node, int x, int y, int z)
  {

      translation[x][y][z] = new TransformGroup();
      float dx = -1.0f + x;
      float dy = -1.0f + y;
      float dz = -1.0f + z;
      Transform3D t = new Transform3D();
      t.setTranslation(new Vector3f(dx,dy,dz));
      translation[x][y][z].setTransform(t);
      translation[x][y][z].addChild(new ColorCube(0.45f));

      rotation[x][y][z] = new TransformGroup();
      rotation[x][y][z].setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
      rotation[x][y][z].addChild(translation[x][y][z]);
      node.addChild(rotation[x][y][z]);


  }

  private void rotateSegmentsAtY(int y, float angleDeg)
  {
    AxisAngle4d rot = new AxisAngle4d(0.0,1.0,0.0,Math.toRadians(angleDeg));
    Transform3D t = new Transform3D();
    t.setRotation(rot);

    for (int x=0; x<3; x++)
    {
        for (int z=0; z<3; z++)
        {
            Transform3D oldRotation = new Transform3D();
            rotation[x][y][z].getTransform(oldRotation);
            Transform3D newRotation = new Transform3D();
            newRotation.mul(t, oldRotation);
            rotation[x][y][z].setTransform(newRotation);
        }
    }
  }


  public void rotate()
  {
      Thread t = new Thread(new Runnable()
      {
          public void run()
          {
              for (int i=0; i<90; i++)
              {
                  rotateSegmentsAtY(0,1);
                  try
                  {
                      Thread.sleep(20);
                  }
                  catch (InterruptedException e)
                  {
                      Thread.currentThread().interrupt();
                  }
              }
          }
      });
      t.start();

  }



  public BranchGroup createSceneGraph() {
    // Create the root of the branch graph
    BranchGroup objRoot = new BranchGroup();

    for (int x=0; x<3; x++)
    {
        for (int y=0; y<3; y++)
        {
            for (int z=0; z<3; z++)
            {
                createSegment(objRoot, x, y, z);
            }
        }
    }

    rotateSegmentsAtY(0,10);
    rotateSegmentsAtY(1,20);
    rotateSegmentsAtY(2,30);

    objRoot.compile();

    return objRoot;
  } // end of CreateSceneGraph method of HelloJava3Dbalt

  // Create a simple scene and attach it to the virtual universe

  public HelloJava3Dbalt() {
    setLayout(new BorderLayout());
    GraphicsConfiguration config =
       SimpleUniverse.getPreferredConfiguration();

    JButton b = new JButton("rotate");
    add("North", b);
    b.addActionListener(new ActionListener()
    {
        public void actionPerformed(ActionEvent e)
        {
            rotate();
        }
    });


    Canvas3D canvas3D = new Canvas3D(config);
    add("Center", canvas3D);

    BranchGroup scene = createSceneGraph();

    // SimpleUniverse is a Convenience Utility class
    SimpleUniverse simpleU = new SimpleUniverse(canvas3D);

    // This will move the ViewPlatform back a bit so the
    // objects in the scene can be viewed.

    Transform3D t = new Transform3D();
    t.setTranslation(new Vector3f(0,0,10));
    simpleU.getViewingPlatform().getViewPlatformTransform().setTransform(t);

    //simpleU.getViewingPlatform().setNominalViewingTransform();

    simpleU.addBranchGraph(scene);
  } // end of HelloJava3Db (constructor)

  //  The following allows this to be run as an application
  //  as well as an applet

  public static void main(String[] args) {
    Frame frame = new MainFrame(new HelloJava3Dbalt(), 256, 256);
  } // end of main (method of HelloJava3Dbalt)

} // end of class HelloJava3Dbalt
 

Chrissy09

Mitglied
Hi.

danke schonmal für die Anregung.
Würde das aber wenn möglich gerne via RotationInterpolator regeln.

Ich habe das soweit auch schon hinbekommen, indem ich bei der Initialisierung der Würfelteile folgendes mache:
Java:
Alpha timer = new Alpha(1, 5000);
                    
Transform3D axis = new Transform3D();
axis.rotX(Math.PI / 2);
                    
RotationInterpolator rotInterp = new RotationInterpolator(timer,rotation);
rotInterp.setSchedulingBounds(new BoundingSphere());
rotInterp.setMaximumAngle(0.0f);
rotInterp.setTransformAxis(axis);

rotation.addChild(rotInterp);

und bei bestimmten Tastendruck mache ich folgendes:
Java:
RotationInterpolator ri = (RotationInterpolator)rottg.getChild(0);
              
ri.setMaximumAngle((float)Math.toRadians(-90.0));

Die Seite dreht sich auch. Allerdings springt die Seite erstmal ruckartig um ca. 45° und dann dreht sie langsam weiter von 45° bis 90° (minus in dem Falle).

Hat jemand eine Ahnung woran das liegt, dass es so springt?

Wenn ich von Anfang an maxAngle auf -90 setze und den Alphawert pausiere bis eine Taste gedrückt wird, dann springt die Würfelseite schon bei der Initialisierung des RotationInterpolators um ca. 45°.
Woran liegt das?
 

Chrissy09

Mitglied
Java:
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package hellojava3dhelp;

/// From [url=http://www.java2s.com/Code/Java/3D/HelloJava3Dbaltrendersasinglerotatedcube.htm]HelloJava3Dbalt renders a single, rotated cube : Cube3DJava[/url]
// Extended for [url]http://www.java-forum.org/spiele-multimedia-programmierung/89915-java3d-rotation-um-bestimmten-punkt.html[/url]

import java.awt.*;
import java.awt.event.ActionEvent;
import javax.vecmath.*;
import com.sun.j3d.utils.geometry.ColorCube;
import com.sun.j3d.utils.universe.SimpleUniverse;
import java.awt.event.ActionListener;
import javax.media.j3d.*;
import javax.swing.JButton;
import javax.swing.JFrame;

//   HelloJava3Dbalt renders a single, rotated cube.
public class HelloJava3Dbalt extends JFrame {

    private TransformGroup translation[][][] = new TransformGroup[3][3][3];
    private TransformGroup rotation[][][] = new TransformGroup[3][3][3];

    private void createSegment(BranchGroup node, int x, int y, int z) {

        translation[x][y][z] = new TransformGroup();
        float dx = -1.0f + x;
        float dy = -1.0f + y;
        float dz = -1.0f + z;
        Transform3D t = new Transform3D();
        t.setTranslation(new Vector3f(dx, dy, dz));

        translation[x][y][z].setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
        translation[x][y][z].setCapability(TransformGroup.ALLOW_TRANSFORM_READ);

        translation[x][y][z].setTransform(t);
        translation[x][y][z].addChild(new ColorCube(0.45f));

        rotation[x][y][z] = new TransformGroup();
        rotation[x][y][z].setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
        rotation[x][y][z].setCapability(TransformGroup.ALLOW_TRANSFORM_READ);

        rotation[x][y][z].addChild(translation[x][y][z]);


        Alpha timer = new Alpha(1, 100000);

        Transform3D axis = new Transform3D();
        axis.rotX(Math.PI / 2);
        //axis.set(new Vector3f(0.0f,0.0f,1.0f));

        RotationInterpolator rotInterp = new RotationInterpolator(timer, rotation[x][y][z]);
        rotInterp.setSchedulingBounds(new BoundingSphere());
        rotInterp.setMaximumAngle(0.0f);
        rotInterp.setTransformAxis(axis);

        if(z==2)
            rotation[x][y][z].addChild(rotInterp);

        node.addChild(rotation[x][y][z]);
    }

    public void rotate(){
        for(int i=0; i<3; i++)
            for(int j=0; j<3; j++){
                RotationInterpolator ri = (RotationInterpolator)rotation[i][j][2].getChild(1);
                ri.setMaximumAngle(-90.0f);
            }
    }

    public BranchGroup createSceneGraph() {
        // Create the root of the branch graph
        BranchGroup objRoot = new BranchGroup();

        for (int x = 0; x < 3; x++) {
            for (int y = 0; y < 3; y++) {
                for (int z = 0; z < 3; z++) {
                    createSegment(objRoot, x, y, z);
                }
            }
        }

        objRoot.compile();

        return objRoot;
    } // end of CreateSceneGraph method of HelloJava3Dbalt

    // Create a simple scene and attach it to the virtual universe
    public HelloJava3Dbalt() {
        setSize(256,256);
        setLayout(new BorderLayout());
        GraphicsConfiguration config =
                SimpleUniverse.getPreferredConfiguration();

        Canvas3D canvas3D = new Canvas3D(config);
        add("Center", canvas3D);
        JButton j = new JButton("Rotate");
        j.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                rotate();
            }
        });
        add("South", j);

        BranchGroup scene = createSceneGraph();

        // SimpleUniverse is a Convenience Utility class
        SimpleUniverse simpleU = new SimpleUniverse(canvas3D);

        // This will move the ViewPlatform back a bit so the
        // objects in the scene can be viewed.

        Transform3D t = new Transform3D();
        t.setTranslation(new Vector3f(0, 0, 10));
        simpleU.getViewingPlatform().getViewPlatformTransform().setTransform(t);

        //simpleU.getViewingPlatform().setNominalViewingTransform();

        simpleU.addBranchGraph(scene);

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);
    } // end of HelloJava3Db (constructor)

    public static void main(String[] args) {
        new HelloJava3Dbalt();
        
    } // end of main (method of HelloJava3Dbalt)
} // end of class HelloJava3Dbalt

Habe mal folgendes gebastelt.

Wenn man auf rotate drückt, dann springt der Würfel erst.
 

Marco13

Top Contributor
Das Alpha läuft sofort los, und läuft innerhalb von 100 Sekunden von 0 bis 0. (Ja.)

Solange es nur zwischen 0 und 0 interpoliert, sieht man nichts. Aber wenn es dann zwischendrin gesagt bekommt, dass es innerhalb dieser 100 Sekunden 14 Drehungen machen soll (grad vs. radians!), hüpft es eben da hin, wo es zu diesem Zeitpunkt sein müßte.

Als ich oben gesagt habe, dass man "mit RotationInterpolator was dengeln" könnte, bezog sich das darauf, dass man ... auch mit einem Schraubenzieher einen Nagel in die Wand hauen kann ... also, dass du, wenn der Button geklickt wird (und nicht vorher) einen neuen RotationInterpolator erstellen musst, der sich auf eine andere "Hilfs"-Rotations-TransformGroup bezieht, als die, mit der du bisher die Rotation machst, und aus dieser Hilfs-TG dann, wenn der Interpolator fertig ist (wie auch immer man das feststellen soll), die Transform auslesen, sie für die eigentlche TransformGroup setzen, die Hilfs-TG auf die Identität setzen, und den Interpolator wieder entfernen musst. (Irgendwie muss das Endergebnis der Transformation ja so gespeichert werden, dass nachfolgende Transformationen sich auf die schon Transformierten Segemente beziehen).

Mein Tipp: Lass' das mit dem Interpolator. Und BEVOR du jetzt wieder so spontan das einbaust, was ich da mit dem Thread gepostet hatte: Denke nach, wie du weitermachen willst. Überleg' dir, wie du die Hintereinanderausführung machst, wie du bestimmst, auf welche Segmente sich eine Transformation beziehen soll, und wie du den Zustand das Würfels richtig speichern kannst (außer implizit, in einem Haufen TransformGroups...:autsch: ). Mit 5 Zeilen mal so einen schicken Würfel in 3D da hinmalen ist eine Sache, und vielleicht ein motivierendes Erfolgserlebnis, aber ... es ist nicht so leicht... und wenn man nicht überlegt und eine genaue Idee entwickelt, wie man vorgehen will, endet's in Rumprobieren, Hacken und Frust. Das hast du ja vielleicht schon gemerkt.
 

Developer_X

Top Contributor
also wenn ich 3d applikationen mache, mache ich das immer mit einem mainthread für das programm.

alpha und andere laggen bei mir.
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
C Java3D Rotation um einen Punkt (y-achse) Spiele- und Multimedia-Programmierung 2
T [gelöst] Java3D: Unerwünschte Rotation um die 3.Achse vermeiden? Spiele- und Multimedia-Programmierung 3
J Hilfe: Rotation X und Y Achse (Java3d) Spiele- und Multimedia-Programmierung 12
"Er" Kamera rotation in Java3D Spiele- und Multimedia-Programmierung 2
T Java3D: Rotation und Translation Spiele- und Multimedia-Programmierung 2
N Java3d in Eclipse einbinden Spiele- und Multimedia-Programmierung 4
Neumi5694 Java3D Viewer Beschriftung Spiele- und Multimedia-Programmierung 1
C Java3D Transformieren von obj. Datein Spiele- und Multimedia-Programmierung 0
M Cylinder anhand eines Vektors ausrichten (Java3d) Spiele- und Multimedia-Programmierung 0
Ruvok Java3D Tutorial gesucht Spiele- und Multimedia-Programmierung 5
U Hilfe bei Implementierung eines PointSounds in Java3D Spiele- und Multimedia-Programmierung 1
R Java3d ViewingPlatform erst Verschieben und dann RotationsInterpolator Spiele- und Multimedia-Programmierung 0
D Java3D - Blickfeld Spiele- und Multimedia-Programmierung 1
P Java3D Box Dimensionen und Positionierung Spiele- und Multimedia-Programmierung 1
E Java3D Objekt skalieren per JSlider/JButton Spiele- und Multimedia-Programmierung 10
S Java3D: Primitives zu einem Objekt kombinieren Spiele- und Multimedia-Programmierung 7
J Java3D - Textur laden geht nicht Spiele- und Multimedia-Programmierung 9
J Java3D - Farben vermischen sich Spiele- und Multimedia-Programmierung 7
T Java3D Rendering Problem Spiele- und Multimedia-Programmierung 7
S Java3D oder JMonkey? Spiele- und Multimedia-Programmierung 17
H Java3D - Textur aufs innere einer Sphere mappen Spiele- und Multimedia-Programmierung 9
C java 3d ohne Java3d Spiele- und Multimedia-Programmierung 28
Maxim6394 [Java3D] Probleme bei Kollision Spiele- und Multimedia-Programmierung 7
Maxim6394 [Java3D] lookAt Mausposition Spiele- und Multimedia-Programmierung 17
Maxim6394 [Java3D] Probleme mit KeyFrame Animationen Spiele- und Multimedia-Programmierung 9
K Java3D als Applet ohne Installation von Java3d Spiele- und Multimedia-Programmierung 6
D Java3D Installation: package javax.media.j3d not found Spiele- und Multimedia-Programmierung 5
C Java3D Texture Mapping Spiele- und Multimedia-Programmierung 2
W Java3D: Kanten die hinter einem Objekt liegen werden gezeigt Spiele- und Multimedia-Programmierung 2
W Java3D: Farbe von Objekten stimmt nicht mit übergebenem RGB-Wert überein Spiele- und Multimedia-Programmierung 9
M Eigene Renderengine ohne Java3D,etc. Spiele- und Multimedia-Programmierung 19
C Java3D Sound spielt nur einen Sound ab. Spiele- und Multimedia-Programmierung 8
A JAVA3D TransformGroup <--> Group Problem Spiele- und Multimedia-Programmierung 3
M [Java3D] Animation von mehreren Objekten Spiele- und Multimedia-Programmierung 7
W Java3D: Eckkoordinaten einer Box herausfinden Spiele- und Multimedia-Programmierung 18
T Java3D: Objekte platzieren und entfernen? Spiele- und Multimedia-Programmierung 7
T Java3D: Nur die Kanten des Würfels rendern? Spiele- und Multimedia-Programmierung 4
W Java3D setBounds(BoundingBox) Spiele- und Multimedia-Programmierung 6
Bastie JAVA3D - WRL Transform Spiele- und Multimedia-Programmierung 9
G Eclipse Problem mit Java3d Spiele- und Multimedia-Programmierung 3
T Java3D - Lichtquelle einbauen Spiele- und Multimedia-Programmierung 7
jemandzehage java3d parallel und perspective view Spiele- und Multimedia-Programmierung 5
H Cinema 4D in Java3D importieren Spiele- und Multimedia-Programmierung 2
1 [Java3D] komplexes Projekt? Spiele- und Multimedia-Programmierung 10
P .obj-Datei in Java3D laden: ParsingErrorException Spiele- und Multimedia-Programmierung 7
C Java3D Lichtquelle beim Beobachter Spiele- und Multimedia-Programmierung 2
C Java3D Interaktion während Animation Spiele- und Multimedia-Programmierung 3
aze Java3D: Flächen teilen Spiele- und Multimedia-Programmierung 15
P Java3D Textur verzerrt Spiele- und Multimedia-Programmierung 3
aze Java3D: Gegenstände aufeinander zubewegen ohne Kollision Spiele- und Multimedia-Programmierung 4
D [JAVA3D] Es werden 2 Fenster erzeugt und auf dem falschen gezeichnet Spiele- und Multimedia-Programmierung 3
aze Java3D: leere Räume füllen Spiele- und Multimedia-Programmierung 2
aze Java3d:Helligkeit von Shape3D ändern Spiele- und Multimedia-Programmierung 2
S Einschätzung zu Java3D-Einstieg Spiele- und Multimedia-Programmierung 3
F Programm mit Java3D unter Linux laufen lassen Spiele- und Multimedia-Programmierung 3
I Vergleich von Java3D und OpenGL Spiele- und Multimedia-Programmierung 17
W Waterslide mit Java3D Spiele- und Multimedia-Programmierung 11
M Java3D Picking - falsche Objekte werden gepickt Spiele- und Multimedia-Programmierung 3
M [Java3D] Rotieren der Scene NICHT des POV Spiele- und Multimedia-Programmierung 4
F Jogl oder Java3D ? Spiele- und Multimedia-Programmierung 20
K Java3D Abfängerfrage Spiele- und Multimedia-Programmierung 3
aze Java3D:Farbige Flächen verschwinden lassen(Transparenz- oder Colorinterpolator?)) Spiele- und Multimedia-Programmierung 5
C Java3D PositionInterpolator Spiele- und Multimedia-Programmierung 3
G [Java3D] Probleme bei Animation Spiele- und Multimedia-Programmierung 4
E [JAVA3D] Kamerasteuerung Spiele- und Multimedia-Programmierung 3
E [JAVA3D] Schattenstrich durch die Szene Spiele- und Multimedia-Programmierung 4
M Grundsätzliche Java3D Fragen Spiele- und Multimedia-Programmierung 2
C Java3D SceneGraohPath Spiele- und Multimedia-Programmierung 2
G Java3D plattformunabhängig bundeln Spiele- und Multimedia-Programmierung 3
TheKing Java3D-Shooter View Spiele- und Multimedia-Programmierung 2
A Java3D tutorial? Spiele- und Multimedia-Programmierung 3
R Java3D Kollisionserkennung und Schwerkraft Spiele- und Multimedia-Programmierung 17
M Java3D Objekte entfernen und hinzufügen Spiele- und Multimedia-Programmierung 10
J Java3d Schnelle Geschosse Spiele- und Multimedia-Programmierung 12
D Kann ich mit Java3D 2D Daten als 3D surfaceplot plotten? Spiele- und Multimedia-Programmierung 5
J Java3d setTextureTransform verändert J3DGraphics2D Spiele- und Multimedia-Programmierung 4
K Java3D: LineStripArray Spiele- und Multimedia-Programmierung 2
P Java3D - Zylinder genau wie Vektor ausrichten Spiele- und Multimedia-Programmierung 5
Developer_X Java3D Mensch Ärgere Dich nicht. Spiele- und Multimedia-Programmierung 10
Developer_X Java3D-Ungeeignet für 3D Spiele wegen Heap Space=? Spiele- und Multimedia-Programmierung 23
Developer_X Java3D Canvas post Renderer und? Spiele- und Multimedia-Programmierung 5
A Java3D Sichtweite Spiele- und Multimedia-Programmierung 2
A Java3D: Behavior scheduling bounds Spiele- und Multimedia-Programmierung 3
Developer_X THE BALL (needs Java3D) Spiele- und Multimedia-Programmierung 34
Developer_X Java3D Game_(die erste) Spiele- und Multimedia-Programmierung 2
Developer_X Java3D und while schleifen Spiele- und Multimedia-Programmierung 4
Developer_X Collisionserkennung in Java3D Spiele- und Multimedia-Programmierung 3
Developer_X Java3D Node -> Obj Data Spiele- und Multimedia-Programmierung 2
Developer_X Figuren werden nicht angezeigt (Java3D) Spiele- und Multimedia-Programmierung 5
S PDFRenderer und Java3D Spiele- und Multimedia-Programmierung 2
Developer_X Java3D- der Mausklick auf Nodes Spiele- und Multimedia-Programmierung 3
Developer_X Java3D Point Sound Spiele- und Multimedia-Programmierung 71
Developer_X Lines in Java3D Spiele- und Multimedia-Programmierung 4
V Java3D: HUD erstellen Spiele- und Multimedia-Programmierung 2
V Java3D: scheinende Sonne Spiele- und Multimedia-Programmierung 4
V Java3D: Ringe für Saturn erstellen Spiele- und Multimedia-Programmierung 8
V Java3D: automatisches Bewegen der Kamera Spiele- und Multimedia-Programmierung 19
V Java3D: mehrere ViewingPlaforms in Sonnensystem Spiele- und Multimedia-Programmierung 8
Developer_X Thread in Java3D Spiele- und Multimedia-Programmierung 8
B Java3D .obj dateien Spiele- und Multimedia-Programmierung 2

Ähnliche Java Themen

Neue Themen


Oben