0

My Javascript code is throwing this error: "Uncaught TypeError: Cannot read property '0' of undefined". I've been searching this error and it always seems to lead back to an undefined variable, but this doesn't seem to be the case with my code. When I run it through Chrome's debugger, it shows that all of my variables are defined on the line that throws the error. The constructor of my class is called first with parameters (64, -0.5, 0.5, -0.5, 0.5). Within constructor, generateTriangles() is called, which populates this.vBuffer by pushing 12675 floating point values onto it. Then constructor calls diamond_square() which calls getVertex(). The error is thrown on the second line of getVertex(). When the error is thrown, the debugger shows vBuffer is populated with values and vid is 0. It specifically underlines [vid] in red and links it to the error. This code works perfectly without the call to diamond_square() in constructor. Here is the relevant code:

/** Class implementing 3D terrain. */
class Terrain{   
/**
 * Initialize members of a Terrain object
 * @param {number} div Number of triangles along x axis and y axis
 * @param {number} minX Minimum X coordinate value
 * @param {number} maxX Maximum X coordinate value
 * @param {number} minY Minimum Y coordinate value
 * @param {number} maxY Maximum Y coordinate value
 */
    constructor(div,minX,maxX,minY,maxY){
        this.div = div;
        this.minX=minX;
        this.minY=minY;
        this.maxX=maxX;
        this.maxY=maxY;

        // Allocate vertex array
        this.vBuffer = [];
        // Allocate triangle array
        this.fBuffer = [];
        // Allocate normal array
        this.nBuffer = [];
        // Allocate array for edges so we can draw wireframe
        this.eBuffer = [];
        console.log("Terrain: Allocated buffers");

        this.generateTriangles();
        console.log("Terrain: Generated triangles");

        this.diamond_square();
        console.log("Terrain: Performed Diamond-Square");

        this.generateLines();
        console.log("Terrain: Generated lines");

        // Get extension for 4 byte integer indices for drwElements
        var ext = gl.getExtension('OES_element_index_uint');
        if (ext ==null){
            alert("OES_element_index_uint is unsupported by your browser and terrain generation cannot proceed.");
        }
    }

    /**
    * Set the x,y,z coords of a vertex at location(i,j)
    * @param {Object} v an an array of length 3 holding x,y,z coordinates
    * @param {number} i the ith row of vertices
    * @param {number} j the jth column of vertices
    */
    setVertex(v,i,j)
    {
        var vid = 3*(i*(this.div+1) + j);
        this.vbuffer[vid] = v[0];
        this.vbuffer[vid+1] = v[1];
        this.vbuffer[vid+2] = v[2];
    }

    /**
    * Return the x,y,z coordinates of a vertex at location (i,j)
    * @param {Object} v an an array of length 3 holding x,y,z coordinates
    * @param {number} i the ith row of vertices
    * @param {number} j the jth column of vertices
    */
    getVertex(v,i,j)
    {
        var vid = 3*(i*(this.div+1) + j);
        v[0] = this.vbuffer[vid];
        v[1] = this.vbuffer[vid+1];
        v[2] = this.vbuffer[vid+2];
    }

    /**
     * Fill the vertex and buffer arrays 
     */    
    generateTriangles()
    {
        var x_amount = (this.maxX - this.minX) / this.div;
        var y_amount = (this.maxY - this.minY) / this.div;

        for (var i = 0; i <= this.div; i++) {
            for (var j = 0; j <= this.div; j++) {
                this.vBuffer.push(j*x_amount + this.minX);
                this.vBuffer.push(this.minY + i*y_amount);
                this.vBuffer.push(0);

                this.nBuffer.push(0);
                this.nBuffer.push(0);
                this.nBuffer.push(1);
            }
        }

        for (var i = 0; i < this.div; i++) {
            for (var j = 0; j < this.div; j++) {

                var vid = i*(this.div+1) + j;

                this.fBuffer.push(vid);
                this.fBuffer.push(vid + this.div+1);
                this.fBuffer.push(vid + this.div+2);

                this.fBuffer.push(vid);
                this.fBuffer.push(vid+1);
                this.fBuffer.push(vid + this.div+2);
            }
        }

        this.numVertices = this.vBuffer.length/3;
        this.numFaces = this.fBuffer.length/3;
    }

    diamond_square()
    {
        // initialize corners to 0
        var init_value = 0;
        var max = this.div;
        var v = [0.0, 0.0, 0.0];
        // top-left corner
        this.getVertex(v, 0, 0);
        v[2] = init_value;
        this.setVertex(v, 0, 0);
        // bottom-left corner
        this.getVertex(v, 0, max);
        v[2] = init_value;
        this.setVertex(v, 0, max);
        // top-right corner
        this.getVertex(v, max, 0);
        v[2] = init_value;
        this.setVertex(v, max, 0);
        // bottom-right corner
        this.getVertex(v, max, max);
        v[2] = init_value;
        this.setVertex(v, max, max);
        // perform diamond-square recursively on the rest of the vertices
        this.subsection(max);
    }
}
5
  • Can you add the code which causes the error? Commented Oct 25, 2018 at 9:06
  • post the code of the generateTriangles() function Commented Oct 25, 2018 at 9:12
  • Added the generateTriangles() function. What code? It's right there. Commented Oct 25, 2018 at 9:21
  • could u just post the part of the code that contains the error. No one wanna look thru the whole thing. It will make it easier to answer. Commented Oct 25, 2018 at 9:28
  • That's why I explained the important datapath that leads to the error. But it's really not much code. 1 constructor, 4 functions. Commented Oct 25, 2018 at 9:32

1 Answer 1

1

In both the getVertex and setVertex functions you mispelled this.vBuffer, you instead used this.vbuffer that is actually undefined, that is throwing the exception

getVertex(v,i,j) {
  var vid = 3*(i*(this.div+1) + j);
  v[0] = this.vbuffer[vid];  //should be this.vBuffer
  v[1] = this.vbuffer[vid+1]; //should be this.vBuffer
  v[2] = this.vbuffer[vid+2]; //should be this.vBuffer
}

setVertex(v,i,j) {
  var vid = 3*(i*(this.div+1) + j);
  this.vbuffer[vid] = v[0]; //should be this.vBuffer
  this.vbuffer[vid+1] = v[1]; //should be this.vBuffer
  this.vbuffer[vid+2] = v[2]; //should be this.vBuffer
}
Sign up to request clarification or add additional context in comments.

1 Comment

This was code provided by course staff to help with our homework, so that's frustrating. I just assumed it was the correct name. Thank you very much for catching that.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.