/**
* Copyright (C) BFH www.bfh.ch 2011
* Code written by: Patrick Dobler, Marc Folly
*
* 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 ch.bfh.ti.kybernetik.engine.controller.lightBulb;
import javax.vecmath.Point2d;
import javax.vecmath.Vector2d;
import ch.bfh.ti.kybernetik.engine.controller.Simulator;
import ch.bfh.ti.kybernetik.engine.model.LightBulb;
import ch.bfh.ti.kybernetik.engine.model.LightSensor;
/**
* The {@link Simulator} default {@link LightBulbController} implementation
*
*/
class DefaultLightBulbControllerImpl implements LightBulbController {
private final LightBulb lightBulb;
@Override
public LightBulb getLightBulb() {
return lightBulb;
}
public DefaultLightBulbControllerImpl(LightBulb lightBulb) {
this.lightBulb = lightBulb;
}
@Override
public double calculateIntensity(Point2d lightSensorPoint, LightSensor lightSensor, Vector2d lightSensorVector) {
Vector2d distanceVector = buildLightBulbToPointVector(lightSensorPoint);
double distance = distanceVector.length();
if (distance > lightBulb.getMaxRadius()) {
return 0;
}
double intensity = calculateGeneralDistanceLightIntensity(distance);
// Calculate Licht_Einfallswinkel (lightSensorToLightBulbAngle)
double lightSensorToLightBulbAngle = calculateLightSensorToLightBulbAngle(lightSensorVector, distanceVector);
// View Field Area of the Sensor
double lightSensorViewFieldAngle = lightSensor.getViewFieldSize() / 2;
if (lightSensorToLightBulbAngle > lightSensorViewFieldAngle) {
return 0;
}
// System.out.println("lightSensorToLightBulbAngle \t" +
// lightSensorToLightBulbAngle);
// System.out.println("lightSensorViewFieldAngle \t" +
// lightSensorViewFieldAngle);
// System.out.println("intensity normal \t" + intensity);
// Lineare Abnahmefunktion
// y = m * x + n
// y = - (intensity / lightSensorViewFieldAngle ) * Licht_Einfallswinkel
// + intensity;
double percentIntensity = -(intensity / lightSensorViewFieldAngle) * lightSensorToLightBulbAngle + intensity;
// System.out.println("intensity scaled \t" + percentIntensity);
// out of visible view field
if (percentIntensity < 0) {
return 0;
}
return percentIntensity;
}
public double calculateLightSensorToLightBulbAngle(Vector2d lightSensorVector, Vector2d distanceVector) {
double lightSensorToLightBulbAngle = Math.toDegrees(distanceVector.angle(lightSensorVector));
return lightSensorToLightBulbAngle;
}
private double calculateGeneralDistanceLightIntensity(double distance) {
// y = lightBulb.getMaxIntensity() * (lightBulb.getMaxRadius() -
// distance )^2) / lightBulb.getMaxRadius()^2
double term1 = ((lightBulb.getMaxRadius() - distance) * (lightBulb.getMaxRadius() - distance)) * lightBulb.getMaxIntensity();
double term2 = (lightBulb.getMaxRadius() * lightBulb.getMaxRadius());
double intensity = term1 / term2;
return intensity;
}
private Vector2d buildLightBulbToPointVector(Point2d lightSensorPoint) {
Vector2d distanceVector = new Vector2d(lightBulb.getX() - lightSensorPoint.getX(), lightBulb.getY() - lightSensorPoint.getY());
return distanceVector;
}
}