#include <utils/geom/GeomHelper.h>
#include <utils/gui/div/GLHelper.h>
#include <utils/gui/globjects/GLIncludes.h>
#include <utils/gui/globjects/GUIGlObjectTypes.h>
#include "GUIDottedGeometry.h"
#include "GUIGeometry.h"
#define MAXIMUM_DOTTEDGEOMETRYLENGTH 500.0
GUIDottedGeometry::DottedGeometryColor::DottedGeometryColor() :
myColorFlag(true) {}
const RGBColor
GUIDottedGeometry::DottedGeometryColor::getColor(const GUIVisualizationSettings& settings, DottedContourType type) {
switch (type) {
case DottedContourType::INSPECT:
if (myColorFlag) {
myColorFlag = false;
return settings.dottedContourSettings.firstInspectedColor;
} else {
myColorFlag = true;
return settings.dottedContourSettings.secondInspectedColor;
}
case DottedContourType::FRONT:
if (myColorFlag) {
myColorFlag = false;
return settings.dottedContourSettings.firstFrontColor;
} else {
myColorFlag = true;
return settings.dottedContourSettings.secondFrontColor;
}
case DottedContourType::FROM:
if (myColorFlag) {
myColorFlag = false;
return RGBColor::GREEN;
} else {
myColorFlag = true;
return RGBColor::GREEN.changedBrightness(-30);
}
case DottedContourType::TO:
if (myColorFlag) {
myColorFlag = false;
return RGBColor::MAGENTA;
} else {
myColorFlag = true;
return RGBColor::MAGENTA.changedBrightness(-30);
}
case DottedContourType::REMOVE:
if (myColorFlag) {
myColorFlag = false;
return RGBColor(229, 233, 255);
} else {
myColorFlag = true;
return RGBColor(255, 109, 196);
}
case DottedContourType::SELECT:
if (myColorFlag) {
myColorFlag = false;
return RGBColor::BLUE;
} else {
myColorFlag = true;
return RGBColor::BLUE.changedBrightness(-30);
}
case DottedContourType::MOVE:
if (myColorFlag) {
myColorFlag = false;
return RGBColor(220, 0, 0);
} else {
myColorFlag = true;
return RGBColor(220, 0, 0).changedBrightness(-30);
}
case DottedContourType::OVER:
if (myColorFlag) {
myColorFlag = false;
return RGBColor::ORANGE;
} else {
myColorFlag = true;
return RGBColor::ORANGE.changedBrightness(-30);
}
case DottedContourType::RELATED:
if (myColorFlag) {
myColorFlag = false;
return RGBColor::CYAN;
} else {
myColorFlag = true;
return RGBColor::CYAN.changedBrightness(-30);
}
case DottedContourType::WALKINGAREA:
return settings.junctionColorer.getScheme().getColor(6);
default:
return RGBColor::BLACK;
}
}
void
GUIDottedGeometry::DottedGeometryColor::changeColor() {
if (myColorFlag) {
myColorFlag = false;
} else {
myColorFlag = true;
}
}
void
GUIDottedGeometry::DottedGeometryColor::reset() {
myColorFlag = true;
}
GUIDottedGeometry::Segment::Segment() {}
GUIDottedGeometry::Segment::Segment(PositionVector newShape) :
shape(newShape) {
}
GUIDottedGeometry::GUIDottedGeometry() {}
GUIDottedGeometry::GUIDottedGeometry(const GUIVisualizationSettings& s, const GUIVisualizationSettings::Detail d,
PositionVector shape, const bool closeShape) {
myUnresampledShape = shape;
if (closeShape && (myUnresampledShape.size() > 2)) {
myUnresampledShape.closePolygon();
}
if (myUnresampledShape.size() > 1) {
for (int i = 1; i < (int)myUnresampledShape.size(); i++) {
myDottedGeometrySegments.push_back(Segment({myUnresampledShape[i - 1], myUnresampledShape[i]}));
}
if (d <= GUIVisualizationSettings::Detail::DottedContoursResampled) {
double segmentLength = s.dottedContourSettings.segmentLength;
if (myUnresampledShape.length2D() > MAXIMUM_DOTTEDGEOMETRYLENGTH) {
segmentLength = myUnresampledShape.length2D() / (MAXIMUM_DOTTEDGEOMETRYLENGTH * 0.5);
}
for (auto& segment : myDottedGeometrySegments) {
segment.shape = segment.shape.resample(segmentLength, true);
}
}
calculateShapeRotationsAndLengths();
}
}
void
GUIDottedGeometry::updateDottedGeometry(const GUIVisualizationSettings& s, const GUIVisualizationSettings::Detail d,
const PositionVector& laneShape) {
myUnresampledShape = laneShape;
myDottedGeometrySegments.clear();
for (int i = 1; i < (int)myUnresampledShape.size(); i++) {
myDottedGeometrySegments.push_back(Segment({myUnresampledShape[i - 1], myUnresampledShape[i]}));
}
if (d <= GUIVisualizationSettings::Detail::DottedContoursResampled) {
for (auto& segment : myDottedGeometrySegments) {
segment.shape = segment.shape.resample(s.dottedContourSettings.segmentLength, true);
}
}
calculateShapeRotationsAndLengths();
}
void
GUIDottedGeometry::updateDottedGeometry(const GUIVisualizationSettings& s, const GUIVisualizationSettings::Detail d,
PositionVector shape, const bool closeShape) {
myUnresampledShape = shape;
myDottedGeometrySegments.clear();
if (closeShape && (myUnresampledShape.size() > 2)) {
myUnresampledShape.closePolygon();
}
if (myUnresampledShape.size() > 1) {
for (int i = 1; i < (int)myUnresampledShape.size(); i++) {
myDottedGeometrySegments.push_back(Segment({myUnresampledShape[i - 1], myUnresampledShape[i]}));
}
if (d <= GUIVisualizationSettings::Detail::DottedContoursResampled) {
for (auto& segment : myDottedGeometrySegments) {
segment.shape = segment.shape.resample(s.dottedContourSettings.segmentLength, true);
}
}
calculateShapeRotationsAndLengths();
}
}
void
GUIDottedGeometry::drawDottedGeometry(const GUIVisualizationSettings& s, GUIDottedGeometry::DottedContourType type,
DottedGeometryColor& dottedGeometryColor, const double lineWidth, const bool addOffset) const {
for (auto& segment : myDottedGeometrySegments) {
for (int i = 0; i < ((int)segment.shape.size() - 1); i++) {
GLHelper::setColor(dottedGeometryColor.getColor(s, type));
if (addOffset) {
GLHelper::drawBoxLine(segment.shape[i], segment.rotations.at(i), segment.lengths.at(i), lineWidth, -lineWidth);
} else {
GLHelper::drawBoxLine(segment.shape[i], segment.rotations.at(i), segment.lengths.at(i), lineWidth);
}
}
}
}
void
GUIDottedGeometry::drawInnenGeometry(const double lineWidth) const {
for (auto& segment : myDottedGeometrySegments) {
for (int i = 0; i < ((int)segment.shape.size() - 1); i++) {
GLHelper::drawBoxLine(segment.shape[i], segment.rotations.at(i), segment.lengths.at(i), lineWidth, lineWidth);
}
}
}
void
GUIDottedGeometry::moveShapeToSide(const double value) {
for (auto& segment : myDottedGeometrySegments) {
segment.shape.move2side(value);
}
myUnresampledShape.move2side(value);
}
Position
GUIDottedGeometry::getFrontPosition() const {
if (myUnresampledShape.size() > 0) {
return myUnresampledShape.front();
} else {
return Position::INVALID;
}
}
Position
GUIDottedGeometry::getBackPosition() const {
if (myUnresampledShape.size() > 0) {
return myUnresampledShape.back();
} else {
return Position::INVALID;
}
}
const PositionVector&
GUIDottedGeometry::getUnresampledShape() const {
return myUnresampledShape;
}
void
GUIDottedGeometry::clearDottedGeometry() {
myDottedGeometrySegments.clear();
myUnresampledShape.clear();
}
void
GUIDottedGeometry::calculateShapeRotationsAndLengths() {
for (auto& segment : myDottedGeometrySegments) {
int numberOfSegments = (int)segment.shape.size() - 1;
if (numberOfSegments >= 0) {
segment.rotations.reserve(numberOfSegments);
segment.lengths.reserve(numberOfSegments);
for (int i = 0; i < numberOfSegments; i++) {
segment.rotations.push_back(GUIGeometry::calculateRotation(segment.shape[i], segment.shape[i + 1]));
segment.lengths.push_back(GUIGeometry::calculateLength(segment.shape[i], segment.shape[i + 1]));
}
}
}
}