# Java3D Box Dimensionen und Positionierung



## Peet0r (14. Jan 2014)

Hallo,

ich versuche mehrere Boxen mittels Java3D darzustellen. Von den Boxen sind die Dimensionen (w,h,d) und die Position (x,y,z) bekannt. Anders als Java3D würde ich die Boxen gerne anhand ihrer linken, unteren, hinteren Ecken positionieren, komme damit aber nicht ganz zurecht. Folgenden Code habe ich mir anhand von Codeschnippseln zurechtgebastelt: es wird eine Box mit den Abmessungen (0.5f, 0.5f, 0.5f) erzeugt. Um die linke untere Ecke an den Ursprung zu legen, hätte ich jetzt die halben Boxenabmessungen zu den Positionsangaben gezählt, da Java die Boxen immer "mittig" positioniert". Zur Überprüfung habe ich noch ein Koordinatenkreuz sowie Punkte bei (1,0,0), (0,1,0) und (0,0,1) gezeichnet. Wie man sehen kann, erreicht die Box die Eckpunkte, obwohl die Seitenlängen nur 0.5f sind. Zusätzlich muss ich zu den originalen (x,y,z) Werten jeweils (w,h,d) addieren, um mit der Ecke beim Ursprung zu landen. 
Damit könnte ich zwar leben, aber wenn ich eine neue Box mit anderen Dimensionen platzieren will, muss ich die Abmessungen der vorherigen Box kennen (siehe blaue Box daneben). Das ist bestimmt irgendwie machbar, aber ist natürlich wenig sinnvoll, wenn ich ja bereits bei allen Boxen die (x,y,z) Werte habe.

Hat jemand eine Idee, warum die Boxen mit doppelter Länge erzeugt werden oder was falsch an unten stehendem Code ist?


```
import java.applet.Applet; 
import java.awt.BorderLayout; 
import java.awt.GraphicsConfiguration; 
import java.awt.Color;

import com.sun.j3d.utils.applet.MainFrame; 
import com.sun.j3d.utils.geometry.*; 
import com.sun.j3d.utils.universe.*; 
import com.sun.j3d.utils.behaviors.mouse.*; 

import javax.media.j3d.*;
import javax.vecmath.*;

public class showPacking3D extends Applet { 
    
        
    protected TransformGroup objRotate = new TransformGroup(); 
    protected BranchGroup objRoot = new BranchGroup();
    //Zähler für Farbwechsel
    protected int counter = 0;
    
    public showPacking3D() { 
          setLayout(new BorderLayout()); 
          GraphicsConfiguration config = SimpleUniverse.getPreferredConfiguration(); 
          Canvas3D canvas3D = new Canvas3D(config); 
          add("Center", canvas3D); 
          BranchGroup scene = createSceneGraph(); 
          SimpleUniverse simpleU = new SimpleUniverse(canvas3D); 
          simpleU.getViewingPlatform().setNominalViewingTransform(); 
          simpleU.addBranchGraph(scene); 
     } 
     
    public BranchGroup createSceneGraph() { 
          
          
          //Transformgroup objRotate rotierbar machen  
          addMouseActions();
        
          addBox(0.5f,0.5f,0.5f,0.0f,0.0f,0.0f, getColor());
          addBox(0.25f,0.25f,0.25f,1.0f,0.0f,0.0f, getColor());

          addCornerPoint(0.0f,1.0f,0.0f);
          addCornerPoint(1.0f,0.0f,0.0f);
          addCornerPoint(0.0f,0.0f,1.0f);
          // weiße Hintergrundfarbe festlegen
          Color3f bgColor = new Color3f(1.0f, 1.0f, 1.0f);     
          Background bgNode = new Background(bgColor);
          bgNode.setApplicationBounds(new BoundingSphere());
          objRoot.addChild(bgNode);
          //Koordinatensystem erzeugen
          objRoot.addChild(this.erzeugeKoordinatensystem());
          
          objRoot.compile(); 
          return objRoot; 
     } 
     
     private void addMouseActions(){
          //Interaktionen erlauben
          objRotate.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); 
          objRotate.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
          objRoot.addChild(objRotate);
                           
          //Mouse Rotation
          MouseRotate myMouseRotate = new MouseRotate(); 
          myMouseRotate.setTransformGroup(objRotate); 
          myMouseRotate.setSchedulingBounds(new BoundingSphere()); 
          objRoot.addChild(myMouseRotate); 
          //Mouse Bewegung
          MouseTranslate myMouseTranslate = new MouseTranslate();
          myMouseTranslate.setTransformGroup(objRotate);  // ---------------(5)
          myMouseTranslate.setSchedulingBounds(new BoundingSphere());   // ---------------(6)
          objRoot.addChild(myMouseTranslate);
          //Mouse Zoom
          MouseZoom myMouseZoom = new MouseZoom();
          myMouseZoom.setTransformGroup(objRotate);  // ---------------(7)
          myMouseZoom.setSchedulingBounds(new BoundingSphere());   // ---------------(8)
          objRoot.addChild(myMouseZoom);
        }
         
     private void addBox(float w, float h, float d, float x, float y, float z, Color3f col){
         TransformGroup tg = new TransformGroup(); 
         Transform3D transform = new Transform3D();
         float offset = 1.0f;
         Vector3f vector = new Vector3f(x + offset*w,y + offset*h, z + offset*d);
         transform.setTranslation(vector);
         tg.setTransform(transform);
         objRotate.addChild(tg); 
         Appearance app = new Appearance();
         ColoringAttributes ca = new ColoringAttributes(col, ColoringAttributes.NICEST); 
         app.setColoringAttributes(ca);
         Box box = new Box(w,h,d,Box.ENABLE_APPEARANCE_MODIFY | Box.GENERATE_NORMALS,app);
         tg.addChild(box);
        }
        
     private void addCornerPoint(float x, float y, float z){
         TransformGroup tg = new TransformGroup(); 
         Transform3D transform = new Transform3D();
         Vector3f vector = new Vector3f(x,y,z);
         transform.setTranslation(vector);
         tg.setTransform(transform);
         tg.addChild(new Sphere(0.05f));
         objRotate.addChild(tg); 
     }
     
     private Shape3D erzeugeKoordinatensystem(){
        /* LineArray zur Aufnahme des Koordinatensystems erzeugen         */
        LineArray kreuz = new LineArray(6,GeometryArray.COORDINATES
                                          | GeometryArray.COLOR_3);
    
        /* X-Achse in rot zeichnen                                        */
        kreuz.setCoordinate( 0, new Point3f( -40.0f, 0.0f, 0.0f ));
        kreuz.setCoordinate( 1, new Point3f(  40.0f, 0.0f, 0.0f ));
        kreuz.setColor(0,new Color3f(Color.red));
        kreuz.setColor(1,new Color3f(Color.red));
    
        /* Y-Achse in gruen zeichnen                                      */
        kreuz.setCoordinate( 2, new Point3f(  0.0f, -40.0f, 0.0f ));
        kreuz.setCoordinate( 3, new Point3f(  0.0f,  40.0f, 0.0f ));
        kreuz.setColor(2,new Color3f(Color.green));
        kreuz.setColor(3,new Color3f(Color.green));
    
        /* Z-Achse in blau zeichnen                                       */
        kreuz.setCoordinate( 4, new Point3f(  0.0f, 0.0f, -40.0f ));
        kreuz.setCoordinate( 5, new Point3f(  0.0f, 0.0f,  40.0f ));
        kreuz.setColor(4,new Color3f(Color.blue));
        kreuz.setColor(5,new Color3f(Color.blue));
    
        return new Shape3D(kreuz);
     }  
        
     private Color3f getColor(){
      counter++;   
          
      //neue Farbe
      Color3f col = new Color3f();
      
      switch(counter % 6){
        case 1:
            return col = new Color3f(Color.red);
        case 2:
            return col = new Color3f(Color.blue);
        case 3:
            return col = new Color3f(Color.yellow);
        case 4:
            return col = new Color3f(Color.green);
        case 5:
            return col = new Color3f(Color.gray);
        default:
            return col = new Color3f(Color.cyan);
        } 
    }
     
     
    public static void main(String[] args) { 
        new MainFrame(new showPacking3D(), 512, 512); 
     } 
}
```


----------



## Peet0r (14. Jan 2014)

Wenn man nur die Hälfte der gewünschten Dimensionen der Box angibt, scheint es zu funktionieren. Da passt dann auch meine Logik mit x + w/2 als x Koordinate wieder. Ich kann mir das zwar nicht erklären, da sich die Doku diesbezüglich ausschweigt, aber vereinzelt wird auch davon bei Onkel Google berichtet (eigentlich viel zu selten bei so einem Standard-Fall...).

Kurzum: ich verstehe es nicht, aber indem man alle Dimensionen halbiert, kommt das richtige raus. :bloed:


----------

