/*
* JFlow
* Created by Tim De Pauw <http://pwnt.be/>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package be.pwnt.jflow;
import java.awt.Dimension;
import be.pwnt.jflow.geometry.Point3D;
import be.pwnt.jflow.geometry.RotationMatrix;
public class Scene {
private Point3D cameraLocation;
private RotationMatrix cameraRotation;
private Point3D viewerLocation;
public Scene(Point3D cameraLocation, RotationMatrix cameraRotation,
Point3D viewerLocation) {
setCameraLocation(cameraLocation);
setCameraRotation(cameraRotation);
setViewerLocation(viewerLocation);
}
public Point3D getCameraLocation() {
return cameraLocation;
}
public void setCameraLocation(Point3D cameraLocation) {
this.cameraLocation = cameraLocation;
}
public RotationMatrix getCameraRotation() {
return cameraRotation;
}
public void setCameraRotation(RotationMatrix cameraRotationMatrix) {
this.cameraRotation = cameraRotationMatrix;
}
public Point3D getViewerLocation() {
return viewerLocation;
}
public void setViewerLocation(Point3D viewerLocation) {
this.viewerLocation = viewerLocation;
}
public Point3D project(Point3D a, Dimension surfaceSize) {
RotationMatrix rot = getCameraRotation();
Point3D e = getViewerLocation();
Point3D d = new Point3D(a.subtract(getCameraLocation()));
d.rotate(rot);
// maintain aspect ratio
double side = Math.max(surfaceSize.getWidth(), surfaceSize.getHeight());
//make scene can always show all shapes.
side = Math.min(Math.min(surfaceSize.getWidth(), surfaceSize.getHeight()) * 8 / 3, side);
double xo = (surfaceSize.getWidth() - side) / 2;
double yo = (surfaceSize.getHeight() - side) / 2;
return new Point3D(xo
+ scale((d.getX() - e.getX()) * e.getZ() / d.getZ(), side), yo
+ scale((d.getY() - e.getY()) * e.getZ() / d.getZ(), side));
}
private static double scale(double coord, double max) {
return (coord + 1) / 2 * max;
}
}