Java3D: Ikosaeder mit unterschiedlich gefärbten Flächen

Stefan1971HH

Mitglied
Hi,

ich möchte einen Ikosaeder kontruieren, bei dem jede der 20 Flächen eine andere Farbe hat.
Problem: Egal, ob ich einen TriangleArray oder einen IndexedTriangleArray nutze -
ich kann (falls ich es richtg verstanden habe...) im Daten-Array nur soviele verschiedene Farben speichern, wie es Vertices gibt (nämlich 12).
Vermutlich deswegen wird folgendes mit einer IndexOutOfBounds-Exception und Verweis auf Zeile 84 quittiert:
Java:
public class IcosahedronGeo extends TriangleArray {

  Color3f red = new Color3f(1.0f, 0.0f, 0.0f);
   Color3f green = new Color3f(0.0f, 1.0f, 0.0f);
   Color3f blue = new Color3f(0.0f, 0.0f, 1.0f);
  Color3f yellow = new Color3f(1.0f, 1.0f, 0.0f);
  Color3f cyan = new Color3f(0.0f, 1.0f, 1.0f);
  Color3f magenta = new Color3f(1.0f, 0.0f, 1.0f);
 Color3f white = new Color3f(1.0f, 1.0f, 1.0f);
 Color3f black = new Color3f(0.0f, 0.0f, 0.0f);
 Color3f grey = new Color3f(0.2f, 0.2f, 0.2f);
  Color3f darkRed = new Color3f(0.2f, 0.0f, 0.0f);
   Color3f brown = new Color3f(0.35f, 0.29f, 0.0f);
   Color3f darkBrown = new Color3f(0.15f, 0.1f, 0.0f);
     Color3f darkGrey = new Color3f(0.2f, 0.2f, 0.2f);
    Color3f darkYellow = new Color3f(0.3f, 0.3f, 0.0f);
   Color3f darkGreen = new Color3f(0.0f, 0.3f, 0.0f);
   Color3f darkBlue = new Color3f(0.0f, 0.0f, 0.3f);
    Color3f color1 = new Color3f(0.8f, 0.6f, 0.4f);
    Color3f color2 = new Color3f(0.6f, 0.2f, 0.2f);
    Color3f color3 = new Color3f(0.2f, 0.6f, 0.6f); 
    Color3f color4 = new Color3f(0.9f, 0.5f, 0.3f);
    
    Point3d p0 = new Point3d(0, 0, 1);
    Point3d p1 = new Point3d(0.894, 0, 0.447);
    Point3d p2 = new Point3d(0.276, 0.851, 0.447);
    Point3d p3 = new Point3d(-0.724, 0.526, 0.447);
    Point3d p4 = new Point3d(-0.724, -0.526, 0.447);
    Point3d p5 = new Point3d(0.276, -0.851, 0.447);
    Point3d p6 = new Point3d(0.724, 0.526, -0.447);
    Point3d p7 = new Point3d(-0.276, 0.851, -0.447);
    Point3d p8 = new Point3d(-0.894, 0.000, -0.447);
    Point3d p9 = new Point3d(-0.276, -0.851, -0.447);
    Point3d p10 = new Point3d(0.724, -0.526, -0.447);
    Point3d p11 = new Point3d(0.000, 0.000, -1.000);
    Point3d[] vertices = 
                    {p0,p1,p2,
                     p0,p2,p3,
                     p0,p3,p4,
                     p0,p4,p5,
                     p0,p5,p1,
                     p11,p6,p7,
                     p11,p7,p8,
                     p11,p8,p9,
                     p11,p9,p10,
                     p11,p10,p6,
                     p1,p2,p6,
                     p2,p3,p7,
                     p3,p4,p8,
                     p4,p5,p9,
                     p5,p1,p10,
                     p6,p7,p2,
                     p7,p8,p3,
                     p8,p9,p4,
                     p9,p10,p5,
                     p10,p6,p1};
    
    
    
   Color3f[] colors =
    {red,red,red,
green,green, green,
blue, blue,blue, 
yellow,yellow,yellow,
cyan, cyan, cyan,
darkBrown,darkBrown,darkBrown,
magenta,magenta,magenta,
white,white,white,
black, black,black,
grey,grey,grey,
darkRed,darkRed,darkRed ,
brown, brown,brown, 
darkGrey,darkGrey, darkGrey,
darkYellow,darkYellow,darkYellow,
darkGreen,darkGreen,darkGreen,
darkBlue,darkBlue,darkBlue,
color1,color1,color1,
color2,color2,color2,
color3,color3,
color4,color4,color4};
    
 public IcosahedronGeo(){
        super (12,TriangleArray.COORDINATES | TriangleArray.NORMALS |TriangleArray.COLOR_3);
setCoordinates(0, vertices);

setColors(0, colors);

    }
}
Gibts hier eine schöne Lösung?.danke
 
Zuletzt bearbeitet:

Stefan1971HH

Mitglied
Danke Marco13, aber ich hatte es auch schon mit einem IndexedTriangleArray probiert.
Da hatte ich aber auch das Problem, dass die indizierten Arrays alle gleich lang
sein müssen (d.h. die Daten-Arrays, die dann von den IndexedArrays referenziert
werde). Ich kann also nur 12 verschieden Farben referenzieren, so dass für 20 Flächen
8 Farben doppelt verwendet (referenziert)werden müssten. Bei den anderen platonischen Körpern
ergibt sich dieses Problem nicht, weil der Ikosaeder als einziger mehr Flächen als Ecken hat.
Diese Version sieht so aus:
Java:
package platonicSolids;

import javax.media.j3d.IndexedTriangleArray;
import javax.vecmath.Color3f;
import javax.vecmath.Point3d;

/**
 *
 * @author Stefan
 */
public class IcosahedronGeo extends IndexedTriangleArray {

    Color3f white = new Color3f(1.0f, 1.0f, 1.0f);
    Color3f gray = new Color3f(0.7f, 0.7f, 0.7f);
    Color3f darkGray = new Color3f(0.2f, 0.2f, 0.2f);
    Color3f black = new Color3f(0.0f, 0.0f, 0.0f);
    Color3f red = new Color3f(1.0f, 0.0f, 0.0f);
    Color3f darkRed = new Color3f(0.3f, 0.0f, 0.0f);
    Color3f yellow = new Color3f(1.0f, 1.0f, 0.0f);
    Color3f darkYellow = new Color3f(0.3f, 0.3f, 0.0f);
    Color3f green = new Color3f(0.0f, 1.0f, 0.0f);
    Color3f darkGreen = new Color3f(0.0f, 0.3f, 0.0f);
    Color3f cyan = new Color3f(0.0f, 1.0f, 1.0f);
    Color3f blue = new Color3f(0.0f, 0.0f, 1.0f);
    Color3f darkBlue = new Color3f(0.0f, 0.0f, 0.3f);
    Color3f magenta = new Color3f(1.0f, 0.0f, 1.0f);
    Color3f magenta2 = new Color3f(0.8f, 0.0f, 0.8f);
    Color3f cyan2 = new Color3f(0.0f, 0.3f, 0.3f);
    Color3f color1 = new Color3f(0.8f, 0.6f, 0.4f);
    Color3f color2 = new Color3f(0.6f, 0.2f, 0.2f);
    Color3f color3 = new Color3f(0.2f, 0.6f, 0.6f); 
    Color3f color4 = new Color3f(0.9f, 0.5f, 0.3f);
    
    Point3d p0 = new Point3d(0, 0, 1);
    Point3d p1 = new Point3d(0.894, 0, 0.447);
    Point3d p2 = new Point3d(0.276, 0.851, 0.447);
    Point3d p3 = new Point3d(-0.724, 0.526, 0.447);
    Point3d p4 = new Point3d(-0.724, -0.526, 0.447);
    Point3d p5 = new Point3d(0.276, -0.851, 0.447);
    Point3d p6 = new Point3d(0.724, 0.526, -0.447);
    Point3d p7 = new Point3d(-0.276, 0.851, -0.447);
    Point3d p8 = new Point3d(-0.894, 0.000, -0.447);
    Point3d p9 = new Point3d(-0.276, -0.851, -0.447);
    Point3d p10 = new Point3d(0.724, -0.526, -0.447);
    Point3d p11 = new Point3d(0.000, 0.000, -1.000);
    Point3d[] vertices = {p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11};
    int[]vertInd = {0,1,2,
                    0,2,3,
                    0,3,4,
                    0,4,5,
                    0,5,1,
                    11,6,7,
                    11,7,8,
                    11,8,9,
                    11,9,10,
                    11,10,6,
                    1,2,6,
                    2,3,7,
                    3,4,8,
                    4,5,9,
                    5,1,10,
                    6,7,2,
                    7,8,3,
                    8,9,4,
                    9,10,5,
                    10,6,1};
    Color3f[] colors =
    {white,gray,darkGray,black,red,darkRed,yellow,darkYellow,green,darkGreen,cyan,blue}; 
    
    int[] colorInd = {0,0,0,
                      1,1,1,
                      2,2,2,
                      3,3,3,
                      4,4,4,
                      5,5,5,
                      6,6,6,
                      7,7,7,
                      8,8,8,
                      9,9,9,
                     10,10,10,
                     11,11,11,
                     0,0,0,
                      1,1,1,
                      2,2,2,
                      3,3,3,
                      4,4,4,
                      5,5,5,
                      6,6,6,
                      8,8,8};
    
    
    
    public IcosahedronGeo(){
        super (12, IndexedTriangleArray.COORDINATES | IndexedTriangleArray.NORMALS |IndexedTriangleArray.COLOR_3,60);
setCoordinates(0, vertices);
setCoordinateIndices(0, vertInd);
setColors(0, colors);
setColorIndices(0, colorInd);
    }
}
Es sind zwar 20 Farben definiert, aber wie kann ich mehr als 12 davon verfügbar machen?
Nofalls könnte man den Vertex-Array um 8 Dummy-Vertices erweitern - aber das muss doch
wohl eleganter gehen? Sorry, falls ich deinen Hinweis nicht vollständig erfasst haben sollte.
 

Marco13

Top Contributor
Ahja, sorry, ist schon eine Weile her, und solche Details weiß man nicht unbedingt auswendig :oops: (BTW: Ein Oktaeder hat auch mehr Flächen als Ecken).

Da die GeometryArrays ihre Daten Vertexbasiert speichern, wird man kaum drumherumkommen, die vertices zu duplizieren (wüßte ich jetzt auch kaum eine andere Möglichkeit). Man würde also das ganze "Flächenweise" zu definieren, ähnlich wie es auch beim "ColorCube" gemacht ist ( z.B. java3d 0.0.cvs.20090202.dfsg, ColorCube_8java-source.html ).

Ganz pragmatisch könnte man das natürlich mit sowas machen wie
Java:
    public IcosahedronGeo(){
        super (60, IndexedTriangleArray.COORDINATES | IndexedTriangleArray.COLOR_3, 60);
        
		int numFaces = vertInd.length / 3;
		
		Point3d resultVertices[] = new Point3d[numFaces * 3];
		int resultVertexIndices[] = new int[numFaces * 3];
		
		Color3f resultColors[] = new Color3f[numFaces * 3];
		int resultColorIndices[] = new int[numFaces * 3];
		
		for (int i=0; i<numFaces; i++)
		{
			for (int j=0; j<3; j++)
			{
				int index = i * 3 + j;
				
				int vertexIndex = vertInd[index];
				Point3d v = vertices[vertexIndex];
				resultVertices[index] = v;
				resultVertexIndices[index] = index;
				
				int colorIndex = colorInd[index];
				Color3f c = colors[colorIndex];
				resultColors[index] = c;
				resultColorIndices[index] = index;
			}
		}
		setCoordinates(0, resultVertices);
		setCoordinateIndices(0, resultVertexIndices);
		setColors(0, resultColors);
		setColorIndices(0, resultColorIndices);
        
    }
aber eigentlich braucht man dann gar keinen speziell Indizierten array mehr, d.h. es würde ein GeometryArray schon tun. (Wenn man das für mehrere Fälle braucht, könnte man aber nach so einem Schema eine Methode basteln, der man die Daten in der "gewünschten Form" (d.h. in Form der vorhanderen Arrays) übergibt, und die einem dann durch so ein bißchen Umkopieren+Duplizieren einen passenden GeometryArray ausspuckt... (ich erwähne das nur, um zu verhindern, dass jemand versucht, die Flächen einzeln in den Code zu schreiben, wie es beim ColorCube gemacht ist ;) ))
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
H Java3D, ViewP Translattform soll sich nach einerformgroup richten. AWT, Swing, JavaFX & SWT 5
K Fullscreen Java3D AWT, Swing, JavaFX & SWT 5
T 3D-Grafik (Java3D) Aus einem Objekt einer Szene (Würfel, Ebene) die wichtigen Randkoordinaten auslesen AWT, Swing, JavaFX & SWT 3
T Erstellung einer ShadowMap mit Java3D AWT, Swing, JavaFX & SWT 6
S Hilfe beim Lernprozess von java3d AWT, Swing, JavaFX & SWT 20
K 3D-Grafik Textur Java3d AWT, Swing, JavaFX & SWT 5
S 3D-Grafik Grafikprogramm mit Java3D AWT, Swing, JavaFX & SWT 14
B 3D-Grafik Punkt in JAVA3D darstellen AWT, Swing, JavaFX & SWT 2
B Java3D Szenegraph Export als VRML, .X3D, .OBJ, .POV, U3D oder PLY AWT, Swing, JavaFX & SWT 4
E Java3D im FSEM AWT, Swing, JavaFX & SWT 5
K Java3D - Startposition ? AWT, Swing, JavaFX & SWT 5
M 3D-Grafik Java3D-Application als executable .jar exportieren (Eclipse) AWT, Swing, JavaFX & SWT 5
I 3D-Grafik Java3D RAM AWT, Swing, JavaFX & SWT 3
S 3D-Grafik Java3D und was noch? AWT, Swing, JavaFX & SWT 3
E 3D-Grafik Java3D AWT, Swing, JavaFX & SWT 5
T Java3D - Picking AWT, Swing, JavaFX & SWT 12
L 3D-Grafik Java3D - Alle SceneGraphObjects geordnet erhalten AWT, Swing, JavaFX & SWT 2
S Java3D in ein JPanel integrieren mit Netbeans 6.8 AWT, Swing, JavaFX & SWT 4
S Java3D: Alle Objekte in BranchGroup löschen während Laufzeit AWT, Swing, JavaFX & SWT 3
C java3D - sichtbare Kanten eines Shape3D AWT, Swing, JavaFX & SWT 2
E JavaFX Sehr viel und unterschiedlich Großen Inhalt auf einer "Fläche" ... Umsetzbar ? AWT, Swing, JavaFX & SWT 3
S Swing Größe von JLabels verändern sich in einem Panel unterschiedlich AWT, Swing, JavaFX & SWT 6
N Zellen einer JTable unterschiedlich formatieren AWT, Swing, JavaFX & SWT 7
W jComboBox unterschiedlich selectable elemente AWT, Swing, JavaFX & SWT 7
P Swing [gelöst/erledigt] Gleicher Code läuft unterschiedlich unter Linux und Windows AWT, Swing, JavaFX & SWT 5
R JTable: Zellen einer Spalte unterschiedlich befüllen AWT, Swing, JavaFX & SWT 2
B 3 Zeilen die unterschiedlich gross sind -->Welches Layout AWT, Swing, JavaFX & SWT 3
G abstand zwischen den buttons unterschiedlich AWT, Swing, JavaFX & SWT 2

Ähnliche Java Themen


Oben