
package com.brackeen.javagamebook.math3D;

import java.awt.Rectangle;

/**
    Klasa ViewWindow reprezentująca okno widoku, na które
    rzutowane są obiekty trójwymiarowe.
*/
public class ViewWindow {

    private Rectangle bounds;
    private float angle;
    private float distanceToCamera;

    /**
        Tworzy nowe okno ViewWindow o określonych granicach na ekranie
        i ustalonym kącie widzenia w poziomie.
    */
    public ViewWindow(int left, int top, int width, int height,
        float angle)
    {
        bounds = new Rectangle();
        this.angle = angle;
        setBounds(left, top, width, height);
    }


    /**
        Definiuje granice tego okna ViewWindow na ekranie.
    */
    public void setBounds(int left, int top, int width,
        int height)
    {
        bounds.x = left;
        bounds.y = top;
        bounds.width = width;
        bounds.height = height;
        distanceToCamera = (bounds.width/2) /
            (float)Math.tan(angle/2);
    }


    /**
        Definiuje poziomy kąt widzenia dla tego okna ViewWindow.
    */
    public void setAngle(float angle) {
        this.angle = angle;
        distanceToCamera = (bounds.width/2) /
            (float)Math.tan(angle/2);
    }


    /**
        Pobiera kąt widzenia w poziomie dla tego okna obrazu.
    */
    public float getAngle() {
        return angle;
    }


    /**
        Pobiera szerokość tego okna obrazu.
    */
    public int getWidth() {
        return bounds.width;
    }


    /**
        Pobiera wysokość tego okna obrazu.
    */
    public int getHeight() {
        return bounds.height;
    }


    /**
        Pobiera przesunięcie y tego okna widoku względem ekranu.
    */
    public int getTopOffset() {
        return bounds.y;
    }


    /**
        Pobiera przesunięcie x tego okna widoku względem ekranu. 
    */
    public int getLeftOffset() {
        return bounds.x;
    }


    /**
        Pobiera odległość od kamery do tego okna obrazu.
    */
    public float getDistance() {
        return distanceToCamera;
    }



    /**
        Przekształca współrzędną x z tego okna obrazu
        na odpowiadającą jej współrzędną x na ekranie.
    */
    public float convertFromViewXToScreenX(float x) {
        return x + bounds.x + bounds.width/2;
    }


    /**
        Przekształca współrzędną y z tego okna obrazu
        na odpowiadającą jej współrzędną y na ekranie.
    */
    public float convertFromViewYToScreenY(float y) {
        return -y + bounds.y + bounds.height/2;
    }


    /**
        Przekształca współrzędną x z ekranu na odpowiadającą
        jej współrzędną x w oknie obrazu.
    */
    public float convertFromScreenXToViewX(float x) {
        return x - bounds.x - bounds.width/2;
    }


    /**
        Przekształca współrzędną y z ekranu na odpowiadającą
        jej współrzędną y w oknie obrazu.
    */
    public float convertFromScreenYToViewY(float y) {
        return -y + bounds.y + bounds.height/2;
    }


    /**
        Rzutuje podany wektor na ekran.
    */
    public void project(Vector3D v) {
        // project to view window
        v.x = distanceToCamera * v.x / -v.z;
        v.y = distanceToCamera * v.y / -v.z;

        // convert to screen coordinates
        v.x = convertFromViewXToScreenX(v.x);
        v.y = convertFromViewYToScreenY(v.y);
    }
}


