Pergunta

I'm creating a mobius strip in Java3D. I've got a seam and I can't seem to get rid of it! I'm assuming it's got to do with normals and the fact that the difference in angle between the conjoined edges is technically 180. Can anyone help me remove this seam?

Here's my code:

    public class MobiusStrip extends Applet {
        public static void main(String[] args){
            new MainFrame(new MobiusStrip(), 800, 600);      
        }

        @Override
        public void init(){
            GraphicsConfiguration gc = SimpleUniverse.getPreferredConfiguration();
            Canvas3D canvas = new Canvas3D(gc);
            this.setLayout(new BorderLayout());
            this.add(canvas, BorderLayout.CENTER);
            SimpleUniverse su = new SimpleUniverse(canvas);
            su.getViewingPlatform().setNominalViewingTransform();
            BranchGroup bg = createSceneGraph();
            bg.compile();
            su.addBranchGraph(bg);
        }

        private BranchGroup createSceneGraph(){
            BranchGroup root = new BranchGroup();       
            Shape3D shape = new Shape3D();
            shape.setGeometry(mobius().getIndexedGeometryArray());
            //Scaling transform
            Transform3D tr = new Transform3D();
            tr.setScale(0.5);

            //Spin transform group
            TransformGroup spin = new TransformGroup();
            spin.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
            root.addChild(spin);

            //Set appearance
            Appearance ap = new Appearance();
            PointAttributes pa = new PointAttributes(10, true);
            ap.setPointAttributes(pa);
            ap.setPolygonAttributes(new PolygonAttributes
                    (PolygonAttributes.POLYGON_FILL, 
                    PolygonAttributes.CULL_NONE, 0));

            //Set materials
            Material mat = new Material();
            mat.setLightingEnable(true);
            mat.setShininess(30);
            ap.setMaterial(mat);

            //Overarching Transform group
            TransformGroup tg = new TransformGroup(tr);
            tg.addChild(shape);
            spin.addChild(tg);
            shape.setAppearance(ap);                

            //Set rotation
            Alpha alpha = new Alpha(-1, 6000);
            RotationInterpolator rotate = new RotationInterpolator(alpha, spin);
            BoundingSphere bounds = new BoundingSphere();
            rotate.setSchedulingBounds(bounds);
            spin.addChild(rotate);

            //Set background
            Background background = new Background(1.0f, 1.0f, 1.0f);
            background.setApplicationBounds(bounds);
            root.addChild(background);

            //Set lighting
            AmbientLight light = new AmbientLight(true, new Color3f(Color.BLACK));
            light.setInfluencingBounds(bounds);
            root.addChild(light);

            PointLight ptlight = new PointLight(new Color3f(Color.white),
            new Point3f(0.5f,0.5f,1f),
            new Point3f(1f,0.2f,0f));
            ptlight.setInfluencingBounds(bounds);
            root.addChild(ptlight);

            return root;
        }//Close branchgroup method

        //Create the Mobius shape
        private GeometryInfo mobius()
          {
            int m = 100; //number of row points
            int n = 100; //number of col points
            int p = 4*((m-1)*(n-1)); //faces * points per face

            IndexedQuadArray iqa = new IndexedQuadArray(m*n, 
                          GeometryArray.COORDINATES, p);
            Point3d[] vertices = new Point3d[m*n];
            int index = 0;

            //Create vertices
            for(int i = 0; i < m; i++)
            {
                for(int j = 0; j < n; j++)
                 {
                    double u = i * (2*(Math.PI))/(m - 1);
                    double v = -0.3 + (j * (0.6/(n-1)));
                    double x=(1+v*Math.cos(u/2))*Math.cos(u);
                    double y=(1+v*Math.cos(u/2))*Math.sin(u);
                    double z=v*Math.sin(u/2);
                    vertices[index]=new Point3d(x,y,z);
                    index++;
                }//close nested for loop
             }//close for loop

            iqa.setCoordinates(0, vertices);
            index = 0;

            //set index for coordinates
            for(int i = 0; i < m-1; i++){
                for(int j = 0; j < n-1; j++){
                    iqa.setCoordinateIndex(index, i*m+j);
                    index++;
                    iqa.setCoordinateIndex(index, i*m+j+1);
                    index++;
                    iqa.setCoordinateIndex(index, (i+1)*m+j+1);
                    index++;
                    iqa.setCoordinateIndex(index, (i+1)*m+j);
                    index++;
                }//close nested for loop
            }//close for loop

            //create geometry info and generate normals for shape
            GeometryInfo gi = new GeometryInfo(iqa);
            NormalGenerator ng = new NormalGenerator();
            ng.generateNormals(gi);
            return gi;
        }
    }
Foi útil?

Solução

See this question for more explanation. You'll need two changes:

ap.setPolygonAttributes(new PolygonAttributes(PolygonAttributes.POLYGON_FILL, PolygonAttributes.CULL_BACK, 0));

double u = i * (4 * (Math.PI)) / (m - 1);
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top