/*
* Copyright (C) 2010, 2011, 2012 by Arne Kesting, Martin Treiber, Ralph Germ, Martin Budden
* <movsim.org@gmail.com>
* -----------------------------------------------------------------------------------------
*
* This file is part of
*
* MovSim - the multi-model open-source vehicular-traffic simulator.
*
* MovSim 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.
*
* MovSim 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 MovSim. If not, see <http://www.gnu.org/licenses/>
* or <http://www.movsim.org>.
*
* -----------------------------------------------------------------------------------------
*/
package org.movsim.roadmappings;
/**
* Maps a road segment onto a circle.
*/
public class RoadMappingCircle extends RoadMapping {
protected double centerX;
protected double centerY;
protected final double radius;
protected final boolean clockwise;
/**
*
* @param laneCount
* number of lanes
* @param x0
* start of circle, x coordinate
* @param y0
* start of circle, y coordinate
* @param radius
* radius of circle
*/
RoadMappingCircle(int laneCount, double x0, double y0, double radius) {
this(laneCount, x0, y0, radius, false);
}
protected RoadMappingCircle(int laneCount, double x0, double y0, double radius, boolean clockwise) {
super(laneCount, x0, y0);
this.radius = radius;
this.clockwise = clockwise;
roadLength = 2 * Math.PI * radius;
centerX = clockwise ? x0 + radius : x0 - radius;
centerY = y0;
}
/**
* Returns the x coordinate of the center of the circle.
*
* @return the x coordinate of the center of the circle
*/
public double centerX() {
return centerX;
}
/**
* Returns the y coordinate of the center of the circle.
*
* @return the y coordinate of the center of the circle
*/
public double centerY() {
return centerY;
}
/**
* Returns the radius of the circle.
*
* @return the radius of the circle
*/
public double radius() {
return radius;
}
/**
* Returns true if the circle mapping is in a clockwise direction.
*
* @return true if the circle mapping is in a clockwise direction
*/
public boolean clockwise() {
return clockwise;
}
@Override
public RoadMapping.PosTheta map(double roadPos, double lateralOffset) {
final double arcTheta = clockwise ? -roadPos / radius : roadPos / radius;
// road direction, perpendicular to angle position subtends at center
final double theta = arcTheta + 0.5 * Math.PI;
posTheta.cosTheta = Math.cos(theta);
posTheta.sinTheta = Math.sin(theta);
// lateralOffset is perpendicular to road
final double r = radius + lateralOffset * (clockwise ? -1 : 1);
posTheta.x = centerX + r * Math.cos(arcTheta) * (clockwise ? -1 : 1);
posTheta.y = centerY - r * Math.sin(arcTheta) * (clockwise ? -1 : 1);
return posTheta;
}
}