• Advertisement
Sign in to follow this  

[java] inheritance problem

This topic is 4475 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, I'm creating a small 3D engine in Java 1.5 w/o any 3D API. Here's a pic of what it does right now: Pic. It creates triangles and interpolate colors. I'm having trouble compiling a class. I have a Mesh3D class, that ask for an array of Vertex3D and an array of Face3D in it's constructor. the class is in my "base3D" package
package base3D;

public class Mesh3D {
    protected Point3D _position;
    protected Vecteur3D _orientation;
    protected Vertex3D[] _vertices;
    protected Face3D[] _faces;
    
    /** Creates a new instance of Mesh3D */
    public Mesh3D(Vertex3D[] vertices, Face3D[] faces) {
        this(vertices, faces, Point3D.pORIGINE, Vecteur3D.vJ);
    }
    public Mesh3D(Vertex3D[] vertices, Face3D[] faces, Point3D position, Vecteur3D orientation) {
        _position = position;
        _orientation = orientation;
        
        _vertices = vertices;
        _faces = faces;
        
        for(Vertex3D v : _vertices){
            v.getNormal().normalize();
        }
    }
    
    //then a bunch of getter/setter methods
}


Now, the class that I'm having trouble with is "Plane". A Plane (is a quad) is a Mesh3D, but instead of giving it arrays of Vertex3D and Face3D, it needs parameters to build it (lenght, width, number of segments,...). Plane is in a subpackage called primitive3D.
package base3D.primitive3D;

import base3D.*;

public class Plane extends Mesh3D{
    /** Creates a new instance of Plane */
    public Plane(float largeur, float profondeur) {
        this(largeur, profondeur, 0, 0, 0, 1, 1);
    }
    
    public Plane(float largeur, float profondeur, Point3D pivot){
        this(largeur, profondeur, pivot.getX(), pivot.getY(), pivot.getZ(), 1, 1);
    }
    
    public Plane(float largeur, float profondeur, Point3D pivot, int segLargeur, int segProfondeur){
        this(largeur, profondeur, pivot.getX(), pivot.getY(), pivot.getZ(), segLargeur, segProfondeur);
    }
    
    public Plane(float largeur, float profondeur, float pivotX, float pivotY, float pivotZ, int segLargeur, int segProfondeur){
        
        _position = new Point3D(pivotX, pivotY, pivotZ);
        _orientation = Vecteur3D.vJ;
        
        if(segLargeur<1 || segProfondeur<1){
            System.err.println("-- Numbers of segments are invalid\n--- segLargeur="+ segLargeur +" segProfondeur="+ segProfondeur);
            //do stuff
            segLargeur = ((segLargeur<1) ? 1 : segLargeur);
            segProfondeur = ((segProfondeur<1) ? 1 : segProfondeur);
        }
        //Set the vertices
        int numPoints = (segLargeur+1)*(segProfondeur+1);
        _vertices = new Vertex3D[numPoints];
        
        float startPointX = pivotX - largeur/2;
        float startPointY = pivotY - profondeur/2;
        
        float largeurIncrement = largeur/segLargeur;
        float profondeurIncrement = profondeur/segProfondeur;
        
        int jump = segLargeur+1;
        
        for(int i = 0; i <= segProfondeur; i++){
            for(int j = 0; j <= segLargeur; j++){
                _vertices[i*jump + j] = new Vertex3D(startPointX + j*largeurIncrement,
                        startPointY + i*profondeurIncrement, pivotZ);
            }
        }
        
        //Set the faces
        int numFaces = segLargeur*segProfondeur*2;
        _faces = new Face3D[numFaces];
        int cnt1 = 0, cnt2 = 0;
        for(int i = 0; i <= numFaces-2; i+=2){
            _faces = new Face3D(_vertices[i-cnt2], _vertices[i-cnt2+segLargeur+2], _vertices[i-cnt2+segLargeur+1]);
            //System.out.println("F"+i+" = "+ (i-cnt2) +", "+ (i-cnt2+segLargeur+2) +", "+ (i-cnt2+segLargeur+1));
            ++cnt1;
            ++cnt2;
            if(cnt1==segLargeur){
                cnt1 = 0;
                --cnt2;
            }
        }
        
        cnt1 = 0;
        cnt2 = 1;
        for(int i = 1; i <= numFaces-1; i+=2){
            _faces = new Face3D(_vertices[i-cnt2], _vertices[i-cnt2+1], _vertices[i-cnt2+segLargeur+2]);
            //System.out.println("F"+i+" = "+ (i-cnt2) +", "+ (i-cnt2+1) +", "+ (i-cnt2+segLargeur+2));
            ++cnt1;
            ++cnt2;
            if(cnt1==segLargeur){
                cnt1 = 0;
                --cnt2;
            }
        }
        
        for(Vertex3D v : _vertices){
            v.getNormal().normalize();
        }
        
    }
}


when I compile Plane, I get
init:
deps-jar:
Compiling 1 source file to C:\Documents and Settings\Iarus\Mes documents\Java\Iarus3D_v0_5\build\classes
C:\Documents and Settings\Iarus\Mes documents\Java\Iarus3D_v0_5\src\base3D\primitive3D\Plane.java:27: cannot find symbol
symbol  : constructor Mesh3D()
location: class base3D.Mesh3D
    public Plane(float largeur, float profondeur, float pivotX, float pivotY, float pivotZ, int segLargeur, int segProfondeur){
1 error
BUILD FAILED (total time: 1 second)


Normally I would call super() on the first line of the constructor, but I need to build the data... How do I fix that??

Share this post


Link to post
Share on other sites
Advertisement
It would really help if we could see the rest of the source files. Please edit your post!

EDIT: Thanks. I'll have a squiz.

EDIT: All I can see on line 27 is:
segLargeur = ((segLargeur<1) ? 1 : segLargeur);
Can you please post the original java file that caused the compiler error, and not the version you are using just to get it working?

EDIT: At this stage, all I can do is guess. You need to create a parameterless constructor in Mesh3D.

Share this post


Link to post
Share on other sites
oh yeah sorry, I removed some useless comments. just add 8 empty lines after the package instruction
line 27 points toward the header of the last constructor
public Plane(float largeur, float profondeur, float pivotX, float pivotY, float pivotZ, int segLargeur, int segProfondeur){

about the parameterless constructor, I thought of that too, but I dont want to risk creating an empty Mesh3D object. Is it possible to make that parameterless constructor private or protected? That could be a little bit more "secure". Can I do that:
protected class Mesh3D(){
//I have no data, so I'll create an empty Mesh3D object
//please dont use me, I'm full of NULLs
}

Share this post


Link to post
Share on other sites
Of course, initializers could show any of the public, protected, package, or private keywords. However, as soon as you have set-up _any_ initializer, Java will not create the default initializer, so there is no need to do what you've asked for in this case.

However, the syntax you've posted is for making the _class_ protected, and not its initializer.

Share this post


Link to post
Share on other sites
The problem with your code is that the initializers (notice that this is the correct word if working with Java, not c'tor) of your Plane class all invoke the empty initializer of Mesh3D, since you have not specified which initializer to invoke. However, you have no such initializer in Mesh3D class, so the compiler complains correctly that it could not find one.

Looking at your code, I assume that e.g. this

public Plane(float largeur, float profondeur, float pivotX, float pivotY, float pivotZ, int segLargeur, int segProfondeur) {
// own initialization stuff ...
}


should look like this

public Plane(float largeur, float profondeur, float pivotX, float pivotY, float pivotZ, int segLargeur, int segProfondeur) {
super(/*some arguments here*/);
// own initialization stuff ...
}



"Super" is the keyword for the class the current class extends, so that in your case "super" stands for the Mesh3D class. Since no method name is appended to "super" here, the matching initializer of class Mesh3D is meant.


Interestingly there is no matching initializer in Mesh3D as far as I see (I don't speak french, so I don't know the meaning of your parameters, but the types doesn't match very well). So I assume you perhaps actually have the need for an protected parameterless initializer?


EDIT: Hah. I've written "I don't speech french". That could be read "I can't write english, too" ;)

[Edited by - haegarr on January 19, 2006 1:40:39 PM]

Share this post


Link to post
Share on other sites
yeah sorry I have a bad habit of programming in "frenglish" 50% in french and 50% in english and sometimes a method name can have the two languages in it...

so largeur = width,
profondeur = depth or lenght,
pivot is ..the pivot, the point in space around witch the plane is build
segLargeur = the number of segments along the width side
segProfondeur = the number of segments along the lenght side

when I call "this()" in my construtors (or initialisers if you wish) is because the current initializer generate some default values and then hand those parameters to an other initializer that needs more parameters to create the Plane.

I'm starting to think that I should delete this Plane class and replace it by a Mesh3D method like
public static Mesh3D createPlane(parameters){
//create the data
return new Mesh3D(data)
}


What do you think?

Share this post


Link to post
Share on other sites
First, using the this(...) initializer forwarding is ok. However, at least one of the initializers does _not_ invoke one of the others of the same class. And those initializer/s has/have to invoke one initializer of the super class!

In your code it is just
Plane(float largeur, float profondeur, float pivotX, float pivotY, float pivotZ, int segLargeur, int segProfondeur)

Since you haven't written any _explicit_ invocation of super into it, the compiler completes automatically the parameterless super() invocation that, in your case, will be the initializer Mesh3D.Mesh3D(). However, your Mesh3D class doesn't have such an initializer. Hence the compiler complains.

Quote:
Original post by Iarus
I'm starting to think that I should delete this Plane class and replace it by a Mesh3D method like
*** code removed ***
What do you think?

It depends on what you plan to do furthur. I think it isn't a good idea if it is exlusive due to the following reason: You artificially restrict the generation of kinds of Mesh3D to those for which a factory method exists in the Mesh3D class. So you suffer from 2 things: Each new kind (sphere, cylinder, cone, torus, ...) requires a factory method inside Mesh3D. And no one could write its own sub-type of mesh.

However, if it is though to make the Mesh3D class that general that it could handle meshed of any shape, well, then it is okay. But you have to recall that you will never again know that a Mesh3D represents a plane, or a sphere, or whatever. A mesh will be a mesh will be a mesh, but that may be okay. However, I would nevertheless build-in the ability for client to inherit Mesh3D for own purposes.


EDIT: You also may take into account to make Mesh3D open enough to represent all shapes possible, and to write a Plane class with just nothing more than factories for planes, i.e. a Mesh3D that represents a plane. Similarly, a Sphere class may produce spheres, i.e. a Mesh3D that is set-up to represent a sphere. That may avoid to clutter the Mesh3D class with many many factories, letting it concentrate on common mesh stuff.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement