// Vektori3 tehtiin kopioimalla ensin Vektori2.java nimelle
// Vektori3.java ja sitten lisäämällä z-komponentin käsittely sekä
// ristitulo ja skalaarikolmitulo.
public class Vektori3 {
    private double x;
    private double y;
    private double z;

    public Vektori3(double x, double y, double z) {
	this.x = x;
	this.y = y;
	this.z = z;
    }

    public double xKomponentti() {
	return x;
    }

    public double yKomponentti() {
	return y;
    }

    public double zKomponentti() {
	return z;
    }

    public Vektori3 summa(Vektori3 v) {
	return new Vektori3(x + v.x, y + v.y, z + v.z);
    }

    public Vektori3 erotus(Vektori3 v) {
	return new Vektori3(x - v.x, y - v.y, z - v.z);
    }

    public Vektori3 tulo(double s) {
	return new Vektori3(s*x, s*y, s*z);
    }

    public double pisteTulo(Vektori3 v) {
	return x*v.x + y*v.y + z*v.z;
    }

    // Määritetään apumetodi, joka laskee 2x2 determinantin.
    private double det2(double a11, double a12, double a21, double a22) {
	return a11*a22-a12*a21;
    }

    // Määritetään apumetodi, joka laskee 3x3 determinantin.
    private double det3(double a11, double a12, double a13,
			double a21, double a22, double a23,
			double a31, double a32, double a33) {
	return (a11*det2(a22, a23, a32, a33) +
		a12*det2(a23, a21, a33, a31) +
		a13*det2(a21, a22, a31, a32));
    }

    public Vektori3 ristiTulo(Vektori3 v) {
	return new Vektori3(det2(y, z, v.y, v.z),
			    det2(z, x, v.z, v.x),
			    det2(x, y, v.x, v.y));
    }

    // Tämä voitaisiin tehdä myös ristitulon ja pistetulon avulla.
    public double kolmiTulo(Vektori3 v2, Vektori3 v3) {
	return det3(x, y, z, v2.x, v2.y, v2.z, v3.x, v3.y, v3.z);
    }

    public boolean equals(Object o) {
	if (o instanceof Vektori3) {
	    Vektori3 v = (Vektori3)o;
	    return x == v.x && y == v.y && z == v.z;
	} else {
	    return false;
	}
    }
    
    public String toString() {
	return "(" + x + ", " + y + ", " + z + ")";
    }


    public static void main(String[] args) {
	Vektori3 v1 = new Vektori3(1, 2, 4);
	System.out.println("v1 = " + v1);
	Vektori3 v2 = new Vektori3(2, -3, 5);
	System.out.println("v2 = " + v2);
	System.out.println("v1 . v2 = " + v1 + " . " + v2 + " = "
			   + v1.pisteTulo(v2));
	Vektori3 v3 = new Vektori3(0, 3, 9);
	System.out.println("v3 = " + v3);
	Vektori3 v4 = v1.summa(v2);
	System.out.println("v4 = v1 + v2 = " + v1 + " + " + v2 + " = " + v4);
	Vektori3 v5 = v4.erotus(v3);
	System.out.println("v5 = v4 - v3 = " + v4 + " - " + v3 + " = " + v5);
	Vektori3 v6 = v5.tulo(0.5);
	System.out.println("v6 = 0.5 * v5 = 0.5 * " + v5 + " = " + v6);
	Vektori3 v7 = new Vektori3(2, 0, -1);
	System.out.println("v7 = " + v7);
	Vektori3 v8 = new Vektori3(4, 3, -1);
	System.out.println("v8 = " + v8);
	Vektori3 v9 = v7.ristiTulo(v8);
	System.out.println("v9 = v7 * v8 = " + v7 + " * " + v8 + " = " + v9);
	Vektori3 v10 = new Vektori3(2, -1, 1);
	Vektori3 v11 = new Vektori3(1, 2, -3);
	Vektori3 v12 = new Vektori3(3, -4, 5);
	System.out.println("v10 . v11 * v12 = " + v10 + " . " + v11 + " * " + v12
			   + " = " + v10.kolmiTulo(v11, v12));
	Vektori3 v13 = new Vektori3(1.5, -2.0, 0.0);
	System.out.println("v6.equals(v13) = " + v6 + ".equals(" + v13 + ") = "
			   + v6.equals(v13));
	
    }

}
