import static util.Static3D.*;
import static util.Generic3DUtil.*; 
import util.data.Pair;

// to avoid "Cannot create a generic array of type Pair<Double, double[][]>"
class Branch extends Pair<Double, double[][]> {
    public Branch(double d, double[][] mat) {
        super(d, mat);
    }
}

public class Tree3D {
        
    private static Branch[] branches = {
        new Branch(1,    scaleMatrix(rotateMatrix360(xAxis, PHYLLOTAXIS360), 0.95)),
        new Branch(0.5, scaleMatrix(rotateMatrix360(zAxis, 75), 0.5)),
        //              new Branch(0.55, scaleMatrix(rotateMatrix360(zAxis, 75), 0.48))
    };
        
    public static void drawTree(int d, double x, double y, double z, double[][] mat) {
        if (d<=0) return;
                
        double dx = mat[0][0];
        double dy = mat[1][0];
        double dz = mat[2][0];
        line(x, y, z, x + dx, y + dy, z + dz);
                
        for (Branch branch: branches) {
            double q = branch._1;
            drawTree(d-1, x + q * dx,  y + q * dy, z + q * dz, multipleMatrix(mat, branch._2));
        }
    }
        
    public static void main(String[] args) {
        double[][] initMatrix = scaleMatrix(copyMatrix(idMatrix), 20);
        //              printf("<!--%n");
        //              printMatrix(rotateMatrix(xAxis, PI/2));
        //              printf("-->%n");
        start();
            
        stroke(hsl360(120, 100, 50));
        strokeWeight(5);
        noFill();
        translate(0, -100, 0);
        rotateZ(PI/2);
        drawTree(10 /* 再帰の深さ */, 0, 0, 0, initMatrix);
            
        finish();
        return;
    }
}
