List of usage examples for javax.media.j3d Appearance Appearance
public Appearance()
From source file:LightTest.java
public Group createGeometry() { m_TransformGroup = new TransformGroup(); m_TransformGroup.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); m_TransformGroup.setCapability(TransformGroup.ALLOW_TRANSFORM_READ); // create appearance and material for the Cone Appearance app = new Appearance(); // create the Primitive and add to the parent BranchGroup m_Cone = new Cone(1, 10, Primitive.ENABLE_APPEARANCE_MODIFY | Primitive.GENERATE_NORMALS, app); m_TransformGroup.addChild(m_Cone);/*from www . j a v a 2s .c o m*/ Group superGroup = super.createGeometry(); superGroup.addChild(m_TransformGroup); return superGroup; }
From source file:LightTest.java
public void synchLightToUi() { super.synchLightToUi(); // set some defaults if things go wrong... double x = 0; double y = 0; double z = 0; try {//w w w. j ava 2 s .c o m x = Double.valueOf(m_XDirectionTextField.getText()).doubleValue(); y = Double.valueOf(m_YDirectionTextField.getText()).doubleValue(); z = Double.valueOf(m_ZDirectionTextField.getText()).doubleValue(); } catch (java.lang.NumberFormatException e) { // invalid numeric input - just ignore. } ((DirectionalLight) m_Light).setDirection((float) x, (float) y, (float) z); if (m_TransformGroup != null) { Vector3d coneVector = new Vector3d(0, 1, 0); Vector3d lightVector = new Vector3d(x, y, z); coneVector.normalize(); lightVector.normalize(); Vector3d axisVector = new Vector3d(); axisVector.cross(coneVector, lightVector); double angle = java.lang.Math.acos(coneVector.dot(lightVector)); AxisAngle4d rotAxis = new AxisAngle4d(axisVector.x, axisVector.y, axisVector.z, angle); Transform3D t3d = new Transform3D(); t3d.setRotation(rotAxis); m_TransformGroup.setTransform(t3d); } if (m_Cone != null) { Appearance app = new Appearance(); Color3f objColor = new Color3f(); m_Light.getColor(objColor); Color3f black = new Color3f(0.0f, 0.0f, 0.0f); app.setMaterial(new Material(objColor, black, objColor, black, 80.0f)); m_Cone.setAppearance(app); } }
From source file:FourByFour.java
/** * Create the scenegraph for the 3D view. *//*from w w w . j a v a2s . c o m*/ public BranchGroup createScene3D() { // Define colors Color3f white = new Color3f(1.0f, 1.0f, 1.0f); Color3f black = new Color3f(0.0f, 0.0f, 0.0f); Color3f red = new Color3f(0.80f, 0.20f, 0.2f); Color3f ambient = new Color3f(0.25f, 0.25f, 0.25f); Color3f diffuse = new Color3f(0.7f, 0.7f, 0.7f); Color3f specular = new Color3f(0.9f, 0.9f, 0.9f); Color3f ambientRed = new Color3f(0.2f, 0.05f, 0.0f); Color3f bgColor = new Color3f(0.05f, 0.05f, 0.2f); // Create the branch group BranchGroup branchGroup = new BranchGroup(); // Create the bounding leaf node BoundingSphere bounds = new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 1000.0); BoundingLeaf boundingLeaf = new BoundingLeaf(bounds); branchGroup.addChild(boundingLeaf); // Create the background Background bg = new Background(bgColor); bg.setApplicationBounds(bounds); branchGroup.addChild(bg); // Create the ambient light AmbientLight ambLight = new AmbientLight(white); ambLight.setInfluencingBounds(bounds); branchGroup.addChild(ambLight); // Create the directional light Vector3f dir = new Vector3f(-1.0f, -1.0f, -1.0f); DirectionalLight dirLight = new DirectionalLight(white, dir); dirLight.setInfluencingBounds(bounds); branchGroup.addChild(dirLight); // Create the pole appearance Material poleMaterial = new Material(ambient, black, diffuse, specular, 110.f); poleMaterial.setLightingEnable(true); Appearance poleAppearance = new Appearance(); poleAppearance.setMaterial(poleMaterial); // Create the transform group node TransformGroup transformGroup = new TransformGroup(); transformGroup.setCapability(TransformGroup.ALLOW_TRANSFORM_READ); transformGroup.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); branchGroup.addChild(transformGroup); // Create the poles Poles poles = new Poles(poleAppearance); transformGroup.addChild(poles.getChild()); // Add the position markers to the transform group transformGroup.addChild(positions.getChild()); // Let the positions object know about the transform group positions.setTransformGroup(transformGroup); // Create the mouse pick and drag behavior node PickDragBehavior behavior = new PickDragBehavior(canvas2D, canvas3D, positions, branchGroup, transformGroup); behavior.setSchedulingBounds(bounds); transformGroup.addChild(behavior); return branchGroup; }
From source file:ExSpotLight.java
public AnnotationLine(float x, float y, float z, float x2, float y2, float z2) { float[] coord = new float[3]; float[] texcoord = new float[2]; // Build a shape shape = new Shape3D(); shape.setCapability(Shape3D.ALLOW_APPEARANCE_WRITE); // Create geometry for a 2-vertex straight line line = new LineArray(2, GeometryArray.COORDINATES | GeometryArray.TEXTURE_COORDINATE_2); line.setCapability(GeometryArray.ALLOW_COLOR_WRITE); // Starting point coord[0] = x;//from ww w. ja va 2 s .c o m coord[1] = y; coord[2] = z; texcoord[0] = 0.0f; texcoord[1] = 0.0f; line.setCoordinate(0, coord); line.setTextureCoordinate(0, texcoord); // Ending point coord[0] = x2; coord[1] = y2; coord[2] = z2; texcoord[0] = 1.0f; texcoord[1] = 0.0f; line.setCoordinate(1, coord); line.setTextureCoordinate(1, texcoord); shape.setGeometry(line); // Create an appearance mainAppearance = new Appearance(); mainAppearance.setCapability(Appearance.ALLOW_LINE_ATTRIBUTES_WRITE); mainAppearance.setCapability(Appearance.ALLOW_COLORING_ATTRIBUTES_WRITE); lineAttributes = new LineAttributes(); lineAttributes.setLineWidth(lineWidth); mainAppearance.setLineAttributes(lineAttributes); coloringAttributes = new ColoringAttributes(); coloringAttributes.setColor(lineColor); coloringAttributes.setShadeModel(ColoringAttributes.SHADE_FLAT); mainAppearance.setColoringAttributes(coloringAttributes); addChild(shape); }
From source file:TextureByReference.java
public Tetrahedron(boolean byRef) { if (byRef) {//from ww w.jav a 2s .co m createGeometryByRef(); this.setGeometry(geometryByRef); } else { createGeometryByCopy(); this.setGeometry(geometryByCopy); } this.setCapability(Shape3D.ALLOW_GEOMETRY_READ); this.setCapability(Shape3D.ALLOW_GEOMETRY_WRITE); setAppearance(new Appearance()); }
From source file:ExSpotLight.java
public SphereGroup(float radius, float xSpacing, float ySpacing, int xCount, int yCount, Appearance app) { if (app == null) { app = new Appearance(); Material material = new Material(); material.setDiffuseColor(new Color3f(0.8f, 0.8f, 0.8f)); material.setSpecularColor(new Color3f(0.0f, 0.0f, 0.0f)); material.setShininess(0.0f);/*from ww w .j a v a 2 s . c om*/ app.setMaterial(material); } double xStart = -xSpacing * (double) (xCount - 1) / 2.0; double yStart = -ySpacing * (double) (yCount - 1) / 2.0; Sphere sphere = null; TransformGroup trans = null; Transform3D t3d = new Transform3D(); Vector3d vec = new Vector3d(); double x, y = yStart, z = 0.0; for (int i = 0; i < yCount; i++) { x = xStart; for (int j = 0; j < xCount; j++) { vec.set(x, y, z); t3d.setTranslation(vec); trans = new TransformGroup(t3d); addChild(trans); sphere = new Sphere(radius, // sphere radius Primitive.GENERATE_NORMALS, // generate normals 16, // 16 divisions radially app); // it's appearance trans.addChild(sphere); x += xSpacing; } y += ySpacing; } }
From source file:TransformExplorer.java
CoordSys(float axisLength) { super(Switch.CHILD_ALL); float coordSysLength = axisLength; float labelOffset = axisLength / 20.0f; float axisRadius = axisLength / 500.0f; float arrowRadius = axisLength / 125.0f; float arrowHeight = axisLength / 50.0f; float tickRadius = axisLength / 125.0f; float tickHeight = axisLength / 250.0f; // Set the Switch to allow changes setCapability(Switch.ALLOW_SWITCH_READ); setCapability(Switch.ALLOW_SWITCH_WRITE); // Set up an appearance to make the Axis have // grey ambient, black emmissive, grey diffuse and grey specular // coloring./*w w w . j a v a 2 s. co m*/ //Material material = new Material(grey, black, grey, white, 64); Material material = new Material(white, black, white, white, 64); Appearance appearance = new Appearance(); appearance.setMaterial(material); // Create a shared group to hold one axis of the coord sys SharedGroup coordAxisSG = new SharedGroup(); // create a cylinder for the central line of the axis Cylinder cylinder = new Cylinder(axisRadius, coordSysLength, appearance); // cylinder goes from -coordSysLength/2 to coordSysLength in y coordAxisSG.addChild(cylinder); // create the shared arrowhead Cone arrowHead = new Cone(arrowRadius, arrowHeight, appearance); SharedGroup arrowHeadSG = new SharedGroup(); arrowHeadSG.addChild(arrowHead); // Create a TransformGroup to move the arrowhead to the top of the // axis // The arrowhead goes from -arrowHeight/2 to arrowHeight/2 in y. // Put it at the top of the axis, coordSysLength / 2 tmpVector.set(0.0f, coordSysLength / 2 + arrowHeight / 2, 0.0f); tmpTrans.set(tmpVector); TransformGroup topTG = new TransformGroup(); topTG.setTransform(tmpTrans); topTG.addChild(new Link(arrowHeadSG)); coordAxisSG.addChild(topTG); // create the minus arrowhead // Create a TransformGroup to turn the cone upside down: // Rotate 180 degrees around Z axis tmpAxisAngle.set(0.0f, 0.0f, 1.0f, (float) Math.toRadians(180)); tmpTrans.set(tmpAxisAngle); // Put the arrowhead at the bottom of the axis tmpVector.set(0.0f, -coordSysLength / 2 - arrowHeight / 2, 0.0f); tmpTrans.setTranslation(tmpVector); TransformGroup bottomTG = new TransformGroup(); bottomTG.setTransform(tmpTrans); bottomTG.addChild(new Link(arrowHeadSG)); coordAxisSG.addChild(bottomTG); // Now add "ticks" at 1, 2, 3, etc. // create a shared group for the tick Cylinder tick = new Cylinder(tickRadius, tickHeight, appearance); SharedGroup tickSG = new SharedGroup(); tickSG.addChild(tick); // transform each instance and add it to the coord axis group int maxTick = (int) (coordSysLength / 2); int minTick = -maxTick; for (int i = minTick; i <= maxTick; i++) { if (i == 0) continue; // no tick at 0 // use a TransformGroup to offset to the tick location TransformGroup tickTG = new TransformGroup(); tmpVector.set(0.0f, (float) i, 0.0f); tmpTrans.set(tmpVector); tickTG.setTransform(tmpTrans); // then link to an instance of the Tick shared group tickTG.addChild(new Link(tickSG)); // add the TransformGroup to the coord axis coordAxisSG.addChild(tickTG); } // add a Link to the axis SharedGroup to the coordSys addChild(new Link(coordAxisSG)); // Y axis // Create TransformGroups for the X and Z axes TransformGroup xAxisTG = new TransformGroup(); // rotate 90 degrees around Z axis tmpAxisAngle.set(0.0f, 0.0f, 1.0f, (float) Math.toRadians(90)); tmpTrans.set(tmpAxisAngle); xAxisTG.setTransform(tmpTrans); xAxisTG.addChild(new Link(coordAxisSG)); addChild(xAxisTG); // X axis TransformGroup zAxisTG = new TransformGroup(); // rotate 90 degrees around X axis tmpAxisAngle.set(1.0f, 0.0f, 0.0f, (float) Math.toRadians(90)); tmpTrans.set(tmpAxisAngle); zAxisTG.setTransform(tmpTrans); zAxisTG.addChild(new Link(coordAxisSG)); addChild(zAxisTG); // Z axis // Add the labels. First we need a Font3D for the Text3Ds // select the default font, plain style, 0.5 tall. Use null for // the extrusion so we get "flat" text since we will be putting it // into an oriented Shape3D Font3D f3d = new Font3D(new Font("Default", Font.PLAIN, 1), null); // set up the +X label Text3D plusXText = new Text3D(f3d, "+X", origin, Text3D.ALIGN_CENTER, Text3D.PATH_RIGHT); // orient around the local origin OrientedShape3D plusXTextShape = new OrientedShape3D(plusXText, appearance, OrientedShape3D.ROTATE_ABOUT_POINT, origin); // transform to scale down to 0.15 in height, locate at end of axis TransformGroup plusXTG = new TransformGroup(); tmpVector.set(coordSysLength / 2 + labelOffset, 0.0f, 0.0f); tmpTrans.set(0.15f, tmpVector); plusXTG.setTransform(tmpTrans); plusXTG.addChild(plusXTextShape); addChild(plusXTG); // set up the -X label Text3D minusXText = new Text3D(f3d, "-X", origin, Text3D.ALIGN_CENTER, Text3D.PATH_RIGHT); // orient around the local origin OrientedShape3D minusXTextShape = new OrientedShape3D(minusXText, appearance, OrientedShape3D.ROTATE_ABOUT_POINT, origin); // transform to scale down to 0.15 in height, locate at end of axis TransformGroup minusXTG = new TransformGroup(); tmpVector.set(-coordSysLength / 2 - labelOffset, 0.0f, 0.0f); tmpTrans.set(0.15f, tmpVector); minusXTG.setTransform(tmpTrans); minusXTG.addChild(minusXTextShape); addChild(minusXTG); // set up the +Y label Text3D plusYText = new Text3D(f3d, "+Y", origin, Text3D.ALIGN_CENTER, Text3D.PATH_RIGHT); // orient around the local origin OrientedShape3D plusYTextShape = new OrientedShape3D(plusYText, appearance, OrientedShape3D.ROTATE_ABOUT_POINT, origin); // transform to scale down to 0.15 in height, locate at end of axis TransformGroup plusYTG = new TransformGroup(); tmpVector.set(0.0f, coordSysLength / 2 + labelOffset, 0.0f); tmpTrans.set(0.15f, tmpVector); plusYTG.setTransform(tmpTrans); plusYTG.addChild(plusYTextShape); addChild(plusYTG); // set up the -Y label Text3D minusYText = new Text3D(f3d, "-Y", origin, Text3D.ALIGN_CENTER, Text3D.PATH_RIGHT); // orient around the local origin OrientedShape3D minusYTextShape = new OrientedShape3D(minusYText, appearance, OrientedShape3D.ROTATE_ABOUT_POINT, origin); // transform to scale down to 0.15 in height, locate at end of axis TransformGroup minusYTG = new TransformGroup(); tmpVector.set(0.0f, -coordSysLength / 2 - labelOffset, 0.0f); tmpTrans.set(0.15f, tmpVector); minusYTG.setTransform(tmpTrans); minusYTG.addChild(minusYTextShape); addChild(minusYTG); // set up the +Z label Text3D plusZText = new Text3D(f3d, "+Z", origin, Text3D.ALIGN_CENTER, Text3D.PATH_RIGHT); // orient around the local origin OrientedShape3D plusZTextShape = new OrientedShape3D(plusZText, appearance, OrientedShape3D.ROTATE_ABOUT_POINT, origin); // transform to scale down to 0.15 in height, locate at end of axis TransformGroup plusZTG = new TransformGroup(); tmpVector.set(0.0f, 0.0f, coordSysLength / 2 + labelOffset); tmpTrans.set(0.15f, tmpVector); plusZTG.setTransform(tmpTrans); plusZTG.addChild(plusZTextShape); addChild(plusZTG); // set up the -Z label Text3D minusZText = new Text3D(f3d, "-Z", origin, Text3D.ALIGN_CENTER, Text3D.PATH_RIGHT); // orient around the local origin OrientedShape3D minusZTextShape = new OrientedShape3D(minusZText, appearance, OrientedShape3D.ROTATE_ABOUT_POINT, origin); // transform to scale down to 0.15 in height, locate at end of axis TransformGroup minusZTG = new TransformGroup(); tmpVector.set(0.0f, 0.0f, -coordSysLength / 2 - labelOffset); tmpTrans.set(0.15f, tmpVector); minusZTG.setTransform(tmpTrans); minusZTG.addChild(minusZTextShape); addChild(minusZTG); }
From source file:ffx.potential.MolecularAssembly.java
private Shape3D renderWire() { ArrayList<ROLS> bonds = getBondList(); int numbonds = bonds.size(); if (numbonds < 1) { return null; }//from w ww . j a v a 2 s . c o m Vector3d bondmidpoint = new Vector3d(); double[] mid = { 0, 0, 0 }; Vector3d v1 = new Vector3d(); Vector3d v2 = new Vector3d(); float[] a1 = { 0, 0, 0 }; float[] a2 = { 0, 0, 0 }; float[] col = new float[4]; Bond bond; Atom atom1, atom2; LineArray la = new LineArray(4 * numbonds, GeometryArray.COORDINATES | GeometryArray.COLOR_4 | GeometryArray.NORMALS); la.setCapability(LineArray.ALLOW_COORDINATE_WRITE); la.setCapability(LineArray.ALLOW_COORDINATE_READ); la.setCapability(LineArray.ALLOW_COLOR_WRITE); la.setCapability(LineArray.ALLOW_COUNT_READ); la.setCapability(LineArray.ALLOW_INTERSECT); la.setCapability(LineArray.ALLOW_FORMAT_READ); atomLookUp = new Atom[4 * numbonds]; int i = 0; col[3] = 0.9f; for (ListIterator li = bonds.listIterator(); li.hasNext();) { bond = (Bond) li.next(); bond.setWire(la, i); atom1 = bond.getAtom(0); atom2 = bond.getAtom(1); atom1.getV3D(v1); atom2.getV3D(v2); a1[0] = (float) v1.x; a1[1] = (float) v1.y; a1[2] = (float) v1.z; a2[0] = (float) v2.x; a2[1] = (float) v2.y; a2[2] = (float) v2.z; // Find the bond center bondmidpoint.add(v1, v2); bondmidpoint.scale(0.5d); bondmidpoint.get(mid); // Atom #1 Atom.AtomColor.get(atom1.getAtomicNumber()).get(col); atomLookUp[i] = atom1; la.setCoordinate(i, a1); la.setColor(i, col); la.setNormal(i, a2); i++; atomLookUp[i] = atom1; la.setCoordinate(i, mid); la.setColor(i, col); la.setNormal(i, a2); i++; // Atom #2 Atom.AtomColor.get(atom2.getAtomicNumber()).get(col); atomLookUp[i] = atom2; la.setCoordinate(i, a2); la.setColor(i, col); la.setNormal(i, a1); i++; atomLookUp[i] = atom2; la.setCoordinate(i, mid); la.setColor(i, col); la.setNormal(i, a1); i++; } ColoringAttributes cola = new ColoringAttributes(new Color3f(), ColoringAttributes.SHADE_GOURAUD); Appearance app = new Appearance(); lineAttributes = new LineAttributes(); lineAttributes.setLineWidth(RendererCache.bondwidth); lineAttributes.setCapability(LineAttributes.ALLOW_WIDTH_WRITE); lineAttributes.setLineAntialiasingEnable(true); app.setLineAttributes(lineAttributes); app.setCapability(Appearance.ALLOW_LINE_ATTRIBUTES_READ); app.setCapability(Appearance.ALLOW_LINE_ATTRIBUTES_WRITE); RenderingAttributes ra = new RenderingAttributes(); ra.setAlphaTestValue(0.1f); ra.setAlphaTestFunction(RenderingAttributes.GREATER); ra.setDepthBufferEnable(true); ra.setDepthBufferWriteEnable(true); app.setRenderingAttributes(ra); app.setColoringAttributes(cola); Shape3D wireframe = new Shape3D(la, app); // PickTool.setCapabilities(wire, PickTool.INTERSECT_COORD); wireframe.setUserData(this); wireframe.setBounds(new BoundingSphere(new Point3d(0, 0, 0), 1000.0)); try { wireframe.setBoundsAutoCompute(false); } catch (Exception e) { e.printStackTrace(); } wireframe.setCapability(Shape3D.ALLOW_GEOMETRY_READ); wireframe.setCapability(Shape3D.ALLOW_APPEARANCE_READ); wireframe.setCapability(Shape3D.ALLOW_LOCAL_TO_VWORLD_READ); return wireframe; }
From source file:Demo3D.java
/** * Construction of the desired borders of the virtual universe (cube). * /* w w w .ja v a2 s . co m*/ * @return javax.media.j3d.Shape3D myUniverse - the constructed borders of * the virtual universe */ public Shape3D myInternalUniverse() { cube = new QuadArray(cubeFaces.length, QuadArray.COORDINATES | QuadArray.TEXTURE_COORDINATE_2); ////////////////////// Geometric part /////////////////////////// // Scaling of the faces. for (int i = 0; i < cubeFaces.length; i++) cubeFaces[i].scale(scale_XYZ); cube.setCoordinates(0, cubeFaces); for (int i = 0; i < cubeFaces.length; i++) { // With i mod 4 ==> 0 1 2 3 0 1 2 3 0 1 2 3 0 1 2 3 for // the 4 vertices of the 6 faces, thus each vertex has // a point in the texture space. In this case, each cube's // face has the same texture coordinates. cube.setTextureCoordinate(0, i, textCoord[i % 4]); } // The geometry is passed to the instance this of the cube. this.setGeometry(cube); ////////////////////// Appearance part /////////////////////////// Appearance appearance = new Appearance(); // This code block is only necessary to insure, in all cases, the // correct // rendering of the 6 faces of the cube (bug in Java3D version 1.2.0 !). // Set up the polygon's rendering-mode PolygonAttributes polygonAttributes = new PolygonAttributes(); polygonAttributes.setPolygonMode(PolygonAttributes.POLYGON_FILL); appearance.setPolygonAttributes(polygonAttributes); // Loading the texture for the 6 cube's faces. newTextureLoader = new NewTextureLoader("Images/Galaxies.gif"); newTextureLoader.setImageObserver(newTextureLoader.getImageObserver()); texture = newTextureLoader.getTexture(); appearance.setTexture(texture); // Application modes of the texture textAttr = new TextureAttributes(); textAttr.setTextureMode(TextureAttributes.MODULATE); // there still are: // BLEND, COMBINE, // DECAL, and REPLACE appearance.setTextureAttributes(textAttr); // The appearance is passed to the instance this of the cube. this.setAppearance(appearance); return this; }
From source file:TransformExplorer.java
RotAxis(float axisLength) { super(Switch.CHILD_NONE); setCapability(Switch.ALLOW_SWITCH_READ); setCapability(Switch.ALLOW_SWITCH_WRITE); // set up the proportions for the arrow float axisRadius = axisLength / 120.0f; float arrowRadius = axisLength / 50.0f; float arrowHeight = axisLength / 30.0f; // create the TransformGroup which will be used to orient the axis axisTG = new TransformGroup(); axisTG.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); axisTG.setCapability(TransformGroup.ALLOW_TRANSFORM_READ); addChild(axisTG);// w w w . j a va 2 s . co m // Set up an appearance to make the Axis have // blue ambient, black emmissive, blue diffuse and white specular // coloring. Material material = new Material(blue, black, blue, white, 64); Appearance appearance = new Appearance(); appearance.setMaterial(material); // create a cylinder for the central line of the axis Cylinder cylinder = new Cylinder(axisRadius, axisLength, appearance); // cylinder goes from -length/2 to length/2 in y axisTG.addChild(cylinder); // create a SharedGroup for the arrowHead Cone arrowHead = new Cone(arrowRadius, arrowHeight, appearance); SharedGroup arrowHeadSG = new SharedGroup(); arrowHeadSG.addChild(arrowHead); // Create a TransformGroup to move the cone to the top of the // cylinder tmpVector.set(0.0f, axisLength / 2 + arrowHeight / 2, 0.0f); tmpTrans.set(tmpVector); TransformGroup topTG = new TransformGroup(); topTG.setTransform(tmpTrans); topTG.addChild(new Link(arrowHeadSG)); axisTG.addChild(topTG); // create the bottom of the arrow // Create a TransformGroup to move the cone to the bottom of the // axis so that its pushes into the bottom of the cylinder tmpVector.set(0.0f, -(axisLength / 2), 0.0f); tmpTrans.set(tmpVector); TransformGroup bottomTG = new TransformGroup(); bottomTG.setTransform(tmpTrans); bottomTG.addChild(new Link(arrowHeadSG)); axisTG.addChild(bottomTG); updateAxisTransform(); }