private void drawCurve(ICurve3D curve, int color, Vector3 position) {
    SimpleMaterial lineMaterial = new SimpleMaterial();
    lineMaterial.setUseSingleColor(true);

    Stack<Vector3> points = new Stack<Vector3>();
    for (int i = 0; i <= NUM_POINTS; i++) {
      Vector3 pos = curve.calculatePoint((float) i / (float) NUM_POINTS);
      points.add(pos);
    }

    Line3D line = new Line3D(points, 1, color);
    line.setMaterial(lineMaterial);
    line.setPosition(position);
    getCurrentScene().addChild(line);
  }
  public void initScene() {
    SimpleMaterial material = new SimpleMaterial();
    material.setUseSingleColor(true);

    // -- "curve1" will be the original curve. Note that we create two curves for
    //    demonstration purposes only. You'd typically create one curve and then
    //    reparametrize it.
    CatmullRomCurve3D curve1 = new CatmullRomCurve3D();
    CatmullRomCurve3D curve2 = new CatmullRomCurve3D();

    for (int i = 0; i < 16; i++) {
      // -- generate a random point within certain limits
      Vector3 pos = new Vector3(-1 + (Math.random() * 2), -1.2f + (Math.random() * 2.4f), 0);
      curve1.addPoint(pos);
      curve2.addPoint(pos);

      // -- add a wireframe cube so we can see what the original
      //    points were
      Cube s = new Cube(.06f);
      s.setMaterial(material);
      s.setColor(CURVE1_COLOR);
      s.setPosition(pos);
      s.setDrawingMode(GLES20.GL_LINES);
      addChild(s);
    }

    // -- draw the first curve
    drawCurve(curve1, CURVE1_COLOR, new Vector3());

    BaseObject3D pathFollowObject = new Sphere(.04f, 16, 16);
    pathFollowObject.setColor(CURVE1_COLOR);
    pathFollowObject.setMaterial(material);
    addChild(pathFollowObject);

    // -- animate a sphere that follow the first curve.
    //    This shows the non constant speed of a non parametrized curve.
    TranslateAnimation3D anim = new TranslateAnimation3D(curve1);
    anim.setDuration(ANIMATION_DURATION);
    anim.setTransformable3D(pathFollowObject);
    anim.setRepeatMode(RepeatMode.REVERSE_INFINITE);
    registerAnimation(anim);
    anim.play();

    // -- reparametrize the curve for uniform distribution
    curve2.reparametrizeForUniformDistribution(curve2.getPoints().size() * 4);
    List<Vector3> points = curve2.getPoints();

    // -- put spheres on the curve where the new points are
    for (int i = 0; i < points.size(); i++) {
      Vector3 pos = points.get(i);
      Sphere s = new Sphere(.02f, 4, 4);
      s.setMaterial(material);
      s.setColor(CURVE2_COLOR);
      s.setPosition(pos);
      addChild(s);
    }

    // -- draw the second, reparametrized, curve
    drawCurve(curve2, CURVE2_COLOR, new Vector3());

    pathFollowObject = new Sphere(.04f, 16, 16);
    pathFollowObject.setColor(CURVE2_COLOR);
    pathFollowObject.setMaterial(material);
    addChild(pathFollowObject);

    // -- animate a sphere on the second curve.
    //    This shows a more or less constant speed of a parametrized curve.
    anim = new TranslateAnimation3D(curve2);
    anim.setDuration(ANIMATION_DURATION);
    anim.setTransformable3D(pathFollowObject);
    anim.setRepeatMode(RepeatMode.REVERSE_INFINITE);
    registerAnimation(anim);
    anim.play();
  }