diff --git a/JPSvis.pro b/JPSvis.pro index 54961cf7eb514c3c493ce6a9b6a8210a67a13e2e..80d4ea75025a7256390651f6eb07810c0dd379bf 100644 --- a/JPSvis.pro +++ b/JPSvis.pro @@ -1,7 +1,8 @@ TEMPLATE = app -TARGET = TraVisTo +TARGET = JPSvis CONFIG += qt CONFIG += static +CONFIG += c++11 QT += xml network #avoid some annoying dependencies @@ -11,7 +12,8 @@ QT += xml network #QMAKE_CXXFLAGS += -static #QMAKE_LFLAGS_RELEASE += -static-libgcc -QMAKE_CXXFLAGS += -Wno-deprecated -Wno-unused-parameter -Wno-unused-variable +QMAKE_CXXFLAGS += -std=c++11 +QMAKE_CXXFLAGS += -Wno-deprecated -Wno-unused-parameter -Wno-unused-variable -Wno-sign-compare greaterThan(QT_MAJOR_VERSION, 4):QT += widgets @@ -365,93 +367,73 @@ unix_6 { } #dynamic linking with vtk5.10 -unix_dyn { +unix{ INCLUDEPATH += /usr/include/vtk-5.8 LIBS += -L/usr/lib \ --lvtkRendering \ --lvtkCommon \ --lvtkHybrid \ --lvtkIO \ --lvtkGraphics \ --lvtkFiltering \ - + -lvtkRendering \ + -lvtkCommon \ + -lvtkHybrid \ + -lvtkIO \ + -lvtkGraphics \ + -lvtkFiltering \ + -lvtkCommon \ + -lvtkverdict \ + -lvtkParallel \ + -lvtkexoIIc \ + -lvtkImaging \ + -lvtkDICOMParser \ + -lvtkmetaio \ + -lvtkftgl \ + -lvtkViews \ + -lvtksys \ + #-lvtkpng \ + #-lvtktiff \ + #-lvtkjpeg \ + #-lvtklibxml2 \ + #-lvtkzlib \ + #-lvtkexpat \ + #-lvtkfreetype \ } #Static compilation linux -unix:!macx { +unix_static { #INCLUDEPATH += /usr/include/vtk-5.8 #LIBS += -L/usr/lib \ -INCLUDEPATH +=/usr/local/include/vtk-5.10 -LIBS += -L/usr/local/lib/vtk-5.10 \ --lvtkRendering \ --lvtkCommon \ --lvtkHybrid \ --lvtkIO \ --lvtkGraphics \ --lvtkFiltering \ --lvtkCommon \ --lvtkverdict \ --lvtkParallel \ --lvtkexoIIc \ --lvtkImaging \ --lvtkDICOMParser \ --lvtkmetaio \ --lvtkftgl \ --lLSDyna \ --lvtkViews \ --lvtksys \ --lvtkpng \ --lvtktiff \ --lvtkjpeg \ --lvtklibxml2 \ --lvtkzlib \ --lvtkexpat \ --lvtkfreetype \ --lGL \ --lXt \ --lX11 \ --lXext \ --ldl \ + INCLUDEPATH +=/usr/local/include/vtk-5.10 + LIBS += -L/usr/local/lib/vtk-5.10 \ + -lvtkRendering \ + -lvtkCommon \ + -lvtkHybrid \ + -lvtkIO \ + -lvtkGraphics \ + -lvtkFiltering \ + -lvtkCommon \ + -lvtkverdict \ + -lvtkParallel \ + -lvtkexoIIc \ + -lvtkImaging \ + -lvtkDICOMParser \ + -lvtkmetaio \ + -lvtkftgl \ + -lLSDyna \ + -lvtkViews \ + -lvtksys \ + -lvtkpng \ + -lvtktiff \ + -lvtkjpeg \ + -lvtklibxml2 \ + -lvtkzlib \ + -lvtkexpat \ + -lvtkfreetype \ + -lGL \ + -lXt \ + -lX11 \ + -lXext \ + -ldl \ } -macx { - INCLUDEPATH += /Users/piccolo/VTK6/include/vtk-6.1 - LIBS += -L/Users/piccolo/VTK6/lib \ - /Users/piccolo/VTK6/lib/libvtkFiltersGeometry-6.1.a /Users/piccolo/VTK6/lib/libvtkFiltersCore-6.1.a \ - /Users/piccolo/VTK6/lib/libvtkCommonExecutionModel-6.1.a /Users/piccolo/VTK6/lib/libvtkCommonDataModel-6.1.a \ - /Users/piccolo/VTK6/lib/libvtkCommonMath-6.1.a /Users/piccolo/VTK6/lib/libvtkCommonCore-6.1.a \ - /Users/piccolo/VTK6/lib/libvtksys-6.1.a /Users/piccolo/VTK6/lib/libvtkCommonMisc-6.1.a \ - /Users/piccolo/VTK6/lib/libvtkCommonSystem-6.1.a /Users/piccolo/VTK6/lib/libvtkCommonTransforms-6.1.a \ - /Users/piccolo/VTK6/lib/libvtkFiltersModeling-6.1.a /Users/piccolo/VTK6/lib/libvtkFiltersGeneral-6.1.a \ - /Users/piccolo/VTK6/lib/libvtkCommonComputationalGeometry-6.1.a /Users/piccolo/VTK6/lib/libvtkFiltersSources-6.1.a \ - /Users/piccolo/VTK6/lib/libvtkIOImage-6.1.a /Users/piccolo/VTK6/lib/libvtkDICOMParser-6.1.a \ - /Users/piccolo/VTK6/lib/libvtkIOCore-6.1.a /Users/piccolo/VTK6/lib/libvtkzlib-6.1.a \ - /Users/piccolo/VTK6/lib/libvtkmetaio-6.1.a /Users/piccolo/VTK6/lib/libvtkjpeg-6.1.a \ - /Users/piccolo/VTK6/lib/libvtkpng-6.1.a /Users/piccolo/VTK6/lib/libvtktiff-6.1.a \ - /Users/piccolo/VTK6/lib/libvtkIOXML-6.1.a /Users/piccolo/VTK6/lib/libvtkIOGeometry-6.1.a /Users/piccolo/VTK6/lib/libvtkjsoncpp-6.1.a \ - /Users/piccolo/VTK6/lib/libvtkIOXMLParser-6.1.a /Users/piccolo/VTK6/lib/libvtkexpat-6.1.a /Users/piccolo/VTK6/lib/libvtkImagingStatistics-6.1.a \ - /Users/piccolo/VTK6/lib/libvtkImagingCore-6.1.a /Users/piccolo/VTK6/lib/libvtkInteractionStyle-6.1.a /Users/piccolo/VTK6/lib/libvtkFiltersExtraction-6.1.a \ - /Users/piccolo/VTK6/lib/libvtkFiltersStatistics-6.1.a /Users/piccolo/VTK6/lib/libvtkImagingFourier-6.1.a /Users/piccolo/VTK6/lib/libvtkalglib-6.1.a \ - /Users/piccolo/VTK6/lib/libvtkRenderingCore-6.1.a /Users/piccolo/VTK6/lib/libvtkRenderingVolumeOpenGL-6.1.a /Users/piccolo/VTK6/lib/libvtkRenderingOpenGL-6.1.a \ - /Users/piccolo/VTK6/lib/libvtkImagingHybrid-6.1.a /Users/piccolo/VTK6/lib/libvtkRenderingVolume-6.1.a /Users/piccolo/VTK6/lib/libvtkTestingRendering-6.1.a \ - -framework AGL -framework OpenGL -framework ApplicationServices -framework IOKit -framework Cocoa /Users/piccolo/VTK6/lib/libvtkIOImage-6.1.a \ - /Users/piccolo/VTK6/lib/libvtkDICOMParser-6.1.a /Users/piccolo/VTK6/lib/libvtkIOCore-6.1.a /Users/piccolo/VTK6/lib/libvtkmetaio-6.1.a /Users/piccolo/VTK6/lib/libvtkpng-6.1.a \ - /Users/piccolo/VTK6/lib/libvtktiff-6.1.a /Users/piccolo/VTK6/lib/libvtkzlib-6.1.a /Users/piccolo/VTK6/lib/libvtkjpeg-6.1.a -lm /Users/piccolo/VTK6/lib/libvtkRenderingCore-6.1.a \ - /Users/piccolo/VTK6/lib/libvtkFiltersGeometry-6.1.a /Users/piccolo/VTK6/lib/libvtkFiltersSources-6.1.a /Users/piccolo/VTK6/lib/libvtkFiltersExtraction-6.1.a \ - /Users/piccolo/VTK6/lib/libvtkFiltersGeneral-6.1.a /Users/piccolo/VTK6/lib/libvtkFiltersCore-6.1.a /Users/piccolo/VTK6/lib/libvtkCommonComputationalGeometry-6.1.a \ - /Users/piccolo/VTK6/lib/libvtkFiltersStatistics-6.1.a /Users/piccolo/VTK6/lib/libvtkImagingFourier-6.1.a /Users/piccolo/VTK6/lib/libvtkImagingCore-6.1.a \ - /Users/piccolo/VTK6/lib/libvtkCommonExecutionModel-6.1.a /Users/piccolo/VTK6/lib/libvtkCommonDataModel-6.1.a /Users/piccolo/VTK6/lib/libvtkCommonMisc-6.1.a \ - /Users/piccolo/VTK6/lib/libvtkCommonSystem-6.1.a /Users/piccolo/VTK6/lib/libvtkCommonTransforms-6.1.a /Users/piccolo/VTK6/lib/libvtkCommonMath-6.1.a \ - /Users/piccolo/VTK6/lib/libvtkCommonCore-6.1.a /Users/piccolo/VTK6/lib/libvtksys-6.1.a /Users/piccolo/VTK6/lib/libvtkalglib-6.1.a \ - /Users/piccolo/VTK6/lib/libvtkRenderingAnnotation-6.1.a /Users/piccolo/VTK6/lib/libvtkRenderingLabel-6.1.a \ - /Users/piccolo/VTK6/lib/libvtkRenderingFreeType-6.1.a /Users/piccolo/VTK6/lib/libvtkfreetype-6.1.a /Users/piccolo/VTK6/lib/libvtkftgl-6.1.a \ - /Users/piccolo/VTK6/lib/libvtkRenderingCore-6.1.a /Users/piccolo/VTK6/lib/libvtkRenderingFreeTypeOpenGL-6.1.a \ - -} - -macx_dyn { +macx{ INCLUDEPATH += /Users/piccolo/VTK/include/vtk-6.1 - LIBS += -L/Users/piccolo/VTK/lib \ -lvtkalglib-6.1 \ -lvtkChartsCore-6.1 \ diff --git a/src/Frame.cpp b/src/Frame.cpp index d98756b4834799baef205e61fba7bf838ce4355c..8003b00b045aff86eae06b652ed08a05a171e011 100644 --- a/src/Frame.cpp +++ b/src/Frame.cpp @@ -63,8 +63,8 @@ Frame::~Frame() } _framePoints.clear(); - //_polydata2D->Delete(); - //_polydata3D->Delete(); + _polydata2D->Delete(); + _polydata3D->Delete(); } int Frame::getSize() diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp index 9bcfcebdee48dfab7f02a078498a5a40d1fe8ea1..e9eb9eae4e1d8e0fe4c53d9d4608681cc0d44332 100644 --- a/src/MainWindow.cpp +++ b/src/MainWindow.cpp @@ -540,11 +540,11 @@ bool MainWindow::parsePedestrianShapes(QDomNode shapeNode, int groupID) if(!ok)color=std::numeric_limits<int>::quiet_NaN(); Debug::Messages("id= %d height= %lf color =%d",id,height,color); - if(!isnan(height)) { + if(!std::isnan(height)) { heights.append(QString::number(id)); heights.append(QString::number(height)); } - if(!isnan(color)) { + if(!std::isnan(color)) { colors.append(QString::number(id)); colors.append(QString::number(color)); } diff --git a/src/SaxParser.cpp b/src/SaxParser.cpp index c4c6dbe5c5d8df3f2df2d56af06f356285f06e8d..2fdc72ac7aad5abbfbe315ce88a978332f9bb5a5 100644 --- a/src/SaxParser.cpp +++ b/src/SaxParser.cpp @@ -38,6 +38,8 @@ #include "geometry/FacilityGeometry.h" #include "geometry/Building.h" #include "geometry/Wall.h" +#include "geometry/SubRoom.h" + #include "SystemSettings.h" #include <QMessageBox> @@ -66,6 +68,9 @@ using namespace std; +OutputHandler* Log=NULL; + + /** * constructor * @@ -399,9 +404,9 @@ bool SaxParser::startElement(const QString & /* namespaceURI */, } //coordinates of the ellipse, default to the head of the agent - if(isnan(el_x)) el_x=xPos; - if(isnan(el_y)) el_y=yPos; - if(isnan(el_z)) el_z=zPos; + if(std::isnan(el_x)) el_x=xPos; + if(std::isnan(el_y)) el_y=yPos; + if(std::isnan(el_z)) el_z=zPos; //double pos[3]={xPos,yPos,zPos}; //double vel[3]={xVel,yPos,zPos}; @@ -435,13 +440,13 @@ bool SaxParser::startElement(const QString & /* namespaceURI */, color=at.value(i).toDouble(); } } - if(isnan(id)) return true; + if(std::isnan(id)) return true; - if(!isnan(height)) { + if(!std::isnan(height)) { initialPedestriansHeights.append(QString::number(id)); initialPedestriansHeights.append(QString::number(height)); } - if(!isnan(color)) { + if(!std::isnan(color)) { initialPedestriansColors.append(QString::number(id)); initialPedestriansColors.append(QString::number(color)); } @@ -554,6 +559,9 @@ void SaxParser::clearPoints() bool SaxParser::parseGeometryJPS(QString fileName, FacilityGeometry *geometry) { + // if(Log) delete Log; + Log = new FileHandler(SystemSettings::getLogfile().toStdString().c_str()); + double captionsColor=0;//red if(!fileName.endsWith(".xml",Qt::CaseInsensitive)) return false; QString wd; @@ -564,7 +572,7 @@ bool SaxParser::parseGeometryJPS(QString fileName, FacilityGeometry *geometry) string geometrypath = fileName.toStdString(); // read the geometry - if(!building->LoadBuildingFromFile(geometrypath)) + if(!building->LoadGeometry(geometrypath)) return false; if(!building->InitGeometry()) return false; // create the polygons diff --git a/src/ThreadDataTransfert.cpp b/src/ThreadDataTransfert.cpp index df27480a0d1c5f9668f3f9d8a9bd33cb52585341..36fabf0aeb9cd61000f691672376451554c51a90 100644 --- a/src/ThreadDataTransfert.cpp +++ b/src/ThreadDataTransfert.cpp @@ -406,11 +406,11 @@ void ThreadDataTransfer::parseShapeNode(QDomNode shape) if(!ok)color=std::numeric_limits<int>::quiet_NaN(); //cout <<"id= " <<id <<" height= "<<height<<" color= "<<color<<endl; - if(!isnan(height)) { + if(!std::isnan(height)) { heights.append(QString::number(id)); heights.append(QString::number(height)); } - if(!isnan(color)) { + if(!std::isnan(color)) { colors.append(QString::number(id)); colors.append(QString::number(color)); } diff --git a/src/ThreadVisualisation.cpp b/src/ThreadVisualisation.cpp index 78cb73d9f9ff2df6e95909f4c5b1f6c3c8382589..2688d607744e4dda42c922f3eb337f4da87f98ca 100644 --- a/src/ThreadVisualisation.cpp +++ b/src/ThreadVisualisation.cpp @@ -103,7 +103,7 @@ ThreadVisualisation::ThreadVisualisation(QObject *parent): renderer=NULL; renderWindow=NULL; renderWinInteractor=NULL; - runningTime=NULL; + runningTime=vtkTextActor::New();; framePerSecond=25; axis=NULL; winTitle="header without room caption"; @@ -123,6 +123,9 @@ ThreadVisualisation::~ThreadVisualisation() if(extern_glyphs_pedestrians) extern_glyphs_pedestrians->Delete(); if(extern_glyphs_pedestrians_actor_2D) extern_glyphs_pedestrians_actor_2D->Delete(); if(extern_pedestrians_labels) extern_pedestrians_labels->Delete(); + + runningTime->Delete(); + } void ThreadVisualisation::setFullsreen(bool status) @@ -140,7 +143,7 @@ void ThreadVisualisation::run() { //deactivate the output windows - //vtkObject::GlobalWarningDisplayOff(); + vtkObject::GlobalWarningDisplayOff(); //emit signalStatusMessage("running"); @@ -189,6 +192,7 @@ void ThreadVisualisation::run() actor->SetMapper(mapper); mapper->Delete(); actor->GetProperty()->SetColor(.90,.90,0.0); + actor->Delete(); //renderer->AddActor(actor); } //add another big circle at null point @@ -207,6 +211,7 @@ void ThreadVisualisation::run() mapper->Delete(); actor->GetProperty()->SetColor(.90,.90,0.0); actor->SetPosition(5000,8000,0); + actor->Delete(); //renderer->AddActor(actor); } @@ -239,7 +244,6 @@ void ThreadVisualisation::run() // initLegend(); //add the running time frame - runningTime = vtkTextActor::New(); runningTime->SetTextScaleModeToViewport(); //runningTime->SetTextScaleModeToProp(); //runningTime->SetMinimumSize(10,10); @@ -367,6 +371,9 @@ void ThreadVisualisation::run() renderWinInteractor->Delete(); _topViewCamera->Delete(); renderer=NULL; + + delete renderingTimer; + } @@ -467,11 +474,13 @@ void ThreadVisualisation::initGlyphs2D() // } //speed the rendering using triangles stripers - vtkTriangleFilter *tris = vtkTriangleFilter::New(); + //vtkTriangleFilter *tris = vtkTriangleFilter::New(); + VTK_CREATE(vtkTriangleFilter, tris); tris->SetInputConnection(agentShape->GetOutputPort()); //tris->GetOutput()->ReleaseData(); - vtkStripper *strip = vtkStripper::New(); + //vtkStripper *strip = vtkStripper::New(); + VTK_CREATE(vtkStripper, strip); strip->SetInputConnection(tris->GetOutputPort()); //strip->GetOutput()->ReleaseData(); @@ -736,6 +745,8 @@ void ThreadVisualisation::setGeometry(FacilityGeometry* geometry) FacilityGeometry* ThreadVisualisation::getGeometry() { //if(geometry==NULL){ + //delete the old object + delete geometry; geometry=new FacilityGeometry(); //} return geometry; @@ -792,7 +803,7 @@ void ThreadVisualisation::setGeometryVisibility3D(bool status) void ThreadVisualisation::setOnscreenInformationVisibility(bool show) { - if(runningTime) + //if(runningTime) runningTime->SetVisibility(show); } diff --git a/src/geometry/Building.cpp b/src/geometry/Building.cpp index 9308e6e868ef775698da92e4397e74425b512d24..f4e7d06ea05bf4c38f685dc136f8e250206f0dfb 100644 --- a/src/geometry/Building.cpp +++ b/src/geometry/Building.cpp @@ -1,13 +1,14 @@ /** - * File: Building.cpp + * \file Building.cpp + * \date Oct 1, 2014 + * \version v0.5 + * \copyright <2009-2014> Forschungszentrum Jülich GmbH. All rights reserved. * - * Created on 1. October 2010, 09:25 - * - * @section LICENSE + * \section License * This file is part of JuPedSim. * * JuPedSim is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by + * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * @@ -16,26 +17,25 @@ * 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 + * You should have received a copy of the GNU Lesser General Public License * along with JuPedSim. If not, see <http://www.gnu.org/licenses/>. * - * @section DESCRIPTION - * + * \section Description * * - */ + **/ + #include "Building.h" +#include "../geometry/SubRoom.h" +#include "../geometry/Room.h" #include "../tinyxml/tinyxml.h" -//qt stuff -#include <QString> -#include "../SystemSettings.h" - #ifdef _SIMULATOR #include "../pedestrian/Pedestrian.h" #include "../mpi/LCGrid.h" #include "../routing/RoutingEngine.h" +#include "../routing/SafestPathRouter.h" #endif //#undef _OPENMP @@ -43,28 +43,26 @@ #ifdef _OPENMP #include <omp.h> #else -#define omp_get_thread_num() 0 -#define omp_get_max_threads() 1 +#define omp_get_thread_num() 0 +#define omp_get_max_threads() 1 #endif -//OutputHandler* Log = new STDIOHandler(); -OutputHandler* Log = NULL; - using namespace std; /************************************************************ Konstruktoren ************************************************************/ + Building::Building() { - _caption = "no_caption"; - _projectFilename = ""; - _rooms = vector<Room*>(); - _routingEngine = NULL; - _linkedCellGrid = NULL; - _savePathway = false; - Log = new FileHandler(SystemSettings::getLogfile().toStdString().c_str()); + _caption = "no_caption"; + _projectFilename = ""; + _geometryFilename= ""; + _rooms = vector<Room*>(); + _routingEngine = NULL; + _linkedCellGrid = NULL; + _savePathway = false; } @@ -74,7 +72,11 @@ Building::~Building() delete _rooms[i]; #ifdef _SIMULATOR - delete _routingEngine; + for(unsigned int p=0;p<_allPedestians.size();p++) + { + //delete _allPedestians[p]; + } + _allPedestians.clear(); delete _linkedCellGrid; #endif @@ -105,1445 +107,1265 @@ Building::~Building() ************************************************************/ void Building::SetCaption(const std::string& s) { - _caption = s; + _caption = s; } void Building::SetRoutingEngine(RoutingEngine* r) { - _routingEngine = r; + _routingEngine = r; } void Building::SetRoom(Room* room, int index) { - if ((index >= 0) && (index < (int) _rooms.size())) { - _rooms[index] = room; - } else { - Log->Write("ERROR: \tWrong Index in CBuilding::SetRoom()"); - exit(0); - } + if ((index >= 0) && (index < (int) _rooms.size())) { + _rooms[index] = room; + } else { + Log->Write("ERROR: \tWrong Index in CBuilding::SetRoom()"); + exit(EXIT_FAILURE); + } } + /************************************************************* Getter-Funktionen ************************************************************/ string Building::GetCaption() const { - return _caption; + return _caption; } RoutingEngine* Building::GetRoutingEngine() const { - return _routingEngine; + return _routingEngine; } int Building::GetNumberOfRooms() const { - return _rooms.size(); + return _rooms.size(); } int Building::GetNumberOfGoals() const { - return _transitions.size() + _hLines.size() + _crossings.size(); + return _transitions.size() + _hLines.size() + _crossings.size(); } const vector<Room*>& Building::GetAllRooms() const { - return _rooms; + return _rooms; } Room* Building::GetRoom(int index) const { - if ((index >= 0) && (index < (int) _rooms.size())) { - return _rooms[index]; - } else { - char tmp[CLENGTH]; - sprintf(tmp, - "ERROR: Wrong 'index' in CBuiling::GetRoom() index: %d size: %d", - index, _rooms.size()); - Log->Write(tmp); - exit(0); - } + if ((index >= 0) && (index < (int) _rooms.size())) { + return _rooms[index]; + } else { + Log->Write("ERROR: Wrong 'index' in CBuiling::GetRoom() Room ID: %d size: %d",index, _rooms.size()); + Log->Write("\tControl your rooms ID and make sure they are in the order 0, 1, 2,.. "); + exit(EXIT_FAILURE); + } } LCGrid* Building::GetGrid() const { - return _linkedCellGrid; + return _linkedCellGrid; } void Building::AddRoom(Room* room) { - _rooms.push_back(room); + _rooms.push_back(room); } void Building::AddSurroundingRoom() { - Log->Write("INFO: \tAdding the room 'outside' "); - // first look for the geometry boundaries - double x_min = FLT_MAX; - double x_max = -FLT_MAX; - double y_min = FLT_MAX; - double y_max = -FLT_MAX; - //finding the bounding of the grid - // and collect the pedestrians - for (unsigned int r = 0; r < _rooms.size(); r++) { - Room* room = _rooms[r]; - for (int j = 0; j < room->GetNumberOfSubRooms(); j++) { - SubRoom* sub = room->GetSubRoom(j); - const vector<Wall>& allWalls = sub->GetAllWalls(); - - for (unsigned int a = 0; a < allWalls.size(); a++) { - double x1 = allWalls[a].GetPoint1().GetX(); - double y1 = allWalls[a].GetPoint1().GetY(); - double x2 = allWalls[a].GetPoint2().GetX(); - double y2 = allWalls[a].GetPoint2().GetY(); - - double xmax = (x1 > x2) ? x1 : x2; - double xmin = (x1 > x2) ? x2 : x1; - double ymax = (y1 > y2) ? y1 : y2; - double ymin = (y1 > y2) ? y2 : y1; - - x_min = (xmin <= x_min) ? xmin : x_min; - x_max = (xmax >= x_max) ? xmax : x_max; - y_max = (ymax >= y_max) ? ymax : y_max; - y_min = (ymin <= y_min) ? ymin : y_min; - } - } - } - - for (map<int, Goal*>::const_iterator itr = _goals.begin(); - itr != _goals.end(); ++itr) { - - const vector<Wall>& allWalls = itr->second->GetAllWalls(); - - for (unsigned int a = 0; a < allWalls.size(); a++) { - double x1 = allWalls[a].GetPoint1().GetX(); - double y1 = allWalls[a].GetPoint1().GetY(); - double x2 = allWalls[a].GetPoint2().GetX(); - double y2 = allWalls[a].GetPoint2().GetY(); - - double xmax = (x1 > x2) ? x1 : x2; - double xmin = (x1 > x2) ? x2 : x1; - double ymax = (y1 > y2) ? y1 : y2; - double ymin = (y1 > y2) ? y2 : y1; - - x_min = (xmin <= x_min) ? xmin : x_min; - x_max = (xmax >= x_max) ? xmax : x_max; - y_max = (ymax >= y_max) ? ymax : y_max; - y_min = (ymin <= y_min) ? ymin : y_min; - } - } - - //make the grid slightly larger. - x_min = x_min - 10.0; - x_max = x_max + 10.0; - y_min = y_min - 10.0; - y_max = y_max + 10.0; - - SubRoom* bigSubroom = new NormalSubRoom(); - bigSubroom->SetRoomID(_rooms.size()); - bigSubroom->SetSubRoomID(0); // should be the single subroom - bigSubroom->AddWall(Wall(Point(x_min, y_min), Point(x_min, y_max))); - bigSubroom->AddWall(Wall(Point(x_min, y_max), Point(x_max, y_max))); - bigSubroom->AddWall(Wall(Point(x_max, y_max), Point(x_max, y_min))); - bigSubroom->AddWall(Wall(Point(x_max, y_min), Point(x_min, y_min))); - - Room * bigRoom = new Room(); - bigRoom->AddSubRoom(bigSubroom); - bigRoom->SetCaption("outside"); - bigRoom->SetID(_rooms.size()); - AddRoom(bigRoom); + Log->Write("INFO: \tAdding the room 'outside' "); + // first look for the geometry boundaries + double x_min = FLT_MAX; + double x_max = -FLT_MAX; + double y_min = FLT_MAX; + double y_max = -FLT_MAX; + //finding the bounding of the grid + // and collect the pedestrians + for (unsigned int r = 0; r < _rooms.size(); r++) { + Room* room = _rooms[r]; + for (int j = 0; j < room->GetNumberOfSubRooms(); j++) { + SubRoom* sub = room->GetSubRoom(j); + const vector<Wall>& allWalls = sub->GetAllWalls(); + + for (unsigned int a = 0; a < allWalls.size(); a++) { + double x1 = allWalls[a].GetPoint1().GetX(); + double y1 = allWalls[a].GetPoint1().GetY(); + double x2 = allWalls[a].GetPoint2().GetX(); + double y2 = allWalls[a].GetPoint2().GetY(); + + double xmax = (x1 > x2) ? x1 : x2; + double xmin = (x1 > x2) ? x2 : x1; + double ymax = (y1 > y2) ? y1 : y2; + double ymin = (y1 > y2) ? y2 : y1; + + x_min = (xmin <= x_min) ? xmin : x_min; + x_max = (xmax >= x_max) ? xmax : x_max; + y_max = (ymax >= y_max) ? ymax : y_max; + y_min = (ymin <= y_min) ? ymin : y_min; + } + } + } + + for (map<int, Goal*>::const_iterator itr = _goals.begin(); + itr != _goals.end(); ++itr) { + + const vector<Wall>& allWalls = itr->second->GetAllWalls(); + + for (unsigned int a = 0; a < allWalls.size(); a++) { + double x1 = allWalls[a].GetPoint1().GetX(); + double y1 = allWalls[a].GetPoint1().GetY(); + double x2 = allWalls[a].GetPoint2().GetX(); + double y2 = allWalls[a].GetPoint2().GetY(); + + double xmax = (x1 > x2) ? x1 : x2; + double xmin = (x1 > x2) ? x2 : x1; + double ymax = (y1 > y2) ? y1 : y2; + double ymin = (y1 > y2) ? y2 : y1; + + x_min = (xmin <= x_min) ? xmin : x_min; + x_max = (xmax >= x_max) ? xmax : x_max; + y_max = (ymax >= y_max) ? ymax : y_max; + y_min = (ymin <= y_min) ? ymin : y_min; + } + } + + //make the grid slightly larger. + x_min = x_min - 10.0; + x_max = x_max + 10.0; + y_min = y_min - 10.0; + y_max = y_max + 10.0; + + SubRoom* bigSubroom = new NormalSubRoom(); + bigSubroom->SetRoomID(_rooms.size()); + bigSubroom->SetSubRoomID(0); // should be the single subroom + bigSubroom->AddWall(Wall(Point(x_min, y_min), Point(x_min, y_max))); + bigSubroom->AddWall(Wall(Point(x_min, y_max), Point(x_max, y_max))); + bigSubroom->AddWall(Wall(Point(x_max, y_max), Point(x_max, y_min))); + bigSubroom->AddWall(Wall(Point(x_max, y_min), Point(x_min, y_min))); + + Room * bigRoom = new Room(); + bigRoom->AddSubRoom(bigSubroom); + bigRoom->SetCaption("outside"); + bigRoom->SetID(_rooms.size()); + AddRoom(bigRoom); } bool Building::InitGeometry() { - Log->Write("INFO: \tInit Geometry"); - for (int i = 0; i < GetNumberOfRooms(); i++) { - Room* room = GetRoom(i); - // Polygone berechnen - for (int j = 0; j < room->GetNumberOfSubRooms(); j++) { - SubRoom* s = room->GetSubRoom(j); - // Alle Übergänge in diesem Raum bestimmen - // Übergänge müssen zu Wänden ergänzt werden - vector<Line*> goals = vector<Line*>(); - - // crossings - const vector<Crossing*>& crossings = s->GetAllCrossings(); - for (unsigned int i = 0; i < crossings.size(); i++) { - goals.push_back(crossings[i]); - } - - // and transitions - const vector<Transition*>& transitions = s->GetAllTransitions(); - for (unsigned int i = 0; i < transitions.size(); i++) { - goals.push_back(transitions[i]); - } - - // initialize the poly - if(!s->ConvertLineToPoly(goals)) - return false; - s->CalculateArea(); - goals.clear(); - - //do the same for the obstacles that are closed - const vector<Obstacle*>& obstacles = s->GetAllObstacles(); - for (unsigned int obs = 0; obs < obstacles.size(); ++obs) { - if (obstacles[obs]->GetClosed() == 1) - if(!obstacles[obs]->ConvertLineToPoly()) - return false; - } - } - } - Log->Write("INFO: \tInit Geometry successful!!!\n"); - return true; + Log->Write("INFO: \tInit Geometry"); + for (int i = 0; i < GetNumberOfRooms(); i++) { + Room* room = GetRoom(i); + // Polygone berechnen + for (int j = 0; j < room->GetNumberOfSubRooms(); j++) { + SubRoom* s = room->GetSubRoom(j); + // Alle Übergänge in diesem Raum bestimmen + // Übergänge müssen zu Wänden ergänzt werden + vector<Line*> goals = vector<Line*>(); + + // crossings + const vector<Crossing*>& crossings = s->GetAllCrossings(); + for (unsigned int i = 0; i < crossings.size(); i++) { + goals.push_back(crossings[i]); + } + + // and transitions + const vector<Transition*>& transitions = s->GetAllTransitions(); + for (unsigned int i = 0; i < transitions.size(); i++) { + goals.push_back(transitions[i]); + } + + // initialize the poly + if(! s->ConvertLineToPoly(goals)) + return false; + s->CalculateArea(); + goals.clear(); + + //do the same for the obstacles that are closed + const vector<Obstacle*>& obstacles = s->GetAllObstacles(); + for (unsigned int obs = 0; obs < obstacles.size(); ++obs) { + if (obstacles[obs]->GetClosed() == 1) + if(!obstacles[obs]->ConvertLineToPoly()) + return false; + } + } + } + Log->Write("INFO: \tInit Geometry successful!!!\n"); + + return true; } - - const string& Building::GetProjectFilename() const { - return _projectFilename; + return _projectFilename; } void Building::SetProjectFilename(const std::string &filename) { - _projectFilename=filename; + _projectFilename=filename; } void Building::SetProjectRootDir(const std::string &filename) { - _projectRootDir= filename; + _projectRootDir= filename; } const string& Building::GetProjectRootDir() const { - return _projectRootDir; + return _projectRootDir; } - - -bool Building::LoadBuildingFromFile(const std::string &filename) +const std::string& Building::GetGeometryFilename() const { + return _geometryFilename; +} - //get the geometry filename from the project file if none was supplied - string geoFilename=filename; - if(geoFilename=="") { - TiXmlDocument doc(_projectFilename); - if (!doc.LoadFile()) { - Log->Write("ERROR: \t%s", doc.ErrorDesc()); - Log->Write("ERROR: \t could not parse the project file"); - return false; - } - - Log->Write("INFO: \tParsing the geometry file"); - TiXmlElement* xMainNode = doc.RootElement(); - if(xMainNode->FirstChild("geometry")) { - geoFilename=_projectRootDir+xMainNode->FirstChild("geometry")->FirstChild()->Value(); - Log->Write("INFO: \tgeometry <"+geoFilename+">"); - } - } else { - geoFilename=_projectRootDir+geoFilename; - } - - TiXmlDocument docGeo(geoFilename); - if (!docGeo.LoadFile()) { - Log->Write("ERROR: \t%s", docGeo.ErrorDesc()); - Log->Write("ERROR: \t could not parse the geometry file [%s]",geoFilename.c_str()); - return false; - } - - TiXmlElement* xRootNode = docGeo.RootElement(); - if( ! xRootNode ) { - Log->Write("ERROR:\tRoot element does not exist"); - return false; - } - - if( xRootNode->ValueStr () != "geometry" ) { - Log->Write("ERROR:\tRoot element value is not 'geometry'."); - return false; - } - - if(string(xRootNode->Attribute("unit"))!="m") { - Log->Write("ERROR:\tOnly the unit m (metres) is supported. \n\tYou supplied [%s]",xRootNode->Attribute("unit")); - return false; - } - - double version = xmltof(xRootNode->Attribute("version"), -1); - if (version < 0.4) { - Log->Write("ERROR: \tOnly version > 0.4 supported. Your version is %f",version); - Log->Write("ERROR: \tparsing geometry file failed!"); - return false; - } - _caption = xmltoa(xRootNode->Attribute("caption"), "virtual building"); - - - //The file has two main nodes - //<rooms> and <transitions> - - - //processing the rooms node - TiXmlNode* xRoomsNode = xRootNode->FirstChild("rooms"); - if (!xRoomsNode) { - Log->Write("ERROR: \tThe geometry should have at least one room and one subroom"); - return false; - } - - for(TiXmlElement* xRoom = xRoomsNode->FirstChildElement("room"); xRoom; - xRoom = xRoom->NextSiblingElement("room")) { - - Room* room = new Room(); - - string room_id = xmltoa(xRoom->Attribute("id"), "-1"); - room->SetID(xmltoi(room_id.c_str(), -1)); - - string caption = "room " + room_id; - room->SetCaption( - xmltoa(xRoom->Attribute("caption"), caption.c_str())); - - double position = xmltof(xRoom->Attribute("zpos"), 0.0); - - //TODO?? what the hell is that for ? - //if(position>6.0) position+=50; - room->SetZPos(position); - - //parsing the subrooms - //processing the rooms node - //TiXmlNode* xSubroomsNode = xRoom->FirstChild("subroom"); - - for(TiXmlElement* xSubRoom = xRoom->FirstChildElement("subroom"); xSubRoom; - xSubRoom = xSubRoom->NextSiblingElement("subroom")) { - - - string subroom_id = xmltoa(xSubRoom->Attribute("id"), "-1"); - string closed = xmltoa(xSubRoom->Attribute("closed"), "0"); - string type = xmltoa(xSubRoom->Attribute("class"),"subroom"); - - //get the equation of the plane if any - double A_x = xmltof(xSubRoom->Attribute("A_x"), 0.0); - double B_y = xmltof(xSubRoom->Attribute("B_y"), 0.0); - double C_z = xmltof(xSubRoom->Attribute("C_z"), 0.0); - - SubRoom* subroom = NULL; - - if (type == "stair") { - if(xSubRoom->FirstChildElement("up")==NULL) { - Log->Write("ERROR:\t the attribute <up> and <down> are missing for the stair"); - Log->Write("ERROR:\t check your geometry file"); - exit(EXIT_FAILURE); - } - double up_x = xmltof( xSubRoom->FirstChildElement("up")->Attribute("px"), 0.0); - double up_y = xmltof( xSubRoom->FirstChildElement("up")->Attribute("py"), 0.0); - double down_x = xmltof( xSubRoom->FirstChildElement("down")->Attribute("py"), 0.0); - double down_y = xmltof( xSubRoom->FirstChildElement("down")->Attribute("py"), 0.0); - subroom = new Stair(); - ((Stair*)subroom)->SetUp(Point(up_x,up_y)); - ((Stair*)subroom)->SetDown(Point(down_x,down_y)); - } else { - //normal subroom or corridor - subroom = new NormalSubRoom(); - } - - subroom->SetType(type); - subroom->SetPlanEquation(A_x,B_y,C_z); - subroom->SetRoomID(room->GetID()); - subroom->SetSubRoomID(xmltoi(subroom_id.c_str(), -1)); - - //looking for polygons (walls) - for(TiXmlElement* xPolyVertices = xSubRoom->FirstChildElement("polygon"); xPolyVertices; - xPolyVertices = xPolyVertices->NextSiblingElement("polygon")) { - - for (TiXmlElement* xVertex = xPolyVertices->FirstChildElement( - "vertex"); - xVertex && xVertex != xPolyVertices->LastChild("vertex"); - xVertex = xVertex->NextSiblingElement("vertex")) { - - double x1 = xmltof(xVertex->Attribute("px")); - double y1 = xmltof(xVertex->Attribute("py")); - double x2 = xmltof(xVertex->NextSiblingElement("vertex")->Attribute("px")); - double y2 = xmltof(xVertex->NextSiblingElement("vertex")->Attribute("py")); - - subroom->AddWall(Wall(Point(x1, y1), Point(x2, y2))); - } - - } - - //looking for obstacles - for(TiXmlElement* xObstacle = xSubRoom->FirstChildElement("obstacle"); xObstacle; - xObstacle = xObstacle->NextSiblingElement("obstacle")) { - - int id = xmltof(xObstacle->Attribute("id"), -1); - int height = xmltof(xObstacle->Attribute("height"), 0); - double closed = xmltof(xObstacle->Attribute("closed"), 0); - string caption = xmltoa(xObstacle->Attribute("caption"),"-1"); - - Obstacle* obstacle = new Obstacle(); - obstacle->SetId(id); - obstacle->SetCaption(caption); - obstacle->SetClosed(closed); - obstacle->SetHeight(height); - - //looking for polygons (walls) - for(TiXmlElement* xPolyVertices = xObstacle->FirstChildElement("polygon"); xPolyVertices; - xPolyVertices = xPolyVertices->NextSiblingElement("polygon")) { +bool Building::LoadGeometry(const std::string &geometryfile) +{ + //get the geometry filename from the project file + string geoFilenameWithPath= _projectRootDir + geometryfile; + + if(geometryfile=="") + { + TiXmlDocument doc(_projectFilename); + if (!doc.LoadFile()) { + Log->Write("ERROR: \t%s", doc.ErrorDesc()); + Log->Write("\t could not parse the project file"); + return false; + } + + Log->Write("INFO: \tParsing the geometry file"); + TiXmlElement* xMainNode = doc.RootElement(); + + if(xMainNode->FirstChild("geometry")) { + _geometryFilename=xMainNode->FirstChild("geometry")->FirstChild()->Value(); + geoFilenameWithPath=_projectRootDir+_geometryFilename; + Log->Write("INFO: \tgeometry <"+_geometryFilename+">"); + } + } + + TiXmlDocument docGeo(geoFilenameWithPath); + if (!docGeo.LoadFile()) { + Log->Write("ERROR: \t%s", docGeo.ErrorDesc()); + Log->Write("\t could not parse the geometry file"); + return false; + } + + TiXmlElement* xRootNode = docGeo.RootElement(); + if( ! xRootNode ) { + Log->Write("ERROR:\tRoot element does not exist"); + return false; + } + + if( xRootNode->ValueStr () != "geometry" ) { + Log->Write("ERROR:\tRoot element value is not 'geometry'."); + return false; + } + if(xRootNode->Attribute("unit")) + if(string(xRootNode->Attribute("unit")) != "m") { + Log->Write("ERROR:\tOnly the unit m (meters) is supported. \n\tYou supplied [%s]",xRootNode->Attribute("unit")); + return false; + } + + double version = xmltof(xRootNode->Attribute("version"), -1); + + if (version != std::stod(JPS_VERSION)) { + Log->Write(" \tWrong geometry version!"); + Log->Write(" \tOnly version >= %s supported",JPS_VERSION); + Log->Write(" \tPlease update the version of your geometry file to %s",JPS_VERSION); + return false; + } + + _caption = xmltoa(xRootNode->Attribute("caption"), "virtual building"); + //The file has two main nodes + //<rooms> and <transitions> + + //processing the rooms node + TiXmlNode* xRoomsNode = xRootNode->FirstChild("rooms"); + if (!xRoomsNode) { + Log->Write("ERROR: \tThe geometry should have at least one room and one subroom"); + return false; + } + + for(TiXmlElement* xRoom = xRoomsNode->FirstChildElement("room"); xRoom; + xRoom = xRoom->NextSiblingElement("room")) { + + Room* room = new Room(); + + string room_id = xmltoa(xRoom->Attribute("id"), "-1"); + room->SetID(xmltoi(room_id.c_str(), -1)); + + string caption = "room " + room_id; + room->SetCaption( + xmltoa(xRoom->Attribute("caption"), caption.c_str())); + + double position = xmltof(xRoom->Attribute("zpos"), 0.0); + + //if(position>6.0) position+=50; + room->SetZPos(position); + + //parsing the subrooms + //processing the rooms node + //TiXmlNode* xSubroomsNode = xRoom->FirstChild("subroom"); + + for(TiXmlElement* xSubRoom = xRoom->FirstChildElement("subroom"); xSubRoom; + xSubRoom = xSubRoom->NextSiblingElement("subroom")) { + + + string subroom_id = xmltoa(xSubRoom->Attribute("id"), "-1"); + string closed = xmltoa(xSubRoom->Attribute("closed"), "0"); + string type = xmltoa(xSubRoom->Attribute("class"),"subroom"); + + //get the equation of the plane if any + double A_x = xmltof(xSubRoom->Attribute("A_x"), 0.0); + double B_y = xmltof(xSubRoom->Attribute("B_y"), 0.0); + double C_z = xmltof(xSubRoom->Attribute("C_z"), 0.0); + + SubRoom* subroom = NULL; + + if (type == "stair") { + if(xSubRoom->FirstChildElement("up")==NULL) { + Log->Write("ERROR:\t the attribute <up> and <down> are missing for the stair"); + Log->Write("ERROR:\t check your geometry file"); + return false; + } + double up_x = xmltof( xSubRoom->FirstChildElement("up")->Attribute("px"), 0.0); + double up_y = xmltof( xSubRoom->FirstChildElement("up")->Attribute("py"), 0.0); + double down_x = xmltof( xSubRoom->FirstChildElement("down")->Attribute("py"), 0.0); + double down_y = xmltof( xSubRoom->FirstChildElement("down")->Attribute("py"), 0.0); + subroom = new Stair(); + ((Stair*)subroom)->SetUp(Point(up_x,up_y)); + ((Stair*)subroom)->SetDown(Point(down_x,down_y)); + } else { + //normal subroom or corridor + subroom = new NormalSubRoom(); + } + + subroom->SetType(type); + subroom->SetPlanEquation(A_x,B_y,C_z); + subroom->SetRoomID(room->GetID()); + subroom->SetSubRoomID(xmltoi(subroom_id.c_str(), -1)); + + //static int p_id=1; + //cout<<endl<<"wall polygon: "<< p_id++<<endl; + //looking for polygons (walls) + for(TiXmlElement* xPolyVertices = xSubRoom->FirstChildElement("polygon"); xPolyVertices; + xPolyVertices = xPolyVertices->NextSiblingElement("polygon")) { for (TiXmlElement* xVertex = xPolyVertices->FirstChildElement( - "vertex"); - xVertex && xVertex != xPolyVertices->LastChild("vertex"); - xVertex = xVertex->NextSiblingElement("vertex")) { - - double x1 = xmltof(xVertex->Attribute("px")); - double y1 = xmltof(xVertex->Attribute("py")); - double x2 = xmltof(xVertex->NextSiblingElement("vertex")->Attribute("px")); - double y2 = xmltof(xVertex->NextSiblingElement("vertex")->Attribute("py")); - obstacle->AddWall(Wall(Point(x1, y1), Point(x2, y2))); + "vertex"); + xVertex && xVertex != xPolyVertices->LastChild("vertex"); + xVertex = xVertex->NextSiblingElement("vertex")) { + + double x1 = xmltof(xVertex->Attribute("px")); + double y1 = xmltof(xVertex->Attribute("py")); + double x2 = xmltof(xVertex->NextSiblingElement("vertex")->Attribute("px")); + double y2 = xmltof(xVertex->NextSiblingElement("vertex")->Attribute("py")); + subroom->AddWall(Wall(Point(x1, y1), Point(x2, y2))); + //printf("%0.2f %0.2f %0.2f %0.2f\n",x1,y1,x2,y2); } - } - subroom->AddObstacle(obstacle); - } - room->AddSubRoom(subroom); - } - - //parsing the crossings - TiXmlNode* xCrossingsNode = xRoom->FirstChild("crossings"); - if(xCrossingsNode) - for(TiXmlElement* xCrossing = xCrossingsNode->FirstChildElement("crossing"); xCrossing; - xCrossing = xCrossing->NextSiblingElement("crossing")) { - - int id = xmltoi(xCrossing->Attribute("id"), -1); - int sub1_id = xmltoi(xCrossing->Attribute("subroom1_id"), -1); - int sub2_id = xmltoi(xCrossing->Attribute("subroom2_id"), -1); - - double x1 = xmltof( xCrossing->FirstChildElement("vertex")->Attribute("px")); - double y1 = xmltof( xCrossing->FirstChildElement("vertex")->Attribute("py")); - double x2 = xmltof( xCrossing->LastChild("vertex")->ToElement()->Attribute("px")); - double y2 = xmltof( xCrossing->LastChild("vertex")->ToElement()->Attribute("py")); - - Crossing* c = new Crossing(); - c->SetID(id); - c->SetPoint1(Point(x1, y1)); - c->SetPoint2(Point(x2, y2)); - - c->SetSubRoom1(room->GetSubRoom(sub1_id)); - c->SetSubRoom2(room->GetSubRoom(sub2_id)); - c->SetRoom1(room); - AddCrossing(c); - - room->GetSubRoom(sub1_id)->AddCrossing(c); - room->GetSubRoom(sub2_id)->AddCrossing(c); - } - - AddRoom(room); - } - - // all rooms are read, now proceed with transitions - TiXmlNode* xTransNode = xRootNode->FirstChild("transitions"); - if(xTransNode) - for(TiXmlElement* xTrans = xTransNode->FirstChildElement("transition"); xTrans; - xTrans = xTrans->NextSiblingElement("transition")) { - - int id = xmltoi(xTrans->Attribute("id"), -1); - string caption = "door " + id; - caption = xmltoa(xTrans->Attribute("caption"), caption.c_str()); - int room1_id = xmltoi(xTrans->Attribute("room1_id"), -1); - int room2_id = xmltoi(xTrans->Attribute("room2_id"), -1); - int subroom1_id = xmltoi(xTrans->Attribute("subroom1_id"), -1); - int subroom2_id = xmltoi(xTrans->Attribute("subroom2_id"), -1); - string type = xmltoa(xTrans->Attribute("type"), "normal"); - - double x1 = xmltof( xTrans->FirstChildElement("vertex")->Attribute("px")); - double y1 = xmltof( xTrans->FirstChildElement("vertex")->Attribute("py")); - - double x2 = xmltof( xTrans->LastChild("vertex")->ToElement()->Attribute("px")); - double y2 = xmltof( xTrans->LastChild("vertex")->ToElement()->Attribute("py")); - - - Transition* t = new Transition(); - t->SetID(id); - t->SetCaption(caption); - t->SetPoint1(Point(x1, y1)); - t->SetPoint2(Point(x2, y2)); - t->SetType(type); - - if (room1_id != -1 && subroom1_id != -1) { - Room* room = _rooms[room1_id]; - SubRoom* subroom = room->GetSubRoom(subroom1_id); - - //subroom->AddGoalID(t->GetUniqueID()); - //MPI - room->AddTransitionID(t->GetUniqueID()); - t->SetRoom1(room); - t->SetSubRoom1(subroom); - - //new implementation - subroom->AddTransition(t); - } - if (room2_id != -1 && subroom2_id != -1) { - Room* room = _rooms[room2_id]; - SubRoom* subroom = room->GetSubRoom(subroom2_id); - //subroom->AddGoalID(t->GetUniqueID()); - //MPI - room->AddTransitionID(t->GetUniqueID()); - t->SetRoom2(room); - t->SetSubRoom2(subroom); - - //new implementation - subroom->AddTransition(t); - } - - AddTransition(t); - } - - - Log->Write("INFO: \tLoading building file successful!!!\n"); - return true; + } + + //looking for obstacles + for(TiXmlElement* xObstacle = xSubRoom->FirstChildElement("obstacle"); xObstacle; + xObstacle = xObstacle->NextSiblingElement("obstacle")) { + + int id = xmltof(xObstacle->Attribute("id"), -1); + int height = xmltof(xObstacle->Attribute("height"), 0); + double closed = xmltof(xObstacle->Attribute("closed"), 0); + string caption = xmltoa(xObstacle->Attribute("caption"),"-1"); + + Obstacle* obstacle = new Obstacle(); + obstacle->SetId(id); + obstacle->SetCaption(caption); + obstacle->SetClosed(closed); + obstacle->SetHeight(height); + + //looking for polygons (walls) + for(TiXmlElement* xPolyVertices = xObstacle->FirstChildElement("polygon"); xPolyVertices; + xPolyVertices = xPolyVertices->NextSiblingElement("polygon")) { + + for (TiXmlElement* xVertex = xPolyVertices->FirstChildElement( + "vertex"); + xVertex && xVertex != xPolyVertices->LastChild("vertex"); + xVertex = xVertex->NextSiblingElement("vertex")) { + + double x1 = xmltof(xVertex->Attribute("px")); + double y1 = xmltof(xVertex->Attribute("py")); + double x2 = xmltof(xVertex->NextSiblingElement("vertex")->Attribute("px")); + double y2 = xmltof(xVertex->NextSiblingElement("vertex")->Attribute("py")); + obstacle->AddWall(Wall(Point(x1, y1), Point(x2, y2))); + } + } + subroom->AddObstacle(obstacle); + } + room->AddSubRoom(subroom); + } + + //parsing the crossings + TiXmlNode* xCrossingsNode = xRoom->FirstChild("crossings"); + if(xCrossingsNode) + for(TiXmlElement* xCrossing = xCrossingsNode->FirstChildElement("crossing"); xCrossing; + xCrossing = xCrossing->NextSiblingElement("crossing")) { + + int id = xmltoi(xCrossing->Attribute("id"), -1); + int sub1_id = xmltoi(xCrossing->Attribute("subroom1_id"), -1); + int sub2_id = xmltoi(xCrossing->Attribute("subroom2_id"), -1); + + double x1 = xmltof( xCrossing->FirstChildElement("vertex")->Attribute("px")); + double y1 = xmltof( xCrossing->FirstChildElement("vertex")->Attribute("py")); + double x2 = xmltof( xCrossing->LastChild("vertex")->ToElement()->Attribute("px")); + double y2 = xmltof( xCrossing->LastChild("vertex")->ToElement()->Attribute("py")); + + Crossing* c = new Crossing(); + c->SetID(id); + c->SetPoint1(Point(x1, y1)); + c->SetPoint2(Point(x2, y2)); + + c->SetSubRoom1(room->GetSubRoom(sub1_id)); + c->SetSubRoom2(room->GetSubRoom(sub2_id)); + c->SetRoom1(room); + AddCrossing(c); + + room->GetSubRoom(sub1_id)->AddCrossing(c); + room->GetSubRoom(sub2_id)->AddCrossing(c); + } + + AddRoom(room); + } + //exit(0); + + // all rooms are read, now proceed with transitions + TiXmlNode* xTransNode = xRootNode->FirstChild("transitions"); + if(xTransNode) + for(TiXmlElement* xTrans = xTransNode->FirstChildElement("transition"); xTrans; + xTrans = xTrans->NextSiblingElement("transition")) { + + int id = xmltoi(xTrans->Attribute("id"), -1); + // string caption = "door " + id; + string caption = "door "; + caption += to_string(id); + caption = xmltoa(xTrans->Attribute("caption"), caption.c_str()); + int room1_id = xmltoi(xTrans->Attribute("room1_id"), -1); + int room2_id = xmltoi(xTrans->Attribute("room2_id"), -1); + int subroom1_id = xmltoi(xTrans->Attribute("subroom1_id"), -1); + int subroom2_id = xmltoi(xTrans->Attribute("subroom2_id"), -1); + string type = xmltoa(xTrans->Attribute("type"), "normal"); + + double x1 = xmltof( xTrans->FirstChildElement("vertex")->Attribute("px")); + double y1 = xmltof( xTrans->FirstChildElement("vertex")->Attribute("py")); + + double x2 = xmltof( xTrans->LastChild("vertex")->ToElement()->Attribute("px")); + double y2 = xmltof( xTrans->LastChild("vertex")->ToElement()->Attribute("py")); + + + Transition* t = new Transition(); + t->SetID(id); + t->SetCaption(caption); + t->SetPoint1(Point(x1, y1)); + t->SetPoint2(Point(x2, y2)); + t->SetType(type); + + if (room1_id != -1 && subroom1_id != -1) { + //Room* room = _rooms[room1_id]; + Room* room = GetRoom(room1_id); + SubRoom* subroom = room->GetSubRoom(subroom1_id); + + //subroom->AddGoalID(t->GetUniqueID()); + //MPI + room->AddTransitionID(t->GetUniqueID()); + t->SetRoom1(room); + t->SetSubRoom1(subroom); + + //new implementation + subroom->AddTransition(t); + } + if (room2_id != -1 && subroom2_id != -1) { + Room* room = _rooms[room2_id]; + SubRoom* subroom = room->GetSubRoom(subroom2_id); + //subroom->AddGoalID(t->GetUniqueID()); + //MPI + room->AddTransitionID(t->GetUniqueID()); + t->SetRoom2(room); + t->SetSubRoom2(subroom); + + //new implementation + subroom->AddTransition(t); + } + + AddTransition(t); + } + + Log->Write("INFO: \tLoading building file successful!!!\n"); + + //everything went fine + return true; } void Building::WriteToErrorLog() const { - Log->Write("GEOMETRY: "); - for (int i = 0; i < GetNumberOfRooms(); i++) { - Room* r = GetRoom(i); - r->WriteToErrorLog(); - } - Log->Write("ROUTING: "); - - for (map<int, Crossing*>::const_iterator iter = _crossings.begin(); - iter != _crossings.end(); ++iter) { - iter->second->WriteToErrorLog(); - } - for (map<int, Transition*>::const_iterator iter = _transitions.begin(); - iter != _transitions.end(); ++iter) { - iter->second->WriteToErrorLog(); - } - for (map<int, Hline*>::const_iterator iter = _hLines.begin(); - iter != _hLines.end(); ++iter) { - iter->second->WriteToErrorLog(); - } - Log->Write("\n"); + Log->Write("GEOMETRY: "); + for (int i = 0; i < GetNumberOfRooms(); i++) { + Room* r = GetRoom(i); + r->WriteToErrorLog(); + } + Log->Write("ROUTING: "); + + for (map<int, Crossing*>::const_iterator iter = _crossings.begin(); + iter != _crossings.end(); ++iter) { + iter->second->WriteToErrorLog(); + } + for (map<int, Transition*>::const_iterator iter = _transitions.begin(); + iter != _transitions.end(); ++iter) { + iter->second->WriteToErrorLog(); + } + for (map<int, Hline*>::const_iterator iter = _hLines.begin(); + iter != _hLines.end(); ++iter) { + iter->second->WriteToErrorLog(); + } + Log->Write("\n"); } Room* Building::GetRoom(string caption) const { - for (unsigned int r = 0; r < _rooms.size(); r++) { - if (_rooms[r]->GetCaption() == caption) - return _rooms[r]; - } - Log->Write("Warning: Room not found with caption " + caption); - //return NULL; - exit(EXIT_FAILURE); + for (unsigned int r = 0; r < _rooms.size(); r++) { + if (_rooms[r]->GetCaption() == caption) + return _rooms[r]; + } + Log->Write("ERROR: Room not found with caption " + caption); + //return NULL; + exit(EXIT_FAILURE); } void Building::AddCrossing(Crossing* line) { - if (_crossings.count(line->GetID()) != 0) { - char tmp[CLENGTH]; - sprintf(tmp, - "ERROR: Duplicate index for crossing found [%d] in Routing::AddCrossing()", - line->GetID()); - Log->Write(tmp); - exit(EXIT_FAILURE); - } - _crossings[line->GetID()] = line; + if (_crossings.count(line->GetID()) != 0) { + char tmp[CLENGTH]; + sprintf(tmp, + "ERROR: Duplicate index for crossing found [%d] in Routing::AddCrossing()", + line->GetID()); + Log->Write(tmp); + exit(EXIT_FAILURE); + } + _crossings[line->GetID()] = line; } void Building::AddTransition(Transition* line) { - if (_transitions.count(line->GetID()) != 0) { - char tmp[CLENGTH]; - sprintf(tmp, - "ERROR: Duplicate index for transition found [%d] in Routing::AddTransition()", - line->GetID()); - Log->Write(tmp); - exit(EXIT_FAILURE); - } - _transitions[line->GetID()] = line; + if (_transitions.count(line->GetID()) != 0) { + char tmp[CLENGTH]; + sprintf(tmp, + "ERROR: Duplicate index for transition found [%d] in Routing::AddTransition()", + line->GetID()); + Log->Write(tmp); + exit(EXIT_FAILURE); + } + _transitions[line->GetID()] = line; } void Building::AddHline(Hline* line) { - if (_hLines.count(line->GetID()) != 0) { - Log->Write( - "ERROR: Duplicate index for hlines found [%d] in Routing::AddHline()", - line->GetID()); - exit(EXIT_FAILURE); - } - _hLines[line->GetID()] = line; + if (_hLines.count(line->GetID()) != 0) { + // check if the lines are identical + Hline* ori= _hLines[line->GetID()]; + if(ori->operator ==(*line)) { + Log->Write("INFO: Skipping identical hlines with ID [%d]",line->GetID()); + return; + } else { + Log->Write( + "ERROR: Duplicate index for hlines found [%d] in Routing::AddHline(). You have [%d] hlines", + line->GetID(), _hLines.size()); + exit(EXIT_FAILURE); + } + } + _hLines[line->GetID()] = line; } void Building::AddGoal(Goal* goal) { - if (_goals.count(goal->GetId()) != 0) { - Log->Write( - "ERROR: Duplicate index for goal found [%d] in Routing::AddGoal()", - goal->GetId()); - exit(EXIT_FAILURE); - } - _goals[goal->GetId()] = goal; + if (_goals.count(goal->GetId()) != 0) { + Log->Write( + "ERROR: Duplicate index for goal found [%d] in Routing::AddGoal()", + goal->GetId()); + exit(EXIT_FAILURE); + } + _goals[goal->GetId()] = goal; } const map<int, Crossing*>& Building::GetAllCrossings() const { - return _crossings; + return _crossings; } const map<int, Transition*>& Building::GetAllTransitions() const { - return _transitions; + return _transitions; } const map<int, Hline*>& Building::GetAllHlines() const { - return _hLines; + return _hLines; } const map<int, Goal*>& Building::GetAllGoals() const { - return _goals; + return _goals; } Transition* Building::GetTransition(string caption) const { - //eventually - map<int, Transition*>::const_iterator itr; - for(itr = _transitions.begin(); itr != _transitions.end(); ++itr) { - if (itr->second->GetCaption() == caption) - return itr->second; - } - - Log->Write("WARNING: No Transition with Caption: " + caption); - exit(EXIT_FAILURE); + //eventually + map<int, Transition*>::const_iterator itr; + for(itr = _transitions.begin(); itr != _transitions.end(); ++itr) { + if (itr->second->GetCaption() == caption) + return itr->second; + } + + Log->Write("WARNING: No Transition with Caption: " + caption); + exit(EXIT_FAILURE); } Transition* Building::GetTransition(int ID) { - if (_transitions.count(ID) == 1) { - return _transitions[ID]; - } else { - if (ID == -1) - return NULL; - else { - Log->Write( - "ERROR: I could not find any transition with the 'ID' [%d]. You have defined [%d] transitions", - ID, _transitions.size()); - exit(EXIT_FAILURE); - } - } + if (_transitions.count(ID) == 1) { + return _transitions[ID]; + } else { + if (ID == -1) + return NULL; + else { + Log->Write( + "ERROR: I could not find any transition with the 'ID' [%d]. You have defined [%d] transitions", + ID, _transitions.size()); + exit(EXIT_FAILURE); + } + } } Goal* Building::GetFinalGoal(int ID) { - if (_goals.count(ID) == 1) { - return _goals[ID]; - } else { - if (ID == -1) - return NULL; - else { - Log->Write( - "ERROR: I could not find any goal with the 'ID' [%d]. You have defined [%d] goals", - ID, _goals.size()); - exit(EXIT_FAILURE); - } - } + if (_goals.count(ID) == 1) { + return _goals[ID]; + } else { + if (ID == -1) + return NULL; + else { + Log->Write( + "ERROR: I could not find any goal with the 'ID' [%d]. You have defined [%d] goals", + ID, _goals.size()); + exit(EXIT_FAILURE); + } + } } Crossing* Building::GetTransOrCrossByName(string caption) const { - { - //eventually - map<int, Transition*>::const_iterator itr; - for(itr = _transitions.begin(); itr != _transitions.end(); ++itr) { - if (itr->second->GetCaption() == caption) - return itr->second; - } - } - { - //finally the crossings - map<int, Crossing*>::const_iterator itr; - for(itr = _crossings.begin(); itr != _crossings.end(); ++itr) { - if (itr->second->GetCaption() == caption) - return itr->second; - } - } - - Log->Write("WARNING: No Transition or Crossing with Caption: " + caption); - return NULL; + { + //eventually + map<int, Transition*>::const_iterator itr; + for(itr = _transitions.begin(); itr != _transitions.end(); ++itr) { + if (itr->second->GetCaption() == caption) + return itr->second; + } + } + { + //finally the crossings + map<int, Crossing*>::const_iterator itr; + for(itr = _crossings.begin(); itr != _crossings.end(); ++itr) { + if (itr->second->GetCaption() == caption) + return itr->second; + } + } + + Log->Write("WARNING: No Transition or Crossing with Caption: " + caption); + return NULL; } -Crossing* Building::GetTransOrCrossByID(int id) const +Hline* Building::GetTransOrCrossByUID(int id) const { - { - //eventually - map<int, Transition*>::const_iterator itr; - for(itr = _transitions.begin(); itr != _transitions.end(); ++itr) { - if (itr->second->GetUniqueID()== id) - return itr->second; - } - } - { - //finally the crossings - map<int, Crossing*>::const_iterator itr; - for(itr = _crossings.begin(); itr != _crossings.end(); ++itr) { - if (itr->second->GetUniqueID() == id) - return itr->second; - } - } - - Log->Write("WARNING: No Transition or Crossing with ID %d: " ,id); - return NULL; + { + //eventually transitions + map<int, Transition*>::const_iterator itr; + for(itr = _transitions.begin(); itr != _transitions.end(); ++itr) { + if (itr->second->GetUniqueID()== id) + return itr->second; + } + } + { + //then the crossings + map<int, Crossing*>::const_iterator itr; + for(itr = _crossings.begin(); itr != _crossings.end(); ++itr) { + if (itr->second->GetUniqueID() == id) + return itr->second; + } + } + { + //finally the hlines + for(auto itr = _hLines.begin(); itr != _hLines.end(); ++itr) { + if (itr->second->GetUniqueID() == id) + return itr->second; + } + } + Log->Write("WARNING: No Transition or Crossing or hline with ID %d: " ,id); + return NULL; } +SubRoom* Building::GetSubRoomByUID( int uid) +{ + for (unsigned int i = 0; i < _rooms.size(); i++) { + Room* room = _rooms[i]; + for (int j = 0; j < room->GetNumberOfSubRooms(); j++) { + SubRoom* sub = room->GetSubRoom(j); + if (sub->GetUID()==uid) return sub;; + } + } + Log->Write("ERROR:\t No subroom exits with the unique id %d",uid); + return NULL; +} bool Building::IsVisible(Line* l1, Line* l2, bool considerHlines) { - for (unsigned int i = 0; i < _rooms.size(); i++) { - Room* room = _rooms[i]; - for (int j = 0; j < room->GetNumberOfSubRooms(); j++) { - SubRoom* sub = room->GetSubRoom(j); - if(sub->IsVisible(l1,l2,considerHlines)==false) return false; - } - } - return true; + for (unsigned int i = 0; i < _rooms.size(); i++) { + Room* room = _rooms[i]; + for (int j = 0; j < room->GetNumberOfSubRooms(); j++) { + SubRoom* sub = room->GetSubRoom(j); + if(sub->IsVisible(l1,l2,considerHlines)==false) return false; + } + } + return true; } bool Building::IsVisible(const Point& p1, const Point& p2, bool considerHlines) { - for (unsigned int i = 0; i < _rooms.size(); i++) { - Room* room = _rooms[i]; - for (int j = 0; j < room->GetNumberOfSubRooms(); j++) { - SubRoom* sub = room->GetSubRoom(j); - if(sub->IsVisible(p1,p2,considerHlines)==false) return false; - } - } - return true; + for (unsigned int i = 0; i < _rooms.size(); i++) { + Room* room = _rooms[i]; + for (int j = 0; j < room->GetNumberOfSubRooms(); j++) { + SubRoom* sub = room->GetSubRoom(j); + if(sub->IsVisible(p1,p2,considerHlines)==false) return false; + } + } + return true; } -void Building::SanityCheck() +bool Building::SanityCheck() { - Log->Write("INFO: \tChecking the geometry for artifacts"); - for (unsigned int i = 0; i < _rooms.size(); i++) { - Room* room = _rooms[i]; - - for (int j = 0; j < room->GetNumberOfSubRooms(); j++) { - SubRoom* sub = room->GetSubRoom(j); - sub->SanityCheck(); - } - } - Log->Write("INFO: \t...Done!!!\n"); + Log->Write("INFO: \tChecking the geometry for artifacts"); + bool status = true; + for (unsigned int i = 0; i < _rooms.size(); i++) { + Room* room = _rooms[i]; + + for (int j = 0; j < room->GetNumberOfSubRooms(); j++) { + SubRoom* sub = room->GetSubRoom(j); + if (!sub->SanityCheck()) + status = false; + } + } + Log->Write("INFO: \t...Done!!!\n"); + return status; } -#ifdef _SIMULATOR - -//TODO: merge this with Update and improve runtime -void Building::UpdateVerySlow() -{ - - vector<Pedestrian*> nonConformPeds; - for (int i = 0; i < GetNumberOfRooms(); i++) { - Room* room = GetRoom(i); - - for (int j = 0; j < room->GetNumberOfSubRooms(); j++) { - SubRoom* sub = room->GetSubRoom(j); - for (int k = 0; k < sub->GetNumberOfPedestrians(); k++) { - Pedestrian* ped = sub->GetPedestrian(k); - //set the new room if needed - if ((ped->GetFinalDestination() == FINAL_DEST_OUT) - && (GetRoom(ped->GetRoomID())->GetCaption() == "outside")) { - - sub->DeletePedestrian(k--); - DeletePedestrian(ped); - } else if ((ped->GetFinalDestination() != FINAL_DEST_OUT) - && (_goals[ped->GetFinalDestination()]->Contains( - ped->GetPos()))) { - sub->DeletePedestrian(k--); - DeletePedestrian(ped); - } else if (!sub->IsInSubRoom(ped)) { - nonConformPeds.push_back(ped); - sub->DeletePedestrian(k--); - } - } - } - } - - // reset that pedestrians who left their room not via the intended exit - for (int p = 0; p < (int) nonConformPeds.size(); p++) { - Pedestrian* ped = nonConformPeds[p]; - bool assigned = false; - for (int i = 0; i < GetNumberOfRooms(); i++) { - Room* room = GetRoom(i); - //if(room->GetCaption()=="outside") continue; - for (int j = 0; j < room->GetNumberOfSubRooms(); j++) { - SubRoom* sub = room->GetSubRoom(j); - SubRoom* old_sub= _rooms[ped->GetRoomID()]->GetSubRoom(ped->GetSubRoomID()); - if ((sub->IsInSubRoom(ped->GetPos())) && (sub->IsDirectlyConnectedWith(old_sub))) { - ped->SetRoomID(room->GetID(), room->GetCaption()); - ped->SetSubRoomID(sub->GetSubRoomID()); - ped->ClearMentalMap(); // reset the destination - //ped->FindRoute(); - sub->AddPedestrian(ped); - assigned = true; - break; - } - } - if (assigned == true) - break; // stop the loop - } - if (assigned == false) { - DeletePedestrian(ped); - } - } - - // find the new goals, the parallel way - - unsigned int nSize = _allPedestians.size(); - int nThreads = omp_get_max_threads(); - - // check if worth sharing the work - if (nSize < 12) - nThreads = 1; - - int partSize = nSize / nThreads; - - #pragma omp parallel default(shared) num_threads(nThreads) - { - const int threadID = omp_get_thread_num(); - int start = threadID * partSize; - int end = (threadID + 1) * partSize - 1; - if ((threadID == nThreads - 1)) - end = nSize - 1; - - for (int p = start; p <= end; ++p) { - if (_allPedestians[p]->FindRoute() == -1) { - //a destination could not be found for that pedestrian - //Log->Write("\tINFO: \tCould not found a route for pedestrian %d",_allPedestians[p]->GetID()); - //Log->Write("\tINFO: \tHe has reached the target cell"); - DeletePedFromSim(_allPedestians[p]); - //exit(EXIT_FAILURE); - } - } - } -} - -void Building::Update() -{ - // some peds may change the room via another crossing than the primary intended one - // in that case they are set in the wrong room. - vector<Pedestrian*> nonConformPeds; - for (int i = 0; i < GetNumberOfRooms(); i++) { - Room* room = GetRoom(i); - - for (int j = 0; j < room->GetNumberOfSubRooms(); j++) { - SubRoom* sub = room->GetSubRoom(j); - for (int k = 0; k < sub->GetNumberOfPedestrians(); k++) { - Pedestrian* ped = sub->GetPedestrian(k); - //set the new room if needed - if (!sub->IsInSubRoom(ped)) { - // the peds has changed the room and is farther than 50 cm from - // the exit, thats a real problem. - if (ped->GetExitLine()->DistTo(ped->GetPos()) > 0.50) { - Log->Write( - "WARNING: Building::update() pedestrian [%d] left the room/subroom [%s][%d/%d] " - "via unknown exit[??%d] \n Position: (%f, %f), distance to exit: (%f)", - ped->GetID(), - _rooms[ped->GetRoomID()]->GetCaption().c_str(), - ped->GetRoomID(), ped->GetSubRoomID(), - ped->GetExitIndex(), ped->GetPos().GetX(), - ped->GetPos().GetY(),ped->GetExitLine()->DistTo(ped->GetPos())); - //ped->Dump(ped->GetPedIndex()); - //std::cout << ped->GetLastDestination() << " " - // << ped->GetNextDestination() << std::endl; - //exit(0); - nonConformPeds.push_back(ped); - sub->DeletePedestrian(k--); - continue; // next pedestrian - } - - //safely converting (upcasting) the NavLine to a crossing. - Crossing* cross = - dynamic_cast<Crossing*>(ped->GetExitLine()); - if (cross == NULL) { - Log->Write("ERROR: Building::update() type casting error for ped %d",ped->GetID()); - Log->Write("ERROR: Fix Me !"); - nonConformPeds.push_back(ped); - exit(EXIT_FAILURE); - continue; - //fixme all portal should be derived from crossings - } - - SubRoom* other_sub = cross->GetOtherSubRoom( - room->GetID(), j); - - if (other_sub) { - int nextSubRoom = other_sub->GetSubRoomID(); - int nextRoom = other_sub->GetRoomID(); - ped->SetSubRoomID(nextSubRoom); - ped->SetRoomID(nextRoom, - GetRoom(nextRoom)->GetCaption()); - other_sub->AddPedestrian(ped); - - } else { - DeletePedestrian(ped); - //continue; - } - // Lösche Fußgänger aus aktuellem SubRoom - sub->DeletePedestrian(k--); // k--; - } - // neues Ziel setzten - //pRouting->FindExit(ped); - } - } - } - - // reset that pedestrians who left their room not via the intended exit - for (int p = 0; p < (int) nonConformPeds.size(); p++) { - Pedestrian* ped = nonConformPeds[p]; - bool assigned = false; - for (int i = 0; i < GetNumberOfRooms(); i++) { - Room* room = GetRoom(i); - for (int j = 0; j < room->GetNumberOfSubRooms(); j++) { - SubRoom* sub = room->GetSubRoom(j); - //only relocate in the same room - // or only in neighbouring rooms - if (room->GetID() != ped->GetRoomID()) - continue; - if (sub->IsInSubRoom(ped->GetPos())) { - //set in the new room - Log->Write("pedestrian %d relocated from room/subroom [%s] %d/%d to [%s] %d/%d ", - ped->GetID(), - GetRoom(ped->GetRoomID())->GetCaption().c_str(), - ped->GetRoomID(), ped->GetSubRoomID(), - room->GetCaption().c_str(), i, j); - ped->SetRoomID(room->GetID(), room->GetCaption()); - ped->SetSubRoomID(sub->GetSubRoomID()); - ped->ClearMentalMap(); // reset the destination - ped->FindRoute(); - sub->AddPedestrian(ped); - assigned = true; - break; - } - } - if (assigned == true) - break; // stop the loop - } - if (assigned == false) { - DeletePedestrian(ped); - } - } - - // find the new goals, the parallel way - - unsigned int nSize = _allPedestians.size(); - int nThreads = omp_get_max_threads(); - - // check if worth sharing the work - if (nSize < 12) - nThreads = 1; - - int partSize = nSize / nThreads; - - #pragma omp parallel default(shared) num_threads(nThreads) - { - const int threadID = omp_get_thread_num(); - int start = threadID * partSize; - int end = (threadID + 1) * partSize - 1; - if ((threadID == nThreads - 1)) - end = nSize - 1; - - for (int p = start; p <= end; ++p) { - if (_allPedestians[p]->FindRoute() == -1) { - //a destination could not be found for that pedestrian - //Log->Write("\tINFO: \tCould not found a route for pedestrian %d",_allPedestians[p]->GetID()); - //Log->Write("\tINFO: \tHe has reached the target cell"); - DeletePedFromSim(_allPedestians[p]); - //exit(EXIT_FAILURE); - } - } - } - - //cleaning up - //CleanUpTheScene(); -} +#ifdef _SIMULATOR -void Building::InitPhiAllPeds(double pDt) -{ - for (int i = 0; i < GetNumberOfRooms(); i++) { - Room* room = GetRoom(i); - for (int j = 0; j < room->GetNumberOfSubRooms(); j++) { - SubRoom* sub = room->GetSubRoom(j); - for (int k = 0; k < sub->GetNumberOfPedestrians(); k++) { - double cosPhi, sinPhi; - Pedestrian* ped = sub->GetPedestrian(k); - ped->Setdt(pDt); //set the simulation step - ped->SetRoomID(room->GetID(), room->GetCaption()); - //a destination could not be found for that pedestrian - if (ped->FindRoute() == -1) { - // DeletePedFromSim(ped); - sub->DeletePedestrian(k--); - continue; - } - Line* e = ped->GetExitLine(); - const Point& e1 = e->GetPoint1(); - const Point& e2 = e->GetPoint2(); - Point target = (e1 + e2) * 0.5; - Point d = target - ped->GetPos(); - double dist = d.Norm(); - if (dist != 0.0) { - cosPhi = d.GetX() / dist; - sinPhi = d.GetY() / dist; - } else { - Log->Write( - "ERROR: \tBuilding::InitPhiAllPeds() cannot initialise phi! " - "dist to target ist 0\n"); - exit(0); - } - - JEllipse E = ped->GetEllipse(); - E.SetCosPhi(cosPhi); - E.SetSinPhi(sinPhi); - ped->SetEllipse(E); - } - } - } -} void Building::UpdateGrid() { - _linkedCellGrid->Update(_allPedestians); + _linkedCellGrid->Update(_allPedestians); } void Building::InitGrid(double cellSize) { - - // first look for the geometry boundaries - double x_min = FLT_MAX; - double x_max = FLT_MIN; - double y_min = FLT_MAX; - double y_max = FLT_MIN; - - //finding the bounding of the grid - // and collect the pedestrians - for (unsigned int r = 0; r < _rooms.size(); r++) { - Room* room = _rooms[r]; - for (int j = 0; j < room->GetNumberOfSubRooms(); j++) { - SubRoom* sub = room->GetSubRoom(j); - const vector<Wall>& allWalls = sub->GetAllWalls(); - - for (unsigned int a = 0; a < allWalls.size(); a++) { - double x1 = allWalls[a].GetPoint1().GetX(); - double y1 = allWalls[a].GetPoint1().GetY(); - double x2 = allWalls[a].GetPoint2().GetX(); - double y2 = allWalls[a].GetPoint2().GetY(); - - double xmax = (x1 > x2) ? x1 : x2; - double xmin = (x1 > x2) ? x2 : x1; - double ymax = (y1 > y2) ? y1 : y2; - double ymin = (y1 > y2) ? y2 : y1; - - x_min = (xmin <= x_min) ? xmin : x_min; - x_max = (xmax >= x_max) ? xmax : x_max; - y_max = (ymax >= y_max) ? ymax : y_max; - y_min = (ymin <= y_min) ? ymin : y_min; - } - } - } - - for (unsigned int wa = 0; wa < _rooms.size(); wa++) { - Room* room = _rooms[wa]; - for (int j = 0; j < room->GetNumberOfSubRooms(); j++) { - SubRoom* sub = room->GetSubRoom(j); - for (int k = 0; k < sub->GetNumberOfPedestrians(); k++) { - Pedestrian* ped = sub->GetPedestrian(k); - _allPedestians.push_back(ped); - } - } - } - - //make the grid slightly larger. - x_min = x_min - 1.0; - x_max = x_max + 1.0; - y_min = y_min - 1.0; - y_max = y_max + 1.0; - - double boundaries[] = { x_min, x_max, y_min, y_max }; - int pedsCount = _allPedestians.size(); - - //no algorithms - // the domain is made of a sigle cell - if(cellSize==-1) { - Log->Write("INFO: \tBrute Force will be used for neighborhoods query"); - if ( (x_max-x_min) < (y_max-y_min) ) { - cellSize=(y_max-y_min); - } else { - cellSize=(x_max-x_min); - } - - } else { - Log->Write("INFO: \tInitializing the grid with cell size: %f ", cellSize); - } - - _linkedCellGrid = new LCGrid(boundaries, cellSize, pedsCount); - _linkedCellGrid->ShallowCopy(_allPedestians); - - Log->Write("INFO: \tDone with Initializing the grid "); -} - - - -void Building::DumpSubRoomInRoom(int roomID, int subID) -{ - SubRoom* sub = GetRoom(roomID)->GetSubRoom(subID); - if (sub->GetNumberOfPedestrians() == 0) - return; - cout << "dumping room/subroom " << roomID << " / " << subID << endl; - for (int p = 0; p < sub->GetNumberOfPedestrians(); p++) { - Pedestrian* ped = sub->GetPedestrian(p); - cout << " ID: " << ped->GetID(); - cout << " Index: " << p << endl; - } - + // first look for the geometry boundaries + double x_min = FLT_MAX; + double x_max = FLT_MIN; + double y_min = FLT_MAX; + double y_max = FLT_MIN; + + //finding the bounding of the grid + // and collect the pedestrians + for (unsigned int r = 0; r < _rooms.size(); r++) { + Room* room = _rooms[r]; + for (int j = 0; j < room->GetNumberOfSubRooms(); j++) { + SubRoom* sub = room->GetSubRoom(j); + const vector<Wall>& allWalls = sub->GetAllWalls(); + + for (unsigned int a = 0; a < allWalls.size(); a++) { + double x1 = allWalls[a].GetPoint1().GetX(); + double y1 = allWalls[a].GetPoint1().GetY(); + double x2 = allWalls[a].GetPoint2().GetX(); + double y2 = allWalls[a].GetPoint2().GetY(); + + double xmax = (x1 > x2) ? x1 : x2; + double xmin = (x1 > x2) ? x2 : x1; + double ymax = (y1 > y2) ? y1 : y2; + double ymin = (y1 > y2) ? y2 : y1; + + x_min = (xmin <= x_min) ? xmin : x_min; + x_max = (xmax >= x_max) ? xmax : x_max; + y_max = (ymax >= y_max) ? ymax : y_max; + y_min = (ymin <= y_min) ? ymin : y_min; + } + } + } + + //make the grid slightly larger. + x_min = x_min - 1*cellSize; + x_max = x_max + 1*cellSize; + y_min = y_min - 1*cellSize; + y_max = y_max + 1*cellSize; + + double boundaries[4] = { x_min, x_max, y_min, y_max }; + int pedsCount = _allPedestians.size(); + + //no algorithms + // the domain is made of a single cell + if(cellSize==-1) { + Log->Write("INFO: \tBrute Force will be used for neighborhoods query"); + if ( (x_max-x_min) < (y_max-y_min) ) { + cellSize=(y_max-y_min); + } else { + cellSize=(x_max-x_min); + } + + } else { + Log->Write("INFO: \tInitializing the grid with cell size: %f ", cellSize); + } + + _linkedCellGrid = new LCGrid(boundaries, cellSize, pedsCount); + _linkedCellGrid->ShallowCopy(_allPedestians); + + Log->Write("INFO: \tDone with Initializing the grid "); } - -void Building::LoadRoutingInfo(const string &filename) +bool Building::LoadRoutingInfo(const string &filename) { + Log->Write("INFO:\tLoading extra routing information"); + if (filename == "") { + Log->Write("INFO:\t No file supplied !"); + Log->Write("INFO:\t done with loading extra routing information"); + return true; + } + TiXmlDocument docRouting(filename); + if (!docRouting.LoadFile()) { + Log->Write("ERROR: \t%s", docRouting.ErrorDesc()); + Log->Write("ERROR: \t could not parse the routing file"); + return false; + } + + TiXmlElement* xRootNode = docRouting.RootElement(); + if( ! xRootNode ) { + Log->Write("ERROR:\tRoot element does not exist"); + return false; + } + + //load goals and routes + TiXmlNode* xGoalsNode = xRootNode->FirstChild("routing")->FirstChild("goals"); + + + if(xGoalsNode) + for(TiXmlElement* e = xGoalsNode->FirstChildElement("goal"); e; + e = e->NextSiblingElement("goal")) { + + int id = xmltof(e->Attribute("id"), -1); + int isFinal= string(e->Attribute("final"))=="true"?true:false; + string caption = xmltoa(e->Attribute("caption"),"-1"); + + Goal* goal = new Goal(); + goal->SetId(id); + goal->SetCaption(caption); + goal->SetIsFinalGoal(isFinal); + + //looking for polygons (walls) + for(TiXmlElement* xPolyVertices = e->FirstChildElement("polygon"); xPolyVertices; + xPolyVertices = xPolyVertices->NextSiblingElement("polygon")) { - - Log->Write("INFO:\tLoading extra routing information"); - if (filename == "") { - Log->Write("INFO:\t No file supplied !"); - Log->Write("INFO:\t done with loading extra routing information"); - return; - } - TiXmlDocument docRouting(filename); - if (!docRouting.LoadFile()) { - Log->Write("ERROR: \t%s", docRouting.ErrorDesc()); - Log->Write("ERROR: \t could not parse the routing file"); - exit(EXIT_FAILURE); - } - - TiXmlElement* xRootNode = docRouting.RootElement(); - if( ! xRootNode ) { - Log->Write("ERROR:\tRoot element does not exist"); - exit(EXIT_FAILURE); - } - - //load goals and routes - TiXmlNode* xGoalsNode = xRootNode->FirstChild("routing")->FirstChild("goals"); - - - if(xGoalsNode) - for(TiXmlElement* e = xGoalsNode->FirstChildElement("goal"); e; - e = e->NextSiblingElement("goal")) { - - int id = xmltof(e->Attribute("id"), -1); - int isFinal= string(e->Attribute("final"))=="true"?true:false; - string caption = xmltoa(e->Attribute("caption"),"-1"); - - Goal* goal = new Goal(); - goal->SetId(id); - goal->SetCaption(caption); - goal->SetIsFinalGoal(isFinal); - - //looking for polygons (walls) - for(TiXmlElement* xPolyVertices = e->FirstChildElement("polygon"); xPolyVertices; - xPolyVertices = xPolyVertices->NextSiblingElement("polygon")) { - - for (TiXmlElement* xVertex = xPolyVertices->FirstChildElement( - "vertex"); - xVertex && xVertex != xPolyVertices->LastChild("vertex"); - xVertex = xVertex->NextSiblingElement("vertex")) { - - double x1 = xmltof(xVertex->Attribute("px")); - double y1 = xmltof(xVertex->Attribute("py")); - double x2 = xmltof(xVertex->NextSiblingElement("vertex")->Attribute("px")); - double y2 = xmltof(xVertex->NextSiblingElement("vertex")->Attribute("py")); - goal->AddWall(Wall(Point(x1, y1), Point(x2, y2))); - } - } - - goal->ConvertLineToPoly(); - AddGoal(goal); - _routingEngine->AddFinalDestinationID(goal->GetId()); - } - - //load routes - TiXmlNode* xTripsNode = xRootNode->FirstChild("routing")->FirstChild("routes"); - - if(xTripsNode) - for(TiXmlElement* trip = xTripsNode->FirstChildElement("route"); trip; - trip = trip->NextSiblingElement("route")) { - - double id = xmltof(trip->Attribute("id"), -1); - if (id == -1) { - Log->Write("ERROR:\t id missing for trip"); - exit(EXIT_FAILURE); - } - string sTrip = trip->FirstChild()->ValueStr(); - vector<string> vTrip; - vTrip.clear(); - - char* str = (char*) sTrip.c_str(); - char *p = strtok(str, ":"); - while (p) { - vTrip.push_back(xmltoa(p)); - p = strtok(NULL, ":"); - } - _routingEngine->AddTrip(vTrip); - } - Log->Write("INFO:\tdone with loading extra routing information"); + for (TiXmlElement* xVertex = xPolyVertices->FirstChildElement( + "vertex"); + xVertex && xVertex != xPolyVertices->LastChild("vertex"); + xVertex = xVertex->NextSiblingElement("vertex")) { + + double x1 = xmltof(xVertex->Attribute("px")); + double y1 = xmltof(xVertex->Attribute("py")); + double x2 = xmltof(xVertex->NextSiblingElement("vertex")->Attribute("px")); + double y2 = xmltof(xVertex->NextSiblingElement("vertex")->Attribute("py")); + goal->AddWall(Wall(Point(x1, y1), Point(x2, y2))); + } + } + + if(!goal->ConvertLineToPoly()) + return false; + + AddGoal(goal); + _routingEngine->AddFinalDestinationID(goal->GetId()); + } + + //load routes + TiXmlNode* xTripsNode = xRootNode->FirstChild("routing")->FirstChild("routes"); + + if(xTripsNode) + for(TiXmlElement* trip = xTripsNode->FirstChildElement("route"); trip; + trip = trip->NextSiblingElement("route")) { + + double id = xmltof(trip->Attribute("id"), -1); + if (id == -1) { + Log->Write("ERROR:\t id missing for trip"); + return false; + } + string sTrip = trip->FirstChild()->ValueStr(); + vector<string> vTrip; + vTrip.clear(); + + char* str = (char*) sTrip.c_str(); + char *p = strtok(str, ":"); + while (p) { + vTrip.push_back(xmltoa(p)); + p = strtok(NULL, ":"); + } + _routingEngine->AddTrip(vTrip); + } + Log->Write("INFO:\tdone with loading extra routing information"); + return true; } -void Building::LoadTrafficInfo() +bool Building::LoadTrafficInfo() { - Log->Write("INFO:\tLoading the traffic info file"); - - string trafficFile=""; - TiXmlDocument doc(_projectFilename); - if (!doc.LoadFile()) { - Log->Write("ERROR: \t%s", doc.ErrorDesc()); - Log->Write("ERROR: \t could not parse the project file"); - exit(EXIT_FAILURE); - } - - TiXmlNode* xRootNode = doc.RootElement()->FirstChild("traffic_constraints"); - if( ! xRootNode ) { - Log->Write("WARNING:\tcould not find any traffic information"); - return; - //exit(EXIT_FAILURE); - } - - //processing the rooms node - TiXmlNode* xRoomsNode = xRootNode->FirstChild("rooms"); - if(xRoomsNode) - for(TiXmlElement* xRoom = xRoomsNode->FirstChildElement("room"); xRoom; - xRoom = xRoom->NextSiblingElement("room")) { - - double id = xmltof(xRoom->Attribute("room_id"), -1); - string state = xmltoa(xRoom->Attribute("state"), "good"); - RoomState status = (state == "good") ? ROOM_CLEAN : ROOM_SMOKED; - _rooms[id]->SetState(status); - } - - //processing the doors node - TiXmlNode* xDoorsNode = xRootNode->FirstChild("doors"); - if(xDoorsNode) - for(TiXmlElement* xDoor = xDoorsNode->FirstChildElement("door"); xDoor; - xDoor = xDoor->NextSiblingElement("door")) { - - int id = xmltoi(xDoor->Attribute("trans_id"), -1); - string state = xmltoa(xDoor->Attribute("state"), "open"); - - //store transition in a map and call getTransition/getCrossin - if (state == "open") { - GetTransition(id)->Open(); - } else if (state == "close") { - GetTransition(id)->Close(); - } else { - Log->Write("WARNING:\t Unknown door state: %s", state.c_str()); - } - } - Log->Write("INFO:\tDone with loading traffic info file"); + Log->Write("INFO:\tLoading the traffic info file"); + + string trafficFile=""; + TiXmlDocument doc(_projectFilename); + if (!doc.LoadFile()) { + Log->Write("ERROR: \t%s", doc.ErrorDesc()); + Log->Write("ERROR: \t could not parse the project file"); + return false; + } + + TiXmlNode* xRootNode = doc.RootElement()->FirstChild("traffic_constraints"); + if( ! xRootNode ) { + Log->Write("WARNING:\tcould not find any traffic information"); + return true; + } + + //processing the rooms node + TiXmlNode* xRoomsNode = xRootNode->FirstChild("rooms"); + if(xRoomsNode) + for(TiXmlElement* xRoom = xRoomsNode->FirstChildElement("room"); xRoom; + xRoom = xRoom->NextSiblingElement("room")) { + + double id = xmltof(xRoom->Attribute("room_id"), -1); + string state = xmltoa(xRoom->Attribute("state"), "good"); + RoomState status = (state == "good") ? ROOM_CLEAN : ROOM_SMOKED; + GetRoom(id)->SetState(status); + } + + //processing the doors node + TiXmlNode* xDoorsNode = xRootNode->FirstChild("doors"); + if(xDoorsNode) + for(TiXmlElement* xDoor = xDoorsNode->FirstChildElement("door"); xDoor; + xDoor = xDoor->NextSiblingElement("door")) { + + int id = xmltoi(xDoor->Attribute("trans_id"), -1); + string state = xmltoa(xDoor->Attribute("state"), "open"); + + //store transition in a map and call getTransition/getCrossin + if (state == "open") { + GetTransition(id)->Open(); + } else if (state == "close") { + GetTransition(id)->Close(); + } else { + Log->Write("WARNING:\t Unknown door state: %s", state.c_str()); + } + } + Log->Write("INFO:\tDone with loading traffic info file"); + return true; } -void Building::DeletePedestrian(Pedestrian* ped) +void Building::DeletePedestrian(Pedestrian* &ped) { - vector<Pedestrian*>::iterator it; - it = find(_allPedestians.begin(), _allPedestians.end(), ped); - if (it == _allPedestians.end()) { - Log->Write ("\tINFO: \tPed not found with ID %d ",ped->GetID()); - //FIXME: the pedestrians should always exists. check this in connection with the mesh router. - return; - } else { - //save the path history for this pedestrian before removing from the simulation - if (_savePathway) { - string results; - string path = (*it)->GetPath(); - vector<string> brokenpaths; - StringExplode(path, ">", &brokenpaths); - for (unsigned int i = 0; i < brokenpaths.size(); i++) { - vector<string> tags; - StringExplode(brokenpaths[i], ":", &tags); - string room = _rooms[atoi(tags[0].c_str())]->GetCaption(); - string trans =GetTransition(atoi(tags[1].c_str()))->GetCaption(); - //ignore crossings/hlines - if (trans != "") - _pathWayStream << room << " " << trans << endl; - } - - } - cout << "rescued agent: " << (*it)->GetID() << endl; - _allPedestians.erase(it); - } - delete ped; -} - -void Building::DeletePedFromSim(Pedestrian* ped) -{ - SubRoom* sub = _rooms[ped->GetRoomID()]->GetSubRoom(ped->GetSubRoomID()); - for (int p = 0; p < sub->GetNumberOfPedestrians(); p++) { - if (sub->GetPedestrian(p)->GetID() == ped->GetID()) { - sub->DeletePedestrian(p); - DeletePedestrian(ped); - return; - } - } + vector<Pedestrian*>::iterator it; + it = find(_allPedestians.begin(), _allPedestians.end(), ped); + if (it == _allPedestians.end()) { + Log->Write ("\tERROR: \tPed not found with ID %d ",ped->GetID()); + exit(EXIT_FAILURE); + return; + } else { + // save the path history for this pedestrian before removing from the simulation + if (_savePathway) { + string results; + string path = (*it)->GetPath(); + vector<string> brokenpaths; + StringExplode(path, ">", &brokenpaths); + for (unsigned int i = 0; i < brokenpaths.size(); i++) { + vector<string> tags; + StringExplode(brokenpaths[i], ":", &tags); + string room = _rooms[atoi(tags[0].c_str())]->GetCaption(); + string trans =GetTransition(atoi(tags[1].c_str()))->GetCaption(); + //ignore crossings/hlines + if (trans != "") + _pathWayStream << room << " " << trans << endl; + } + + } + //cout << "rescued agent: " << (*it)->GetID()<<endl; + + static int totalPeds= _allPedestians.size(); + _allPedestians.erase(it); + + int nowPeds= _allPedestians.size(); + //if((*it)->GetID()==69){ + //cout << "rescued agent: " << (*it)->GetID()<<endl; + //cout << "want to rescue agent: " << ped->GetID()<<endl<<endl; + // exit(0); + // } + Log->ProgressBar(totalPeds, totalPeds-nowPeds); + } + //update the stats before deleting + Transition* trans =GetTransitionByUID(ped->GetExitIndex()); + if(trans) { + trans->IncreaseDoorUsage(1, ped->GetGlobalTime()); + } + delete ped; } const vector<Pedestrian*>& Building::GetAllPedestrians() const { - return _allPedestians; + return _allPedestians; } void Building::AddPedestrian(Pedestrian* ped) { - - // for(unsigned int p = 0;p<pAllPedestians.size();p++){ - // Pedestrian* ped1=pAllPedestians[p]; - // if(ped->GetPedIndex()==ped1->GetPedIndex()){ - // cout<<"Pedestrian already in the room ??? "<<ped->GetPedIndex()<<endl; - // return; - // } - // } - _allPedestians.push_back(ped); + for(unsigned int p = 0;p<_allPedestians.size();p++){ + Pedestrian* ped1=_allPedestians[p]; + if(ped->GetID()==ped1->GetID()){ + cout<<"Pedestrian already in the room ??? "<<ped->GetID()<<endl; + return; + } + } + _allPedestians.push_back(ped); } - -//obsolete -void Building::InitSavePedPathway(const string &filename) +void Building::GetPedestrians(int room, int subroom, std::vector<Pedestrian*>& peds) { - _pathWayStream.open(filename.c_str()); - _savePathway = true; - - if (_pathWayStream.is_open()) { - Log->Write("#INFO:\tsaving pedestrian paths to [ " + filename + " ]"); - _pathWayStream << "##pedestrian ways" << endl; - _pathWayStream << "#nomenclature roomid caption" << endl; - // for (unsigned int r=0;r< pRooms.size();r++){ - // Room* room= GetRoom(r); - // const vector<int>& goals=room->GetAllTransitionsIDs(); - // - // for(unsigned int g=0;g<goals.size();g++){ - // int exitid=goals[g]; - // string exit_caption=pRouting->GetGoal(exitid)->GetCaption(); - // PpathWayStream<<exitid<<" "<<exit_caption<<endl; - // } - // } - // - _pathWayStream << "#data room exit_id" << endl; - } else { - Log->Write("#INFO:\t Unable to open [ " + filename + " ]"); - Log->Write("#INFO:\t saving to stdout"); - - } + for(unsigned int p = 0;p<_allPedestians.size();p++){ + Pedestrian* ped=_allPedestians[p]; + if(room==ped->GetRoomID() && subroom==ped->GetSubRoomID()) + { + peds.push_back(ped); + } + } } -void Building::CleanUpTheScene() +//obsolete +void Building::InitSavePedPathway(const string &filename) { - //return; - static int counter = 0; - counter++; - static int totalSliced = 0; - - int updateRate = 80.0 / 0.01; // 20 seconds/pDt - - if (counter % updateRate == 0) { - for (unsigned int i = 0; i < _allPedestians.size(); i++) { - Pedestrian* ped = _allPedestians[i]; - - if (ped->GetDistanceSinceLastRecord() < 0.1) { - //delete from the simulation - DeletePedFromSim(ped); - - totalSliced++; - char msg[CLENGTH]; - sprintf(msg, "INFO:\t slicing Ped %d from room %s, total [%d]", - ped->GetID(), - _rooms[ped->GetRoomID()]->GetCaption().c_str(), - totalSliced); - Log->Write(msg); - } else { - ped->RecordActualPosition(); - } - - } - } - + _pathWayStream.open(filename.c_str()); + _savePathway = true; + + if (_pathWayStream.is_open()) { + Log->Write("#INFO:\tsaving pedestrian paths to [ " + filename + " ]"); + _pathWayStream << "##pedestrian ways" << endl; + _pathWayStream << "#nomenclature roomid caption" << endl; + // for (unsigned int r=0;r< pRooms.size();r++){ + // Room* room= GetRoom(r); + // const vector<int>& goals=room->GetAllTransitionsIDs(); + // + // for(unsigned int g=0;g<goals.size();g++){ + // int exitid=goals[g]; + // string exit_caption=pRouting->GetGoal(exitid)->GetCaption(); + // PpathWayStream<<exitid<<" "<<exit_caption<<endl; + // } + // } + // + _pathWayStream << "#data room exit_id" << endl; + } else { + Log->Write("#INFO:\t Unable to open [ " + filename + " ]"); + Log->Write("#INFO:\t saving to stdout"); + + } } void Building::StringExplode(string str, string separator, vector<string>* results) { - size_t found; - found = str.find_first_of(separator); - while (found != string::npos) { - if (found > 0) { - results->push_back(str.substr(0, found)); - } - str = str.substr(found + 1); - found = str.find_first_of(separator); - } - if (str.length() > 0) { - results->push_back(str); - } + size_t found; + found = str.find_first_of(separator); + while (found != string::npos) { + if (found > 0) { + results->push_back(str.substr(0, found)); + } + str = str.substr(found + 1); + found = str.find_first_of(separator); + } + if (str.length() > 0) { + results->push_back(str); + } } Pedestrian* Building::GetPedestrian(int pedID) const { - for (unsigned int i = 0; i < _rooms.size(); i++) { - Room* room = _rooms[i]; - for (int j = 0; j < room->GetNumberOfSubRooms(); j++) { - SubRoom* sub = room->GetSubRoom(j); - for (int k = 0; k < sub->GetNumberOfPedestrians(); k++) { - Pedestrian* p = sub->GetPedestrian(k); - if (p->GetID() == pedID) { - return p; - } - } - } - } - return NULL; + for(unsigned int p=0;p<_allPedestians.size();p++) + { + Pedestrian* ped = _allPedestians[p]; + if (ped->GetID() == pedID) { + return ped; + } + } + + return NULL; } int Building::GetNumberOfPedestrians() const { - int sum = 0; - for (unsigned int wa = 0; wa < _rooms.size(); wa++) { - sum += _rooms[wa]->GetNumberOfPedestrians(); - } - return sum; + return _allPedestians.size(); +} + +Transition* Building::GetTransitionByUID(int uid) const +{ + //eventually + map<int, Transition*>::const_iterator itr; + for(itr = _transitions.begin(); itr != _transitions.end(); ++itr) { + if (itr->second->GetUniqueID()== uid) + return itr->second; + } + return NULL; } -// FIXME: you should get rid of this method -//Crossing* Building::GetGoal(int index) { -// if (_transitions.count(index) == 1) { -// return _transitions[index]; -// } else if (_crossings.count(index) == 1) { -// return _crossings[index]; -// }else if (_hLines.count(index) == 1) { -// exit(EXIT_FAILURE); -// //return pHlines[index]; -// }else { -// if (index == -1) -// return NULL; -// else { -// char tmp[CLENGTH]; -// sprintf(tmp, -// "ERROR: Wrong 'index' [%d] > [%d] in Routing::GetGoal(), counts in map= [%d]", -// index, _crossings.size(),_crossings.count(index)); -// Log->Write(tmp); -// exit(EXIT_FAILURE); -// } -// } -//} +bool Building::SaveGeometry(const std::string &filename) +{ + std::stringstream geometry; + + //write the header + geometry<< "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>"<<endl; + geometry<< "<geometry version=\"0.5\" caption=\"second life\" unit=\"m\"\n " + " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n " + " xsi:noNamespaceSchemaLocation=\"http://134.94.2.137/jps_geoemtry.xsd\">"<<endl<<endl; + + //write the rooms + geometry<<"<rooms>"<<endl; + for (Room* room : _rooms) + { + geometry<<"\t<room id =\""<<room->GetID()<<"\" caption =\""<<room->GetCaption()<<"\">"<<endl; + const vector<SubRoom*>& allSubs=room->GetAllSubRooms(); + for(SubRoom* sub : allSubs) + { + const double* plane=sub->GetPlaneEquation(); + geometry<<"\t\t<subroom id =\""<<sub->GetSubRoomID() + <<"\" closed=\""<<sub->GetClosed() + <<"\" class=\""<<sub->GetType() + <<"\" A_x=\""<<plane[0] + <<"\" B_y=\""<<plane[1] + <<"\" C_z=\""<<plane[2]<<"\">"<<endl; + + const vector<Wall>& walls=sub->GetAllWalls(); + + for (Wall wall : walls) + { + const Point& p1=wall.GetPoint1(); + const Point& p2=wall.GetPoint2(); + + geometry<<"\t\t\t<polygon caption=\"wall\" type=\""<<wall.GetType()<<"\">"<<endl + <<"\t\t\t\t<vertex px=\""<<p1._x<<"\" py=\""<<p1._y<<"\"/>"<<endl + <<"\t\t\t\t<vertex px=\""<<p2._x<<"\" py=\""<<p2._y<<"\"/>"<<endl + <<"\t\t\t</polygon>"<<endl; + } + + if(sub->GetType()=="stair") + { + const Point& up = ((Stair*)sub)->GetUp(); + const Point& down = ((Stair*)sub)->GetDown(); + geometry<<"\t\t\t<up px=\""<<up._x<<"\" py=\""<<up._y<<"\"/>"<<endl; + geometry<<"\t\t\t<down px=\""<<down._x<<"\" py=\""<<down._y<<"\"/>"<<endl; + } + + geometry<<"\t\t</subroom>"<<endl; + } + + //write the crossings + geometry<<"\t\t<crossings>"<<endl; + for (auto const& mapcross : _crossings) + { + Crossing* cross=mapcross.second; + + //only write the crossings in this rooms + if(cross->GetRoom1()->GetID()!=room->GetID()) continue; + + const Point& p1=cross->GetPoint1(); + const Point& p2=cross->GetPoint2(); + + geometry<<"\t<crossing id =\""<<cross->GetID() + <<"\" subroom1_id=\""<<cross->GetSubRoom1()->GetSubRoomID() + <<"\" subroom2_id=\""<<cross->GetSubRoom2()->GetSubRoomID()<<"\">"<<endl; + + geometry<<"\t\t<vertex px=\""<<p1._x<<"\" py=\""<<p1._y<<"\"/>"<<endl + <<"\t\t<vertex px=\""<<p2._x<<"\" py=\""<<p2._y<<"\"/>"<<endl + <<"\t</crossing>"<<endl; + } + geometry<<"\t\t</crossings>"<<endl; + geometry<<"\t</room>"<<endl; + } + + geometry<<"</rooms>"<<endl; + + //write the transitions + geometry<<"<transitions>"<<endl; + + for (auto const& maptrans : _transitions) + { + Transition* trans=maptrans.second; + const Point& p1=trans->GetPoint1(); + const Point& p2=trans->GetPoint2(); + int room2_id=-1; + int subroom2_id=-1; + if(trans->GetRoom2()) + { + room2_id=trans->GetRoom2()->GetID(); + subroom2_id=trans->GetSubRoom2()->GetSubRoomID(); + } + + geometry<<"\t<transition id =\""<<trans->GetID() + <<"\" caption=\""<<trans->GetCaption() + <<"\" type=\""<<trans->GetType() + <<"\" room1_id=\""<<trans->GetRoom1()->GetID() + <<"\" subroom1_id=\""<<trans->GetSubRoom1()->GetSubRoomID() + <<"\" room2_id=\""<<room2_id + <<"\" subroom2_id=\""<<subroom2_id<<"\">"<<endl; + + geometry<<"\t\t<vertex px=\""<<p1._x<<"\" py=\""<<p1._y<<"\"/>"<<endl + <<"\t\t<vertex px=\""<<p2._x<<"\" py=\""<<p2._y<<"\"/>"<<endl + <<"\t</transition>"<<endl; + + } + + geometry<<"</transitions>"<<endl; + geometry<<"</geometry>"<<endl; + //write the routing file + + //cout<<endl<<geometry.str()<<endl; + + ofstream geofile (filename); + if(geofile.is_open()) + { + geofile<<geometry.str(); + } + else + { + Log->Write("ERROR:\tunable to save the geometry to %s",filename.c_str()); + return false; + } + + return true; +} #endif // _SIMULATOR diff --git a/src/geometry/Building.h b/src/geometry/Building.h index c7ba1bba78e0167a23a535c9a551a4337efe5cbd..006ae966b2d6c7aea56a18efc62f774ad002138e 100644 --- a/src/geometry/Building.h +++ b/src/geometry/Building.h @@ -1,14 +1,14 @@ /** - * File: Building.h + * \file Building.h + * \date Oct 1, 2010 + * \version v0.5 + * \copyright <2009-2014> Forschungszentrum Jülich GmbH. All rights reserved. * - * - * Created on 1. October 2010, 09:25 - * - * @section LICENSE + * \section License * This file is part of JuPedSim. * * JuPedSim is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by + * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * @@ -17,17 +17,17 @@ * 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 + * You should have received a copy of the GNU Lesser General Public License * along with JuPedSim. If not, see <http://www.gnu.org/licenses/>. * - * @section DESCRIPTION + * \section Description * * - * - */ + **/ + #ifndef _BUILDING_H -#define _BUILDING_H +#define _BUILDING_H #include <string> #include <vector> @@ -46,152 +46,177 @@ class RoutingEngine; class Pedestrian; class Transition; class LCGrid; +class ForceModel; class Building { private: - std::string _caption; - std::string _projectFilename; - std::string _projectRootDir; - RoutingEngine* _routingEngine; - LCGrid* _linkedCellGrid; - std::vector<Room*> _rooms; - std::vector<Pedestrian*> _allPedestians; - - std::map<int, Crossing*> _crossings; - std::map<int, Transition*> _transitions; - std::map<int, Hline*> _hLines; - std::map<int, Goal*>_goals; - - /// pedestrians pathway - bool _savePathway; - std::ofstream _pathWayStream; + + std::string _caption; + std::string _projectFilename; + std::string _projectRootDir; + std::string _geometryFilename; + RoutingEngine* _routingEngine; + LCGrid* _linkedCellGrid; + std::vector<Room*> _rooms; + std::vector<Pedestrian*> _allPedestians; + + std::map<int, Crossing*> _crossings; + std::map<int, Transition*> _transitions; + std::map<int, Hline*> _hLines; + std::map<int, Goal*>_goals; + + /// pedestrians pathway + bool _savePathway; + std::ofstream _pathWayStream; public: - /// constructor - Building(); - /// destructor - virtual ~Building(); - - - void SetCaption(const std::string& s); - void SetRoutingEngine(RoutingEngine* r); - void SetRoom(Room* room, int index); - /// delete the ped from the ped vector - void DeletePedestrian(Pedestrian* ped); - /// delete the ped from the simulation - void DeletePedFromSim(Pedestrian* ped); - void AddPedestrian(Pedestrian* ped); - - - std::string GetCaption() const; - RoutingEngine* GetRoutingEngine() const; - const std::vector<Room*>& GetAllRooms() const; - const std::vector<Pedestrian*>& GetAllPedestrians() const; - Pedestrian* GetPedestrian( int pedID) const; - int GetNumberOfRooms() const; - int GetNumberOfGoals()const; - Room* GetRoom(int index) const; - Room* GetRoom(std::string caption)const; - - //TODO: implement the same methods for Crossings and Hlines - Transition* GetTransition(std::string caption) const; - Transition* GetTransition(int id) ; - - /** - * Not implemented - */ - Crossing* GetCrossing(int id); - - /** - * Not implemented - */ - Hline* GetHline(int id); - - /** - * @return true if the two segments are visible from each other. - * Alls walls and transitions and crossings are used in this check. - * The use of hlines is optional, because they are not real, can can be considered transparent - */ - bool IsVisible(Line* l1, Line* l2, bool considerHlines=false); - - /** - * @return true if the two points are visible from each other. - * Alls walls and transitions and crossings are used in this check. - * The use of hlines is optional, because they are not real, can be considered transparent - */ - bool IsVisible(const Point& p1, const Point& p2, bool considerHlines=false); - - - /** - * @return a crossing or a transition matching the given caption. - * Return NULL if none is found - */ - Crossing* GetTransOrCrossByName(std::string caption) const; - - - /** - * @return a crossing or a transition matching the given id. - * Return NULL if none is found - */ - Crossing* GetTransOrCrossByID(int id) const; - - - //TOD0: rename later to GetGoal - Goal* GetFinalGoal(int id); - - int GetNumberOfPedestrians() const; - - /** - * @return the linked-cell grid used for spatial query - */ - LCGrid* GetGrid() const; - - // Sonstiges - bool InitGeometry(); - void InitGrid(double cellSize); - //void InitRoomsAndSubroomsMap(); - void InitPhiAllPeds(double pDt); // initialize the direction of the ellipses - void InitSavePedPathway(const std::string &filename); - void AddRoom(Room* room); - void Update(); - void UpdateVerySlow(); - void UpdateGrid(); - void AddSurroundingRoom(); // add a final room (outside or world), that encompasses the complete geometry - void DumpSubRoomInRoom(int roomID, int subID); - - const std::map<int, Crossing*>& GetAllCrossings() const; - const std::map<int, Transition*>& GetAllTransitions() const; - const std::map<int, Hline*>& GetAllHlines() const; - const std::map<int, Goal*>& GetAllGoals() const; - - void AddCrossing(Crossing* line); - void AddTransition(Transition* line); - void AddHline(Hline* line); - void AddGoal(Goal* goal); - - const std::string& GetProjectRootDir() const; - const std::string& GetProjectFilename() const; - void SetProjectFilename(const std::string &filename) ; - void SetProjectRootDir(const std::string &filename); - bool LoadBuildingFromFile(const std::string &filename=""); - void LoadTrafficInfo(); - void LoadRoutingInfo(const std::string &filename); - void WriteToErrorLog() const; - - void CleanUpTheScene(); - - /** - * Check the scenario for possible errors and - * output user specific informations. - */ - void SanityCheck(); + /// constructor + Building(); + /// destructor + virtual ~Building(); + + + void SetCaption(const std::string& s); + void SetRoutingEngine(RoutingEngine* r); + void SetRoom(Room* room, int index); + + /// delete the ped from the ped vector + void DeletePedestrian(Pedestrian* &ped); + /// delete the ped from the simulation + void AddPedestrian(Pedestrian* ped); + void GetPedestrians(int room, int subroom, std::vector<Pedestrian*>& peds); + + + std::string GetCaption() const; + RoutingEngine* GetRoutingEngine() const; + const std::vector<Room*>& GetAllRooms() const; + const std::vector<Pedestrian*>& GetAllPedestrians() const; + Pedestrian* GetPedestrian( int pedID) const; + int GetNumberOfRooms() const; + int GetNumberOfGoals()const; + Room* GetRoom(int index) const; + Room* GetRoom(std::string caption)const; + + Transition* GetTransition(std::string caption) const; + Transition* GetTransition(int id) ; + + /** + * Not implemented + */ + Crossing* GetCrossing(int id); + + /** + * Not implemented + */ + Hline* GetHline(int id); + + /** + * return the subroom with the corresponding unique identifier + * @param uid ,the unique identifier + * @return NULL if no exists with that identifier. + */ + SubRoom* GetSubRoomByUID( int uid); + + /** + * @return true if the two segments are visible from each other. + * Alls walls and transitions and crossings are used in this check. + * The use of hlines is optional, because they are not real, can can be considered transparent + */ + bool IsVisible(Line* l1, Line* l2, bool considerHlines=false); + + /** + * @return true if the two points are visible from each other. + * Alls walls and transitions and crossings are used in this check. + * The use of hlines is optional, because they are not real, can be considered transparent + */ + bool IsVisible(const Point& p1, const Point& p2, bool considerHlines=false); + + + /** + * @return a crossing or a transition matching the given caption. + * Return NULL if none is found + */ + Crossing* GetTransOrCrossByName(std::string caption) const; + + + /** + * @return a crossing or a transition or a hline matching the given uid. + * Return NULL if none is found + */ + Hline* GetTransOrCrossByUID(int uid) const; + + + /** + * @return the transition matching the uid + */ + Transition* GetTransitionByUID(int uid) const; + + //TOD0: rename later to GetGoal + Goal* GetFinalGoal(int id); + + int GetNumberOfPedestrians() const; + + /** + * @return the linked-cell grid used for spatial query + */ + LCGrid* GetGrid() const; + + // convenience methods + bool InitGeometry(); + void InitGrid(double cellSize); + //void InitRoomsAndSubroomsMap(); + void InitSavePedPathway(const std::string &filename); + void AddRoom(Room* room); + void UpdateGrid(); + void AddSurroundingRoom(); // add a final room (outside or world), that encompasses the complete geometry + + const std::map<int, Crossing*>& GetAllCrossings() const; + const std::map<int, Transition*>& GetAllTransitions() const; + const std::map<int, Hline*>& GetAllHlines() const; + const std::map<int, Goal*>& GetAllGoals() const; + + void AddCrossing(Crossing* line); + void AddTransition(Transition* line); + void AddHline(Hline* line); + void AddGoal(Goal* goal); + + const std::string& GetProjectRootDir() const; + const std::string& GetProjectFilename() const; + const std::string& GetGeometryFilename() const; + void SetProjectFilename(const std::string &filename) ; + void SetProjectRootDir(const std::string &filename); + + /** + * Load and parse the geometry file into the building object. + * If no geometry file is provided, one is searched in the the project file + * + * @param filename, the geometry file + */ + bool LoadGeometry(const std::string &geometryfile=""); + + /** + * Write the geometry to the given file. + * That will be useful in the geometry editor. + * @param filename the relative location of the file + * @return true if everything went fine. + */ + bool SaveGeometry(const std::string &filename); + + bool LoadTrafficInfo(); + bool LoadRoutingInfo(const std::string &filename); + void WriteToErrorLog() const; + + /** + * Check the scenario for possible errors and + * output user specific informations. + */ + bool SanityCheck(); private: - void StringExplode(std::string str, std::string separator, std::vector<std::string>* results); + void StringExplode(std::string str, std::string separator, std::vector<std::string>* results); }; -#endif /* _BUILDING_H */ - +#endif /* _BUILDING_H */ diff --git a/src/geometry/Crossing.cpp b/src/geometry/Crossing.cpp index 08f238d7e1e690fa91556f243217e11ac42c8838..c75a29d035512c0934333a9f9c43a5e4181a3384 100644 --- a/src/geometry/Crossing.cpp +++ b/src/geometry/Crossing.cpp @@ -1,14 +1,14 @@ /** - * File: Crossing.cpp + * \file Crossing.cpp + * \date Nov 16, 2010 + * \version v0.5 + * \copyright <2009-2014> Forschungszentrum Jülich GmbH. All rights reserved. * - * - * Created on 16. November 2010, 12:56 - * - * @section LICENSE + * \section License * This file is part of JuPedSim. * * JuPedSim is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by + * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * @@ -17,15 +17,13 @@ * 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 + * You should have received a copy of the GNU Lesser General Public License * along with JuPedSim. If not, see <http://www.gnu.org/licenses/>. * - * @section DESCRIPTION - * + * \section Description * * - * - */ + **/ #include "Crossing.h" @@ -37,11 +35,11 @@ using namespace std; Crossing::Crossing() { - _id = -1; - _room1 = NULL; - _subRoom1 = NULL; - _subRoom2 = NULL; - _caption = ""; + _id = -1; + _room1 = NULL; + _subRoom1 = NULL; + _subRoom2 = NULL; + _caption = ""; } Crossing::~Crossing() @@ -51,91 +49,91 @@ Crossing::~Crossing() void Crossing::SetID(int ID) { - _id = ID; + _id = ID; } void Crossing::SetRoom1(Room* r) { - _room1 = r; + _room1 = r; } void Crossing::SetSubRoom1(SubRoom* r1) { - _subRoom1 = r1; + _subRoom1 = r1; } void Crossing::SetSubRoom2(SubRoom* r2) { - _subRoom2 = r2; + _subRoom2 = r2; } void Crossing::SetCaption(string s) { - _caption = s; + _caption = s; } // Getter-Funktionen int Crossing::GetID() const { - return _id; + return _id; } string Crossing::GetCaption() const { - return _caption; + return _caption; } Room* Crossing::GetRoom1() const { - return _room1; + return _room1; } SubRoom* Crossing::GetSubRoom1() const { - return _subRoom1; + return _subRoom1; } SubRoom* Crossing::GetSubRoom2() const { - return _subRoom2; + return _subRoom2; } // Sonstiges bool Crossing::IsExit() const { - return false; + return false; } bool Crossing::IsOpen() const { - return true; + return true; } bool Crossing::IsTransition() const { - return false; + return false; } bool Crossing::IsInRoom(int roomID) const { - return _room1->GetID() == roomID; + return _room1->GetID() == roomID; } bool Crossing::IsInSubRoom(int subroomID) const { - bool r1, r2; - if (_subRoom1 != NULL) - r1 = _subRoom1->GetSubRoomID() == subroomID; - else - r1 = false; - if (_subRoom2 != NULL) - r2 = _subRoom2->GetSubRoomID() == subroomID; - else - r2 = false; - return (r1 || r2); + bool r1, r2; + if (_subRoom1 != NULL) + r1 = _subRoom1->GetSubRoomID() == subroomID; + else + r1 = false; + if (_subRoom2 != NULL) + r2 = _subRoom2->GetSubRoomID() == subroomID; + else + r2 = false; + return (r1 || r2); } /* gibt den ANDEREN Subroom != subroomID zurück @@ -143,15 +141,15 @@ bool Crossing::IsInSubRoom(int subroomID) const * (virtuelle Funktion) */ SubRoom* Crossing::GetOtherSubRoom(int roomID, int subroomID) const { - if (_subRoom1->GetSubRoomID() == subroomID) - return _subRoom2; - else if (_subRoom2->GetSubRoomID() == subroomID) - return _subRoom1; - else { - Log->Write("WARMING: \tCrossing::GetOtherSubRoom No exit found " - "on the other side\n ID=%hd, roomID=%hd, subroomID=%hd\n",GetID(),roomID,subroomID); - return NULL; - } + if (_subRoom1->GetSubRoomID() == subroomID) + return _subRoom2; + else if (_subRoom2->GetSubRoomID() == subroomID) + return _subRoom1; + else { + Log->Write("WARMING: \tCrossing::GetOtherSubRoom No exit found " + "on the other side\n ID=%hd, roomID=%hd, subroomID=%hd\n",GetID(),roomID,subroomID); + return NULL; + } } @@ -159,37 +157,36 @@ SubRoom* Crossing::GetOtherSubRoom(int roomID, int subroomID) const void Crossing::WriteToErrorLog() const { - string s; - char tmp[CLENGTH]; - sprintf(tmp, "\t\tCROSS: %d (%f, %f) -- (%f, %f)\n", GetID(), GetPoint1().GetX(), - GetPoint1().GetY(), GetPoint2().GetX(), GetPoint2().GetY()); - s.append(tmp); - sprintf(tmp, "\t\t\t\tSubRoom: %d <-> SubRoom: %d\n", GetSubRoom1()->GetSubRoomID(), - GetSubRoom2()->GetSubRoomID()); - s.append(tmp); - Log->Write(s); + string s; + char tmp[CLENGTH]; + sprintf(tmp, "\t\tCROSS: %d (%f, %f) -- (%f, %f)\n", GetID(), GetPoint1().GetX(), + GetPoint1().GetY(), GetPoint2().GetX(), GetPoint2().GetY()); + s.append(tmp); + sprintf(tmp, "\t\t\t\tSubRoom: %d <-> SubRoom: %d\n", GetSubRoom1()->GetSubRoomID(), + GetSubRoom2()->GetSubRoomID()); + s.append(tmp); + Log->Write(s); } // TraVisTo Ausgabe - string Crossing::WriteElement() const { - //return ""; - string geometry; - char tmp[CLENGTH] = ""; - sprintf(tmp,"\t\t<door ID=\"%d\" color = \"250\" caption=\"%d_%d\">\n",GetUniqueID(),GetID(),GetUniqueID()); - geometry.append(tmp); - //geometry.append("\t\t<door color=\"250\">\n"); - sprintf(tmp, "\t\t\t<point xPos=\"%.2f\" yPos=\"%.2f\" zPos=\"%.2f\" />\n", - (GetPoint1().GetX()) * FAKTOR, - (GetPoint1().GetY()) * FAKTOR, - _subRoom1->GetElevation(GetPoint1())*FAKTOR); - geometry.append(tmp); - sprintf(tmp, "\t\t\t<point xPos=\"%.2f\" yPos=\"%.2f\" zPos=\"%.2f\" />\n", - (GetPoint2().GetX()) * FAKTOR, - (GetPoint2().GetY()) * FAKTOR, - _subRoom1->GetElevation(GetPoint2())*FAKTOR); - geometry.append(tmp); - geometry.append("\t\t</door>\n"); - return geometry; + //return ""; + string geometry; + char tmp[CLENGTH] = ""; + sprintf(tmp,"\t\t<crossing ID=\"%d\" color = \"250\" caption=\"%d_%d\">\n",GetUniqueID(),GetID(),GetUniqueID()); + geometry.append(tmp); + //geometry.append("\t\t<door color=\"250\">\n"); + sprintf(tmp, "\t\t\t<point xPos=\"%.2f\" yPos=\"%.2f\" zPos=\"%.2f\" />\n", + (GetPoint1().GetX()) * FAKTOR, + (GetPoint1().GetY()) * FAKTOR, + _subRoom1->GetElevation(GetPoint1())*FAKTOR); + geometry.append(tmp); + sprintf(tmp, "\t\t\t<point xPos=\"%.2f\" yPos=\"%.2f\" zPos=\"%.2f\" />\n", + (GetPoint2().GetX()) * FAKTOR, + (GetPoint2().GetY()) * FAKTOR, + _subRoom1->GetElevation(GetPoint2())*FAKTOR); + geometry.append(tmp); + geometry.append("\t\t</crossing>\n"); + return geometry; } diff --git a/src/geometry/Crossing.h b/src/geometry/Crossing.h index 1d90365400aa4e5923f6f26fb0447c2d6bf6affe..77d066fc24461087b0d417fb3f89ec38020e79dd 100644 --- a/src/geometry/Crossing.h +++ b/src/geometry/Crossing.h @@ -1,14 +1,14 @@ /** - * File: Crossing.h + * \file Crossing.h + * \date Nov 16, 2010 + * \version v0.5 + * \copyright <2009-2014> Forschungszentrum Jülich GmbH. All rights reserved. * - * - * Created on 16. November 2010, 12:56 - * - * @section LICENSE + * \section License * This file is part of JuPedSim. * * JuPedSim is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by + * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * @@ -17,131 +17,132 @@ * 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 + * You should have received a copy of the GNU Lesser General Public License * along with JuPedSim. If not, see <http://www.gnu.org/licenses/>. * - * @section DESCRIPTION - * + * \section Description * * - */ + **/ + #ifndef _CROSSING_H -#define _CROSSING_H +#define _CROSSING_H #include "NavLine.h" +#include "Hline.h" //class Line; class Room; class SubRoom; -class Crossing : public NavLine { +class Crossing : public Hline { private: - /// ? unique between crossings and transitions ? - int _id; - /// only one room needed, since a crossing only separates 2 subrooms - Room* _room1; - std::string _caption; - SubRoom* _subRoom1; - SubRoom* _subRoom2; + /// ? unique between crossings and transitions ? + int _id; + /// only one room needed, since a crossing only separates 2 subrooms + Room* _room1; + std::string _caption; + SubRoom* _subRoom1; + SubRoom* _subRoom2; public: - Crossing(); - virtual ~Crossing(); - - /** - * Set/Get the Id of the crossing - */ - void SetID(int ID); - - /** - * Set/Get the Id of the crossing - */ - int GetID () const; - - /** - * Set/Get the first room - */ - void SetRoom1(Room* r); - - /** - * Set/Get the crossing caption - */ - void SetCaption(std::string s); - - /** - * Set/Get the first subroom - */ - void SetSubRoom1(SubRoom* r1); - - /** - * Set/Get the second subroom - */ - void SetSubRoom2(SubRoom* r2); - - /** - * Set/Get the crossing caption - */ - std::string GetCaption() const; - - /** - * Set/Get the first room - */ - Room* GetRoom1() const; - - /** - * Set/Get the first subroom - */ - SubRoom* GetSubRoom1() const; - - /** - * Set/Get the second subroom - */ - SubRoom* GetSubRoom2() const; - - /** - * \return true if the subroomID is associated with the current crossing - */ - bool IsInSubRoom(int subroomID) const; - - - /** - * @return true if the crossing is open = passable - */ - virtual bool IsOpen() const; - - /** - * @return true if the crossing is an exit/transition. (Transitions are derived from this class) - * @see Transition - */ - virtual bool IsExit() const; - - /** - * - * @return true if it is a transition - */ - virtual bool IsTransition() const; - - /** - * @return true if the crossing/transintion/hline is associated with the room - */ - virtual bool IsInRoom(int roomID) const; - - /** - * @return the other subroom not matching the data - */ - virtual SubRoom* GetOtherSubRoom(int roomID, int subroomID) const; - - /** - * Debug output - */ - virtual void WriteToErrorLog() const; - - /** - * @return a nicely formatted string representation of the object - */ - virtual std::string WriteElement() const; + Crossing(); + virtual ~Crossing(); + + /** + * Set/Get the Id of the crossing + */ + void SetID(int ID); + + /** + * Set/Get the Id of the crossing + */ + int GetID () const; + + /** + * Set/Get the first room + */ + void SetRoom1(Room* r); + + /** + * Set/Get the crossing caption + */ + void SetCaption(std::string s); + + /** + * Set/Get the first subroom + */ + void SetSubRoom1(SubRoom* r1); + + /** + * Set/Get the second subroom + */ + void SetSubRoom2(SubRoom* r2); + + /** + * Set/Get the crossing caption + */ + std::string GetCaption() const; + + /** + * Set/Get the first room + */ + Room* GetRoom1() const; + + /** + * Set/Get the first subroom + */ + SubRoom* GetSubRoom1() const; + + /** + * Set/Get the second subroom + */ + SubRoom* GetSubRoom2() const; + + /** + * \return true if the subroomID is associated with the current crossing + */ + bool IsInSubRoom(int subroomID) const; + + + /** + * @return true if the crossing is open = passable + */ + virtual bool IsOpen() const; + + /** + * @return true if the crossing is an exit/transition. (Transitions are derived from this class) + * @see Transition + */ + virtual bool IsExit() const; + + /** + * + * @return true if it is a transition + */ + virtual bool IsTransition() const; + + /** + * @return true if the crossing/transintion/hline is associated with the room + */ + virtual bool IsInRoom(int roomID) const; + + /** + * @return the other subroom not matching the data + */ + virtual SubRoom* GetOtherSubRoom(int roomID, int subroomID) const; + + /** + * Debug output + */ + virtual void WriteToErrorLog() const; + + /** + * @return a nicely formatted string representation of the object + */ + virtual std::string WriteElement() const; }; -#endif /* _CROSSING_H */ +#endif /* _CROSSING_H */ diff --git a/src/geometry/FacilityGeometry.cpp b/src/geometry/FacilityGeometry.cpp index f62a37b64a5aa5d2919c4d8f794dad045ac848eb..543c98e8d7bb9be0afd41e9fe626ebb4d2d1c964 100644 --- a/src/geometry/FacilityGeometry.cpp +++ b/src/geometry/FacilityGeometry.cpp @@ -108,10 +108,20 @@ FacilityGeometry::FacilityGeometry() FacilityGeometry::~FacilityGeometry() { - if(assembly) - assembly->Delete(); + //if(assembly) + // assembly->Delete(); lookupTable->Delete(); + captions->Delete(); + + assembly->Delete(); + assembly2D->Delete(); + assemblyCaptions->Delete(); + + assemblyWalls3D->Delete(); + assemblyDoors3D->Delete(); + assembly3D->Delete(); + floorActor->Delete(); delete linesPlotter2D; } @@ -285,15 +295,15 @@ void FacilityGeometry::addWall(double x1, double y1, double z1, double x2, doubl JPoint *p1 = new JPoint(x1,y1,z1); JPoint *p2 = new JPoint(x2,y2,z2); - double *center = p1->centreCoordinatesWith(*p2); + JPoint p3 =p1->centreCoordinatesWith(*p2); + double centre[3]; p3.getXYZ(centre); double angle =p1->angleMadeWith(*p2); double length =p1->distanceTo(*p2)+wallThickness; - addNewElement(center, length, angle, WALL); + addNewElement(centre, length, angle, WALL); delete p1; delete p2; - delete center; } void FacilityGeometry::addStair(double x1, double y1, double z1, double x2, double y2, double z2,double thickness,double height,double color) @@ -335,15 +345,16 @@ void FacilityGeometry::addDoor(double x1, double y1, double z1, double x2, doubl JPoint *p1 = new JPoint(x1,y1,z1); JPoint *p2 = new JPoint(x2,y2,z2); - double *center = p1->centreCoordinatesWith(*p2); + JPoint p3 =p1->centreCoordinatesWith(*p2); + double centre[3]; p3.getXYZ(centre); double angle =p1->angleMadeWith(*p2); double length =p1->distanceTo(*p2)+wallThickness; - addNewElement(center, length, angle, DOOR); + addNewElement(centre, length, angle, DOOR); delete p1; delete p2; - delete center; + } void FacilityGeometry::addNavLine(double x1, double y1, double z1, double x2, double y2, double z2,double thickness ,double height, double color) @@ -379,15 +390,16 @@ void FacilityGeometry::addStep(double x1, double y1, double z1, double x2, doubl JPoint *p1 = new JPoint(x1,y1,z1); JPoint *p2 = new JPoint(x2,y2,z2); - double *center = p1->centreCoordinatesWith(*p2); + JPoint p3 =p1->centreCoordinatesWith(*p2); + double centre[3]; p3.getXYZ(centre); double angle =p1->angleMadeWith(*p2); double length =p1->distanceTo(*p2)+wallThickness; - addNewElement(center, length, angle, STEP); + addNewElement(centre, length, angle, STEP); delete p1; delete p2; - delete center; + } void FacilityGeometry::addStep(JPoint* p1, JPoint* p2) @@ -406,10 +418,11 @@ void FacilityGeometry::addStep(JPoint* p1, JPoint* p2) linesPlotter2D->PlotDoor(m,n,doorColor/255.0); - double *center = p1->centreCoordinatesWith(*p2); + JPoint p3 =p1->centreCoordinatesWith(*p2); + double centre[3]; p3.getXYZ(centre); double angle =p1->angleMadeWith(*p2); double length =p1->distanceTo(*p2)+wallThickness; - addNewElement( center, length, angle, STEP); + addNewElement(centre, length, angle, STEP); } @@ -437,10 +450,11 @@ void FacilityGeometry::addWall(JPoint* p1, JPoint* p2, string caption) addNewElementText(center,orientation,caption.c_str(),50); } - double *center = p1->centreCoordinatesWith(*p2); + JPoint p3 =p1->centreCoordinatesWith(*p2); + double centre[3]; p3.getXYZ(centre); double angle =p1->angleMadeWith(*p2); double length =p1->distanceTo(*p2)+wallThickness; - addNewElement( center, length, angle, WALL); + addNewElement( centre, length, angle, WALL); } void FacilityGeometry::addStair(JPoint* p1, JPoint* p2, string caption) @@ -503,10 +517,11 @@ void FacilityGeometry::addDoor(JPoint* p1, JPoint* p2, string caption) addNewElementText(center,orientation,caption.c_str(),0); } - double *center = p1->centreCoordinatesWith(*p2); + JPoint p3 =p1->centreCoordinatesWith(*p2); + double centre[3]; p3.getXYZ(centre); double angle =p1->angleMadeWith(*p2); double length =p1->distanceTo(*p2)+wallThickness; - addNewElement( center, length, angle, DOOR); + addNewElement( centre, length, angle, DOOR); } void FacilityGeometry::addNavLine(JPoint* p1, JPoint* p2, string caption) @@ -832,7 +847,7 @@ void FacilityGeometry::addNewElementText(double center[3], double orientation[3] //caption VTK_CREATE(vtkTextActor3D,caption); - caption = vtkTextActor3D ::New(); + //caption = vtkTextActor3D ::New(); //caption->SetVisibility(false); caption->SetInput(text.c_str()); diff --git a/src/geometry/Goal.cpp b/src/geometry/Goal.cpp index e62d5397d8aa37b000dbe25c8820607634f3839d..a2157819a0986f834920bb0c822049feac9bb44d 100644 --- a/src/geometry/Goal.cpp +++ b/src/geometry/Goal.cpp @@ -1,14 +1,14 @@ /** - * @file Goal.cpp - * @author Ulrich Kemloh <kemlohulrich@gmail.com> - * Created on: Sep 12, 2013 - * Copyright (C) <2009-2013> + * \file Goal.cpp + * \date Spe 12, 2013 + * \version v0.5 + * \copyright <2009-2014> Forschungszentrum Jülich GmbH. All rights reserved. * - * @section LICENSE + * \section License * This file is part of JuPedSim. * * JuPedSim is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by + * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * @@ -17,18 +17,18 @@ * 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 + * You should have received a copy of the GNU Lesser General Public License * along with JuPedSim. If not, see <http://www.gnu.org/licenses/>. * - * @section DESCRIPTION + * \section Description * * - * - */ + **/ + +#include "Point.h" #include "Goal.h" #include "Wall.h" -#include "Point.h" using namespace std; @@ -36,11 +36,11 @@ using namespace std; Goal::Goal() { - _id=-1; - _caption="Goal"; - _isFinalGoal=0; - _walls = vector<Wall > (); - _poly = vector<Point > (); + _id=-1; + _caption="Goal"; + _isFinalGoal=0; + _walls = vector<Wall > (); + _poly = vector<Point > (); } Goal::~Goal() @@ -50,87 +50,87 @@ Goal::~Goal() void Goal::AddWall(const Wall& w) { - _walls.push_back(w); + _walls.push_back(w); } string Goal::GetCaption() const { - return _caption; + return _caption; } void Goal::SetCaption(string caption) { - _caption = caption; + _caption = caption; } int Goal::GetId() const { - return _id; + return _id; } void Goal::SetId(int id) { - _id = id; + _id = id; } const vector<Point>& Goal::GetPolygon() const { - return _poly; + return _poly; } string Goal::Write() { - string s; - Point pos; - - for (unsigned int j = 0; j < _walls.size(); j++) { - const Wall& w = _walls[j]; - s.append(w.Write()); - pos = pos + w.GetPoint1() + w.GetPoint2(); - } - pos = pos * (0.5 / _walls.size()); - - // add some fancy stuffs - if(_poly.size()>=4) { - s.append(Wall(_poly[0],_poly[2]).Write()); - s.append(Wall(_poly[1],_poly[3]).Write()); - } - //add the Goal caption - char tmp[CLENGTH]; - sprintf(tmp, "\t\t<label centerX=\"%.2f\" centerY=\"%.2f\" centerZ=\"0\" text=\"%s\" color=\"100\" />\n" - , pos.GetX() * FAKTOR, pos.GetY() * FAKTOR, _caption.c_str()); - s.append(tmp); - - return s; + string s; + Point pos; + + for (unsigned int j = 0; j < _walls.size(); j++) { + const Wall& w = _walls[j]; + s.append(w.Write()); + pos = pos + w.GetPoint1() + w.GetPoint2(); + } + pos = pos * (0.5 / _walls.size()); + + // add some fancy stuffs + if(_poly.size()>=4) { + s.append(Wall(_poly[0],_poly[2]).Write()); + s.append(Wall(_poly[1],_poly[3]).Write()); + } + //add the Goal caption + char tmp[CLENGTH]; + sprintf(tmp, "\t\t<label centerX=\"%.2f\" centerY=\"%.2f\" centerZ=\"0\" text=\"%s\" color=\"100\" />\n" + , pos.GetX() * FAKTOR, pos.GetY() * FAKTOR, _caption.c_str()); + s.append(tmp); + + return s; } const vector<Wall>& Goal::GetAllWalls() const { - return _walls; + return _walls; } int Goal::WhichQuad(const Point& vertex, const Point& hitPos) const { - return (vertex.GetX() > hitPos.GetX()) ? ((vertex.GetY() > hitPos.GetY()) ? 1 : 4) : - ((vertex.GetY() > hitPos.GetY()) ? 2 : 3); + return (vertex.GetX() > hitPos.GetX()) ? ((vertex.GetY() > hitPos.GetY()) ? 1 : 4) : + ((vertex.GetY() > hitPos.GetY()) ? 2 : 3); } int Goal::GetIsFinalGoal() const { - return _isFinalGoal; + return _isFinalGoal; } void Goal::SetIsFinalGoal(int isFinalGoal) { - _isFinalGoal = isFinalGoal; + _isFinalGoal = isFinalGoal; } // x-Koordinate der Linie von einer Eccke zur nächsten double Goal::Xintercept(const Point& point1, const Point& point2, double hitY) const { - return (point2.GetX() - (((point2.GetY() - hitY) * (point1.GetX() - point2.GetX())) / - (point1.GetY() - point2.GetY()))); + return (point2.GetX() - (((point2.GetY() - hitY) * (point1.GetX() - point2.GetX())) / + (point1.GetY() - point2.GetY()))); } @@ -138,137 +138,136 @@ bool Goal::Contains(const Point& ped) const { - short edge, first, next; - short quad, next_quad, delta, total; - - ///////////////////////////////////////////////////////////// - edge = first = 0; - quad = WhichQuad(_poly[edge], ped); - total = 0; // COUNT OF ABSOLUTE SECTORS CROSSED - /* LOOP THROUGH THE VERTICES IN A SECTOR */ - do { - next = (edge + 1) % _poly.size(); - next_quad = WhichQuad(_poly[next], ped); - delta = next_quad - quad; // HOW MANY QUADS HAVE I MOVED - - // SPECIAL CASES TO HANDLE CROSSINGS OF MORE THEN ONE - //QUAD - - switch (delta) { - case 2: // IF WE CROSSED THE MIDDLE, FIGURE OUT IF IT - //WAS CLOCKWISE OR COUNTER - case -2: // US THE X POSITION AT THE HIT POINT TO - // DETERMINE WHICH WAY AROUND - if (Xintercept(_poly[edge], _poly[next], ped.GetY()) > ped.GetX()) - delta = -(delta); - break; - case 3: // MOVING 3 QUADS IS LIKE MOVING BACK 1 - delta = -1; - break; - case -3: // MOVING BACK 3 IS LIKE MOVING FORWARD 1 - delta = 1; - break; - } - /* ADD IN THE DELTA */ - total += delta; - quad = next_quad; // RESET FOR NEXT STEP - edge = next; - } while (edge != first); - - /* AFTER ALL IS DONE IF THE TOTAL IS 4 THEN WE ARE INSIDE */ - if (abs(total) == 4) - return true; - else - return false; + short edge, first, next; + short quad, next_quad, delta, total; + + ///////////////////////////////////////////////////////////// + edge = first = 0; + quad = WhichQuad(_poly[edge], ped); + total = 0; // COUNT OF ABSOLUTE SECTORS CROSSED + /* LOOP THROUGH THE VERTICES IN A SECTOR */ + do { + next = (edge + 1) % _poly.size(); + next_quad = WhichQuad(_poly[next], ped); + delta = next_quad - quad; // HOW MANY QUADS HAVE I MOVED + + // SPECIAL CASES TO HANDLE CROSSINGS OF MORE THEN ONE + //QUAD + + switch (delta) { + case 2: // IF WE CROSSED THE MIDDLE, FIGURE OUT IF IT + //WAS CLOCKWISE OR COUNTER + case -2: // US THE X POSITION AT THE HIT POINT TO + // DETERMINE WHICH WAY AROUND + if (Xintercept(_poly[edge], _poly[next], ped.GetY()) > ped.GetX()) + delta = -(delta); + break; + case 3: // MOVING 3 QUADS IS LIKE MOVING BACK 1 + delta = -1; + break; + case -3: // MOVING BACK 3 IS LIKE MOVING FORWARD 1 + delta = 1; + break; + } + /* ADD IN THE DELTA */ + total += delta; + quad = next_quad; // RESET FOR NEXT STEP + edge = next; + } while (edge != first); + + /* AFTER ALL IS DONE IF THE TOTAL IS 4 THEN WE ARE INSIDE */ + if (abs(total) == 4) + return true; + else + return false; } -void Goal::ConvertLineToPoly() +bool Goal::ConvertLineToPoly() { - - vector<Line*> copy; - vector<Point> tmpPoly; - Point point; - Line* line; - // Alle Linienelemente in copy speichern - for (unsigned int i = 0; i < _walls.size(); i++) { - copy.push_back(&_walls[i]); - } - - line = copy[0]; - tmpPoly.push_back(line->GetPoint1()); - point = line->GetPoint2(); - copy.erase(copy.begin()); - // Polygon aus allen Linen erzeugen - for (int i = 0; i < (int) copy.size(); i++) { - line = copy[i]; - if ((point - line->GetPoint1()).Norm() < J_TOLERANZ) { - tmpPoly.push_back(line->GetPoint1()); - point = line->GetPoint2(); - copy.erase(copy.begin() + i); - // von vorne suchen - i = -1; - } else if ((point - line->GetPoint2()).Norm() < J_TOLERANZ) { - tmpPoly.push_back(line->GetPoint2()); - point = line->GetPoint1(); - copy.erase(copy.begin() + i); - // von vorne suchen - i = -1; - } - } - if ((tmpPoly[0] - point).Norm() > J_TOLERANZ) { - char tmp[CLENGTH]; - sprintf(tmp, "ERROR: \tGoal::ConvertLineToPoly(): ID %d !!!\n", _id); - Log->Write(tmp); - exit(0); - } - _poly = tmpPoly; - - ComputeControid(); + vector<Line*> copy; + vector<Point> tmpPoly; + Point point; + Line* line; + // Alle Linienelemente in copy speichern + for (unsigned int i = 0; i < _walls.size(); i++) { + copy.push_back(&_walls[i]); + } + + line = copy[0]; + tmpPoly.push_back(line->GetPoint1()); + point = line->GetPoint2(); + copy.erase(copy.begin()); + // Polygon aus allen Linen erzeugen + for (int i = 0; i < (int) copy.size(); i++) { + line = copy[i]; + if ((point - line->GetPoint1()).Norm() < J_TOLERANZ) { + tmpPoly.push_back(line->GetPoint1()); + point = line->GetPoint2(); + copy.erase(copy.begin() + i); + // von vorne suchen + i = -1; + } else if ((point - line->GetPoint2()).Norm() < J_TOLERANZ) { + tmpPoly.push_back(line->GetPoint2()); + point = line->GetPoint1(); + copy.erase(copy.begin() + i); + // von vorne suchen + i = -1; + } + } + if ((tmpPoly[0] - point).Norm() > J_TOLERANZ) { + char tmp[CLENGTH]; + sprintf(tmp, "ERROR: \tGoal::ConvertLineToPoly(): ID %d !!!\n", _id); + Log->Write(tmp); + return false; + } + _poly = tmpPoly; + ComputeControid(); + return true; } const Point& Goal::GetCentroid() const { - return _centroid; + return _centroid; } void Goal::ComputeControid() { - double px=0,py=0; - double signedArea = 0.0; - double x0 = 0.0; // Current vertex X - double y0 = 0.0; // Current vertex Y - double x1 = 0.0; // Next vertex X - double y1 = 0.0; // Next vertex Y - double a = 0.0; // Partial signed area - - // For all vertices except last - unsigned int i=0; - for (i=0; i<_poly.size()-1; ++i) { - x0 = _poly[i].GetX(); - y0 = _poly[i].GetY(); - x1 = _poly[i+1].GetX(); - y1 = _poly[i+1].GetY(); - a = x0*y1 - x1*y0; - signedArea += a; - px += (x0 + x1)*a; - py += (y0 + y1)*a; - } - - // Do last vertex - x0 = _poly[i].GetX(); - y0 = _poly[i].GetY(); - x1 = _poly[0].GetX(); - y1 = _poly[0].GetY(); - a = x0*y1 - x1*y0; - signedArea += a; - px += (x0 + x1)*a; - py += (y0 + y1)*a; - - signedArea *= 0.5; - px /= (6*signedArea); - py /= (6*signedArea); - - _centroid._x=px; - _centroid._y=py; + double px=0,py=0; + double signedArea = 0.0; + double x0 = 0.0; // Current vertex X + double y0 = 0.0; // Current vertex Y + double x1 = 0.0; // Next vertex X + double y1 = 0.0; // Next vertex Y + double a = 0.0; // Partial signed area + + // For all vertices except last + unsigned int i=0; + for (i=0; i<_poly.size()-1; ++i) { + x0 = _poly[i].GetX(); + y0 = _poly[i].GetY(); + x1 = _poly[i+1].GetX(); + y1 = _poly[i+1].GetY(); + a = x0*y1 - x1*y0; + signedArea += a; + px += (x0 + x1)*a; + py += (y0 + y1)*a; + } + + // Do last vertex + x0 = _poly[i].GetX(); + y0 = _poly[i].GetY(); + x1 = _poly[0].GetX(); + y1 = _poly[0].GetY(); + a = x0*y1 - x1*y0; + signedArea += a; + px += (x0 + x1)*a; + py += (y0 + y1)*a; + + signedArea *= 0.5; + px /= (6*signedArea); + py /= (6*signedArea); + + _centroid._x=px; + _centroid._y=py; } diff --git a/src/geometry/Goal.h b/src/geometry/Goal.h index 866a7eccdeca5452363d99c30f94cf00e8c2e304..3fe6596f0883d589b238b74e97d6c5acbf7e9d42 100644 --- a/src/geometry/Goal.h +++ b/src/geometry/Goal.h @@ -1,14 +1,14 @@ /** - * @file Goal.h - * @author Ulrich Kemloh <kemlohulrich@gmail.com> - * Created on: Sep 12, 2013 - * Copyright (C) <2009-2013> + * \file Goal.h + * \date Sep 12, 2013 + * \version v0.5 + * \copyright <2009-2014> Forschungszentrum Jülich GmbH. All rights reserved. * - * @section LICENSE + * \section License * This file is part of JuPedSim. * * JuPedSim is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by + * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * @@ -17,116 +17,119 @@ * 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 + * You should have received a copy of the GNU Lesser General Public License * along with JuPedSim. If not, see <http://www.gnu.org/licenses/>. * - * @section DESCRIPTION + * \section Description * * - * - */ + **/ + #ifndef GOAL_H_ #define GOAL_H_ #include <string> #include <vector> -#include "Point.h" + +//forward declarations class Wall; +class Point; + class Goal { private: - int _isFinalGoal; - int _id; - Point _centroid; - std::string _caption; - std::vector<Wall> _walls; - std::vector<Point> _poly; + int _isFinalGoal; + int _id; + Point _centroid; + std::string _caption; + std::vector<Wall> _walls; + std::vector<Point> _poly; public: - Goal(); - virtual ~Goal(); - - /** - * Set/Get the obstacles' caption - */ - std::string GetCaption() const; - - /** - * Set/Get the obstacles' caption - */ - void SetCaption(std::string caption); - - /** - * Set/Get the id of the Goal - */ - int GetId() const; - - /** - * Set/Get the id of the Goal - */ - void SetId(int id); - - /** - * construct the Goal by adding more walls - */ - void AddWall(const Wall& w); - - /** - * @return All walls that constitute the Goal - */ - const std::vector<Wall>& GetAllWalls() const; - - /** - * @return true if the point p is contained within the Closed Goal - */ - bool Contains(const Point& p) const; - - /** - * Create the obstacles polygonal structure from the walls - */ - void ConvertLineToPoly(); - - /** - * @return the Goal as a polygon - */ - const std::vector<Point>& GetPolygon() const; - - /** - * agents are remove from the simulation when they reached a final goal - */ - int GetIsFinalGoal() const; - - /** - * agents are remove from the simulation when they reached a final goal - */ - void SetIsFinalGoal(int isFinalGoal); - - /** - * @return the centroid of the subroom - * @see http://en.wikipedia.org/wiki/Centroid - */ - void ComputeControid() ; - - /** - * @return the centroid of the goal - * @see ComputeControid - */ - const Point& GetCentroid() const; - - /** - * @return a nicely formatted string representation of the Goal - */ - std::string Write(); + Goal(); + virtual ~Goal(); + + /** + * Set/Get the obstacles' caption + */ + std::string GetCaption() const; + + /** + * Set/Get the obstacles' caption + */ + void SetCaption(std::string caption); + + /** + * Set/Get the id of the Goal + */ + int GetId() const; + + /** + * Set/Get the id of the Goal + */ + void SetId(int id); + + /** + * construct the Goal by adding more walls + */ + void AddWall(const Wall& w); + + /** + * @return All walls that constitute the Goal + */ + const std::vector<Wall>& GetAllWalls() const; + + /** + * @return true if the point p is contained within the Closed Goal + */ + bool Contains(const Point& p) const; + + /** + * Create the obstacles polygonal structure from the walls + */ + bool ConvertLineToPoly(); + + /** + * @return the Goal as a polygon + */ + const std::vector<Point>& GetPolygon() const; + + /** + * agents are remove from the simulation when they reached a final goal + */ + int GetIsFinalGoal() const; + + /** + * agents are remove from the simulation when they reached a final goal + */ + void SetIsFinalGoal(int isFinalGoal); + + /** + * @return the centroid of the subroom + * @see http://en.wikipedia.org/wiki/Centroid + */ + void ComputeControid() ; + + /** + * @return the centroid of the goal + * @see ComputeControid + */ + const Point& GetCentroid() const; + + /** + * @return a nicely formatted string representation of the Goal + */ + std::string Write(); private: - int WhichQuad(const Point& vertex, const Point& hitPos) const; + int WhichQuad(const Point& vertex, const Point& hitPos) const; - // x-Koordinate der Linie von einer Eccke zur nächsten - double Xintercept(const Point& point1, const Point& point2, - double hitY) const; + // x-Koordinate der Linie von einer Eccke zur nächsten + double Xintercept(const Point& point1, const Point& point2, + double hitY) const; }; diff --git a/src/geometry/Hline.cpp b/src/geometry/Hline.cpp index dafb48147883b0646dc6e3086e638b96e1db6a1f..a88a5dd69b7ce564da5ed932a00257f09f7fb9e6 100644 --- a/src/geometry/Hline.cpp +++ b/src/geometry/Hline.cpp @@ -1,13 +1,14 @@ /** - * Hline.cpp + * \file Hline.cpp + * \date Aug 1, 2012 + * \version v0.5 + * \copyright <2009-2014> Forschungszentrum Jülich GmbH. All rights reserved. * - * Created on: Aug 1, 2012 - * - * @section LICENSE + * \section License * This file is part of JuPedSim. * * JuPedSim is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by + * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * @@ -16,25 +17,25 @@ * 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 + * You should have received a copy of the GNU Lesser General Public License * along with JuPedSim. If not, see <http://www.gnu.org/licenses/>. * - * @section DESCRIPTION - * + * \section Description * * - */ + **/ #include "Hline.h" +#include "SubRoom.h" using namespace std; Hline::Hline() { - _room=NULL; - _subRoom=NULL; - _id=-1; + _room1=NULL; + _subRoom1=NULL; + _id=-1; } Hline::~Hline() @@ -43,88 +44,88 @@ Hline::~Hline() void Hline::SetID(int ID) { - _id=ID; + _id=ID; } -void Hline::SetRoom(Room* r) +void Hline::SetRoom1(Room* r) { - _room=r; + _room1=r; } void Hline::SetCaption(string s) { - _caption=s; + _caption=s; } -void Hline::SetSubRoom(SubRoom* s) +void Hline::SetSubRoom1(SubRoom* s) { - _subRoom=s; + _subRoom1=s; } int Hline::GetID() const { - return _id; + return _id; } string Hline::GetCaption() const { - return _caption; + return _caption; } -Room* Hline::GetRoom() const +Room* Hline::GetRoom1() const { - return _room; + return _room1; } -SubRoom* Hline::GetSubRoom() const +SubRoom* Hline::GetSubRoom1() const { - return _subRoom; + return _subRoom1; } bool Hline::IsInSubRoom(int subroomID) const { - return _subRoom->GetSubRoomID() == subroomID; + return _subRoom1->GetSubRoomID() == subroomID; } bool Hline::IsInRoom(int roomID) const { - return _room->GetID() == roomID; + return _room1->GetID() == roomID; } void Hline::WriteToErrorLog() const { - string s; - char tmp[CLENGTH]; - sprintf(tmp, "\t\tHline: %d (%f, %f) -- (%f, %f)\n", GetID(), GetPoint1().GetX(), - GetPoint1().GetY(), GetPoint2().GetX(), GetPoint2().GetY()); - s.append(tmp); - sprintf(tmp, "\t\t\t\tRoom: %d <-> SubRoom: %d\n", _room->GetID(), - _subRoom->GetSubRoomID()); - s.append(tmp); - Log->Write(s); + string s; + char tmp[CLENGTH]; + sprintf(tmp, "\t\tHline: %d (%f, %f) -- (%f, %f)\n", GetID(), GetPoint1().GetX(), + GetPoint1().GetY(), GetPoint2().GetX(), GetPoint2().GetY()); + s.append(tmp); + sprintf(tmp, "\t\t\t\tRoom: %d <-> SubRoom: %d\n", _room1->GetID(), + _subRoom1->GetSubRoomID()); + s.append(tmp); + Log->Write(s); } // TraVisTo Ausgabe string Hline::WriteElement() const { - string geometry; - char tmp[CLENGTH] = ""; - sprintf(tmp,"\t\t<door ID=\"%d\" color = \"250\" caption=\"%d_%d\">\n",GetUniqueID(),GetID(),GetUniqueID()); - geometry.append(tmp); - //geometry.append("\t\t<door color=\"250\">\n"); - sprintf(tmp, "\t\t\t<point xPos=\"%.2f\" yPos=\"%.2f\" zPos=\"%.2f\"/>\n", - (GetPoint1().GetX()) * FAKTOR, - (GetPoint1().GetY()) * FAKTOR, - _subRoom->GetElevation(GetPoint1())*FAKTOR); - geometry.append(tmp); - sprintf(tmp, "\t\t\t<point xPos=\"%.2f\" yPos=\"%.2f\" zPos=\"%.2f\"/>\n", - (GetPoint2().GetX()) * FAKTOR, - (GetPoint2().GetY()) * FAKTOR, - _subRoom->GetElevation(GetPoint2())*FAKTOR); - geometry.append(tmp); - geometry.append("\t\t</door>\n"); - return geometry; + string geometry; + char tmp[CLENGTH] = ""; + sprintf(tmp,"\t\t<hline ID=\"%d\" color = \"250\" caption=\"%d_%d\">\n",GetUniqueID(),GetID(),GetUniqueID()); + geometry.append(tmp); + //geometry.append("\t\t<door color=\"250\">\n"); + sprintf(tmp, "\t\t\t<point xPos=\"%.2f\" yPos=\"%.2f\" zPos=\"%.2f\"/>\n", + (GetPoint1().GetX()) * FAKTOR, + (GetPoint1().GetY()) * FAKTOR, + _subRoom1->GetElevation(GetPoint1())*FAKTOR); + geometry.append(tmp); + sprintf(tmp, "\t\t\t<point xPos=\"%.2f\" yPos=\"%.2f\" zPos=\"%.2f\"/>\n", + (GetPoint2().GetX()) * FAKTOR, + (GetPoint2().GetY()) * FAKTOR, + _subRoom1->GetElevation(GetPoint2())*FAKTOR); + geometry.append(tmp); + geometry.append("\t\t</hline>\n"); + return geometry; } diff --git a/src/geometry/Hline.h b/src/geometry/Hline.h index dd91ead7aec942ecd4e6723c041d530169f25706..fb42a23e0bcdfb2371a3e32d07da0de9d54ad10b 100644 --- a/src/geometry/Hline.h +++ b/src/geometry/Hline.h @@ -1,14 +1,14 @@ /** - * Hline.h + * \file Hline.h + * \date Aug 1, 2012 + * \version v0.5 + * \copyright <2009-2014> Forschungszentrum Jülich GmbH. All rights reserved. * - * Created on: Aug 1, 2012 - * - * - * @section LICENSE + * \section License * This file is part of JuPedSim. * * JuPedSim is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by + * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * @@ -17,14 +17,14 @@ * 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 + * You should have received a copy of the GNU Lesser General Public License * along with JuPedSim. If not, see <http://www.gnu.org/licenses/>. * - * @section DESCRIPTION - * + * \section Description * * - */ + **/ + #ifndef HLINE_H_ #define HLINE_H_ @@ -39,76 +39,76 @@ class Room; class Hline: public NavLine { private: - int _id; - Room* _room; - std::string _caption; - SubRoom* _subRoom; + int _id; + Room* _room1; + std::string _caption; + SubRoom* _subRoom1; public: - Hline(); - virtual ~Hline(); - - /** - * Set/Get the id of the line - */ - void SetID(int ID); - - /** - * Set/Get the Room containing this line - */ - void SetRoom(Room* r); - - /** - * Set/Get the line caption - */ - void SetCaption(std::string s); - - /** - * Set/Get the subroom containing this line - */ - void SetSubRoom(SubRoom* r); - - - /** - * Set/Get the id of the line - */ - int GetID() const; - - /** - * Set/Get the line caption - */ - std::string GetCaption() const; - - /** - * Set/Get the Room containing this line - */ - Room* GetRoom() const; - - /** - * Set/Get the subroom containing this line - */ - SubRoom* GetSubRoom() const; - - - /** - * @return true if the line is in the given subroom - */ - bool IsInSubRoom(int subroomID) const; - - /** - * @return true if the line is in the given room - */ - bool IsInRoom(int roomID) const; - - /** - * Debug output - */ - void WriteToErrorLog() const; - - /** - * @return a nicely formatted string representation of the object - */ - std::string WriteElement() const; + Hline(); + virtual ~Hline(); + + /** + * Set/Get the id of the line + */ + void SetID(int ID); + + /** + * Set/Get the Room containing this line + */ + void SetRoom1(Room* r); + + /** + * Set/Get the line caption + */ + void SetCaption(std::string s); + + /** + * Set/Get the subroom containing this line + */ + void SetSubRoom1(SubRoom* r); + + + /** + * Set/Get the id of the line + */ + int GetID() const; + + /** + * Set/Get the line caption + */ + std::string GetCaption() const; + + /** + * Set/Get the Room containing this line + */ + Room* GetRoom1() const; + + /** + * Set/Get the subroom containing this line + */ + SubRoom* GetSubRoom1() const; + + + /** + * @return true if the line is in the given subroom + */ + bool IsInSubRoom(int subroomID) const; + + /** + * @return true if the line is in the given room + */ + bool IsInRoom(int roomID) const; + + /** + * Debug output + */ + virtual void WriteToErrorLog() const; + + /** + * @return a nicely formatted string representation of the object + */ + virtual std::string WriteElement() const; }; #endif /* HLINE_H_ */ diff --git a/src/geometry/JPoint.cpp b/src/geometry/JPoint.cpp index f892dc549a72ca097a66dbf99e58d354bc1cc7d7..484f4fb9b965850c10fab8466b2b7c9cdcf9ef72 100644 --- a/src/geometry/JPoint.cpp +++ b/src/geometry/JPoint.cpp @@ -93,15 +93,15 @@ void JPoint::getXYZ(double*xyz) /* * return the coordinates */ -double JPoint::getX() +double JPoint::getX() const { return x; } -double JPoint::getY() +double JPoint::getY() const { return y; } -double JPoint::getZ() +double JPoint::getZ() const { return z; } @@ -111,7 +111,7 @@ double JPoint::getZ() * @return the angle in degree * FIXME: why +90?? */ -double JPoint::angleMadeWith(JPoint& pt) +double JPoint::angleMadeWith(JPoint& pt) const { double dx=x-pt.x; double dy=y-pt.y; @@ -128,7 +128,7 @@ double JPoint::angleMadeWith(JPoint& pt) return vtkMath::DegreesFromRadians(atan2(dy,dx))+90 ; } -double JPoint::distanceTo(JPoint& pt) +double JPoint::distanceTo(JPoint& pt) const { double dx=x-pt.x; dx*=dx; @@ -139,24 +139,27 @@ double JPoint::distanceTo(JPoint& pt) return sqrt(dx+dy+dz); } -double * JPoint::centreCoordinatesWith(JPoint &pt) + +JPoint JPoint::centreCoordinatesWith(JPoint &pt) const { - double *res= new double[3]; - res[0]=(x+pt.getX())/2; - res[1]=(y+pt.getY())/2; - res[2]=(z+pt.getZ())/2; - return res; + + //centre[0]=(x+pt.getX())/2; + //centre[1]=(y+pt.getY())/2; + //centre[2]=(z+pt.getZ())/2; + return (*this +pt)*0.5; } double JPoint::distanceBetween(JPoint& pt1, JPoint& pt2) { return pt1.distanceTo(pt2); } + double JPoint::angleMadeBetween(JPoint& pt1, JPoint& pt2) { return pt1.angleMadeWith(pt2); } -double *JPoint::centreCoordinatesBetween(JPoint& pt1, JPoint& pt2) + +JPoint JPoint::centreCoordinatesBetween(JPoint& pt1, JPoint& pt2) { return pt1.centreCoordinatesWith(pt2); } @@ -191,3 +194,36 @@ void JPoint::getColorHeightThicknes(double *CHT) CHT[1]=height; CHT[2]=thickness; } + +// sum +const JPoint JPoint::operator+(const JPoint& p) const +{ + //return Point(_x + p.GetX(), _y + p.GetY()); + return JPoint(x + p.x, y + p.y, z+p.z); +} + +// sub +const JPoint JPoint::operator-(const JPoint& p) const +{ + // return Point(_x - p.GetX(), _y - p.GetY()); + return JPoint(x - p.x, y - p.y, z-p.z); +} + + +// multiplication with scalar +JPoint operator*(const JPoint& p, double f) +{ + return JPoint(p.getX() * f, p.getY() * f, p.getZ() * f); +} + +// divition with scalar +JPoint operator/(const JPoint& p, double f) +{ +// if (f>J_EPS*J_EPS) +// return JPoint(p._x / f, p._y / f); +// else { +// std::cout << "Warning: Point::/operator. dividand "<<f<< " is to small. Set it to 1 instead"<<std::endl; +// return JPoint(p._x, p._y); +// } + return JPoint(p.getX() / f, p.getY() / f, p.getZ()/f); +} diff --git a/src/geometry/JPoint.h b/src/geometry/JPoint.h index 64c558a6509c65bba92f3d49369710e56e631765..5caa19c9f01dfd7a6dfbf243a38e0e59753d6008 100644 --- a/src/geometry/JPoint.h +++ b/src/geometry/JPoint.h @@ -47,16 +47,16 @@ public: JPoint(double xyz[3], const char* col="abc"); virtual ~JPoint(); - double getX(); - double getY(); - double getZ(); - double distanceTo(JPoint& pt); - double angleMadeWith(JPoint &pt); - double* centreCoordinatesWith(JPoint &pt); + double getX() const; + double getY()const; + double getZ()const; + double distanceTo(JPoint& pt)const; + double angleMadeWith(JPoint &pt)const; + JPoint centreCoordinatesWith(JPoint &pt) const; static double distanceBetween(JPoint& pt1, JPoint& pt2); static double angleMadeBetween(JPoint& pt1, JPoint& pt2); - static double *centreCoordinatesBetween(JPoint& pt1, JPoint& pt2); + static JPoint centreCoordinatesBetween(JPoint& pt1, JPoint& pt2); void setColorRGB(unsigned char r, unsigned char g, unsigned char b); void getColorRGB(unsigned char *rgb); @@ -72,6 +72,18 @@ public: //this is the end point of a door/wall for instance void setColorHeightThicknes(double CHT[3]); void getColorHeightThicknes(double *CHT); + + // operators + /// addition + const JPoint operator+(const JPoint& p) const; + /// substraction + const JPoint operator-(const JPoint& p) const; + }; +/// multiplication +JPoint operator*(const JPoint& p, const double f); +/// division +JPoint operator/(const JPoint& p, const double f); + #endif /* POINT_H_ */ diff --git a/src/geometry/Line.cpp b/src/geometry/Line.cpp index 0b6ccc4ad46383ed4ac69291b456541187b8a563..b987e90f326e22a6209fefbd6399dcf679178283 100644 --- a/src/geometry/Line.cpp +++ b/src/geometry/Line.cpp @@ -1,12 +1,14 @@ /** - * File: Line.cpp + * \file Line.cpp + * \date Sep 30, 2010 + * \version v0.5 + * \copyright <2009-2014> Forschungszentrum Jülich GmbH. All rights reserved. * - * Created on 30. September 2010, 09:40 - * @section LICENSE + * \section License * This file is part of JuPedSim. * * JuPedSim is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by + * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * @@ -15,18 +17,21 @@ * 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 + * You should have received a copy of the GNU Lesser General Public License * along with JuPedSim. If not, see <http://www.gnu.org/licenses/>. * - * @section DESCRIPTION + * \section Description * * - * - */ + **/ + #include "Point.h" +//#include "SubRoom.h" #include "../general/Macros.h" #include "Line.h" +#include "../IO/OutputHandler.h" + #include <cmath> @@ -41,29 +46,29 @@ using namespace std; ************************************************************/ Line::Line() { - SetPoint1(Point()); //Default-Constructor (0.0,0.0) - SetPoint2(Point()); - _uid = _static_UID++; + SetPoint1(Point()); //Default-Constructor (0.0,0.0) + SetPoint2(Point()); + _uid = _static_UID++; } Line::Line(const Point& p1, const Point& p2) { - SetPoint1(p1); - SetPoint2(p2); - _uid = _static_UID++; + SetPoint1(p1); + SetPoint2(p2); + _uid = _static_UID++; } int Line::GetUniqueID() const { - return _uid; + return _uid; } Line::Line(const Line& orig) { - _point1 = orig.GetPoint1(); - _point2 = orig.GetPoint2(); - _centre = orig.GetCentre(); - _uid = orig.GetUniqueID(); + _point1 = orig.GetPoint1(); + _point2 = orig.GetPoint2(); + _centre = orig.GetCentre(); + _uid = orig.GetUniqueID(); } Line::~Line() @@ -75,14 +80,14 @@ Line::~Line() ************************************************************/ void Line::SetPoint1(const Point& p) { - _point1 = p; - _centre = (_point1+_point2)*0.5; + _point1 = p; + _centre = (_point1+_point2)*0.5; } void Line::SetPoint2(const Point& p) { - _point2 = p; - _centre = (_point1+_point2)*0.5; + _point2 = p; + _centre = (_point1+_point2)*0.5; } /************************************************************* @@ -90,17 +95,17 @@ void Line::SetPoint2(const Point& p) ************************************************************/ const Point& Line::GetPoint1() const { - return _point1; + return _point1; } const Point& Line::GetPoint2() const { - return _point2; + return _point2; } const Point& Line::GetCentre()const { - return _centre; + return _centre; } /************************************************************* @@ -108,19 +113,19 @@ const Point& Line::GetCentre()const ************************************************************/ string Line::Write() const { - string geometry; - char wall[500] = ""; - geometry.append("\t\t<wall color=\"100\">\n"); - sprintf(wall, "\t\t\t<point xPos=\"%.2f\" yPos=\"%.2f\"/>\n", - (GetPoint1().GetX()) * FAKTOR, - (GetPoint1().GetY()) * FAKTOR); - geometry.append(wall); - sprintf(wall, "\t\t\t<point xPos=\"%.2f\" yPos=\"%.2f\"/>\n", - (GetPoint2().GetX()) * FAKTOR, - (GetPoint2().GetY()) * FAKTOR); - geometry.append(wall); - geometry.append("\t\t</wall>\n"); - return geometry; + string geometry; + char wall[500] = ""; + geometry.append("\t\t<wall color=\"100\">\n"); + sprintf(wall, "\t\t\t<point xPos=\"%.2f\" yPos=\"%.2f\"/>\n", + (GetPoint1().GetX()) * FAKTOR, + (GetPoint1().GetY()) * FAKTOR); + geometry.append(wall); + sprintf(wall, "\t\t\t<point xPos=\"%.2f\" yPos=\"%.2f\"/>\n", + (GetPoint2().GetX()) * FAKTOR, + (GetPoint2().GetY()) * FAKTOR); + geometry.append(wall); + geometry.append("\t\t</wall>\n"); + return geometry; } @@ -131,67 +136,67 @@ string Line::Write() const Point Line::NormalVec() const { - double nx, ny, norm; - Point r = GetPoint2() - GetPoint1(); - - if (r.GetX() == 0.0) { - nx = 1; - ny = 0; - } else { - nx = -r.GetY() / r.GetX(); - ny = 1; - /* Normieren */ - norm = sqrt(nx * nx + ny * ny); - if (fabs(norm) < J_EPS) { - Log->Write("ERROR: \tLine::NormalVec() norm==0\n"); - exit(0); - } - nx /= norm; - ny /= norm; - } - return Point(nx, ny); + double nx, ny, norm; + Point r = GetPoint2() - GetPoint1(); + + if (r.GetX() == 0.0) { + nx = 1; + ny = 0; + } else { + nx = -r.GetY() / r.GetX(); + ny = 1; + /* Normieren */ + norm = sqrt(nx * nx + ny * ny); + if (fabs(norm) < J_EPS) { + Log->Write("ERROR: \tLine::NormalVec() norm==0\n"); + exit(0); + } + nx /= norm; + ny /= norm; + } + return Point(nx, ny); } // Normale Komponente von v auf l double Line::NormalComp(const Point& v) const { - // Normierte Vectoren - Point l = (GetPoint2() - GetPoint1()).Normalized(); - const Point& n = NormalVec(); + // Normierte Vectoren + Point l = (GetPoint2() - GetPoint1()).Normalized(); + const Point& n = NormalVec(); - double lx = l.GetX(); - double ly = l.GetY(); - double nx = n.GetX(); - double ny = n.GetY(); - double alpha; + double lx = l.GetX(); + double ly = l.GetY(); + double nx = n.GetX(); + double ny = n.GetY(); + double alpha; - if (fabs(lx) < J_EPS) { - alpha = v.GetX() / nx; - } else if (fabs(ly) < J_EPS) { - alpha = v.GetY() / ny; - } else { - alpha = (v.GetY() * lx - v.GetX() * ly) / (nx * ly - ny * lx); - } + if (fabs(lx) < J_EPS) { + alpha = v.GetX() / nx; + } else if (fabs(ly) < J_EPS) { + alpha = v.GetY() / ny; + } else { + alpha = (v.GetY() * lx - v.GetX() * ly) / (nx * ly - ny * lx); + } - return fabs(alpha); + return fabs(alpha); } // Lotfußpunkt zur Geraden Line // Muss nicht im Segment liegen Point Line::LotPoint(const Point& p) const { - const Point& r = GetPoint1(); - const Point& s = GetPoint2(); - const Point& t = r - s; - Point tmp; - double lambda; + const Point& r = GetPoint1(); + const Point& s = GetPoint2(); + const Point& t = r - s; + Point tmp; + double lambda; - tmp = p - s; - lambda = tmp.ScalarP(t) / t.ScalarP(t); - Point f = s + t*lambda; - return f; + tmp = p - s; + lambda = tmp.ScalarP(t) / t.ScalarP(t); + Point f = s + t*lambda; + return f; } /* Punkt auf der Linie mit kürzestem Abstand zu p @@ -201,19 +206,20 @@ Point Line::LotPoint(const Point& p) const Point Line::ShortestPoint(const Point& p) const { - const Point& t = _point1 - _point2; + const Point& t = _point1 - _point2; + if(_point1 == _point2) + return _point1; + Point tmp = p - _point2; + double lambda = tmp.ScalarP(t) / t.ScalarP(t); + Point f = _point2 + t*lambda; - Point tmp = p - _point2; - double lambda = tmp.ScalarP(t) / t.ScalarP(t); - Point f = _point2 + t*lambda; + /* Prüfen ob Punkt in der Linie,sonst entsprechenden Eckpunkt zurückgeben */ + if (lambda < 0) + f = _point2; + if (lambda > 1) + f = _point1; - /* Prüfen ob Punkt in der Linie,sonst entsprechenden Eckpunkt zurückgeben */ - if (lambda < 0) - f = _point2; - if (lambda > 1) - f = _point1; - - return f; + return f; } /* Prüft, ob Punkt p im Liniensegment enthalten ist @@ -221,25 +227,25 @@ Point Line::ShortestPoint(const Point& p) const * lambda berechnen und prüfen ob zwischen 0 und 1 * */ //bool Line::IsInLine(const Point& p) const { -// double ax, ay, bx, by, px, py; -// const Point& a = GetPoint1(); -// const Point& b = GetPoint2(); -// double lambda; -// ax = a.GetX(); -// ay = a.GetY(); -// bx = b.GetX(); -// by = b.GetY(); -// px = p.GetX(); -// py = p.GetY(); -// if (fabs(ax - bx) > J_EPS_DIST) { -// lambda = (px - ax) / (bx - ax); -// } else if (fabs(ay - by) > J_EPS_DIST) { -// lambda = (py - ay) / (by - ay); -// } else { -// Log->Write("ERROR: \tIsInLine: Endpunkt = Startpunkt!!!"); -// exit(0); -// } -// return (0 <= lambda) && (lambda <= 1); +// double ax, ay, bx, by, px, py; +// const Point& a = GetPoint1(); +// const Point& b = GetPoint2(); +// double lambda; +// ax = a.GetX(); +// ay = a.GetY(); +// bx = b.GetX(); +// by = b.GetY(); +// px = p.GetX(); +// py = p.GetY(); +// if (fabs(ax - bx) > J_EPS_DIST) { +// lambda = (px - ax) / (bx - ax); +// } else if (fabs(ay - by) > J_EPS_DIST) { +// lambda = (py - ay) / (by - ay); +// } else { +// Log->Write("ERROR: \tIsInLine: Endpunkt = Startpunkt!!!"); +// exit(0); +// } +// return (0 <= lambda) && (lambda <= 1); //} /* @@ -249,24 +255,24 @@ Point Line::ShortestPoint(const Point& p) const * */ bool Line::IsInLineSegment(const Point& p) const { - //const Point& _point1 = GetPoint1(); - //const Point& _point2 = GetPoint2(); - double ax = _point1.GetX(); - double ay = _point1.GetY(); - double bx = _point2.GetX(); - double by = _point2.GetY(); - double px = p._x; - double py = p._y; + //const Point& _point1 = GetPoint1(); + //const Point& _point2 = GetPoint2(); + double ax = _point1.GetX(); + double ay = _point1.GetY(); + double bx = _point2.GetX(); + double by = _point2.GetY(); + double px = p._x; + double py = p._y; - // cross product to check if point i colinear - double crossp = (py-ay)*(bx-ax)-(px-ax)*(by-ay); - if(fabs(crossp) > J_EPS) return false; + // cross product to check if point i colinear + double crossp = (py-ay)*(bx-ax)-(px-ax)*(by-ay); + if(fabs(crossp) > J_EPS) return false; - // dotproduct and distSquared to check if point is in segment and not just in line - double dotp = (px-ax)*(bx-ax)+(py-ay)*(by-ay); - if(dotp < 0 || (_point1-_point2).NormSquare() < dotp) return false; + // dotproduct and distSquared to check if point is in segment and not just in line + double dotp = (px-ax)*(bx-ax)+(py-ay)*(by-ay); + if(dotp < 0 || (_point1-_point2).NormSquare() < dotp) return false; - return true; + return true; } @@ -276,21 +282,27 @@ bool Line::IsInLineSegment(const Point& p) const * */ double Line::DistTo(const Point& p) const { - return (p - ShortestPoint(p)).Norm(); + return (p - ShortestPoint(p)).Norm(); } double Line::DistToSquare(const Point& p) const { - return (p - ShortestPoint(p)).NormSquare(); + return (p - ShortestPoint(p)).NormSquare(); } +// bool Line::operator*(const Line& l) const { +// return ((_point1*l.GetPoint1() && _point2 == l.GetPoint2()) || +// (_point2 == l.GetPoint1() && _point1 == l.GetPoint2())); +// } + + /* Zwei Linien sind gleich, wenn ihre beiden Punkte * gleich sind * */ bool Line::operator==(const Line& l) const { - return ((_point1 == l.GetPoint1() && _point2 == l.GetPoint2()) || - (_point2 == l.GetPoint1() && _point1 == l.GetPoint2())); + return ((_point1 == l.GetPoint1() && _point2 == l.GetPoint2()) || + (_point2 == l.GetPoint1() && _point1 == l.GetPoint2())); } /* Zwei Linien sind ungleich, wenn ihre beiden Punkte @@ -298,202 +310,397 @@ bool Line::operator==(const Line& l) const * */ bool Line::operator!=(const Line& l) const { - return ((_point1 != l.GetPoint1() && _point2 != l.GetPoint2()) && - (_point2 != l.GetPoint1() && _point1 != l.GetPoint2())); + return ((_point1 != l.GetPoint1() && _point2 != l.GetPoint2()) && + (_point2 != l.GetPoint1() && _point1 != l.GetPoint2())); } double Line::Length() const { - return (_point1 - _point2).Norm(); + return (_point1 - _point2).Norm(); } double Line::LengthSquare() const { - return (_point1 - _point2).NormSquare(); + return (_point1 - _point2).NormSquare(); } bool Line::IntersectionWith(const Line& l) const { - //if(ShareCommonPointWith(l)) return true; + //if(ShareCommonPointWith(l)) return true; - double deltaACy = _point1.GetY() - l.GetPoint1().GetY(); - double deltaDCx = l.GetPoint2().GetX() - l.GetPoint1().GetX(); - double deltaACx = _point1.GetX() - l.GetPoint1().GetX(); - double deltaDCy = l.GetPoint2().GetY() - l.GetPoint1().GetY(); - double deltaBAx = _point2.GetX() - _point1.GetX(); - double deltaBAy = _point2.GetY() - _point1.GetY(); + double deltaACy = _point1.GetY() - l.GetPoint1().GetY(); + double deltaDCx = l.GetPoint2().GetX() - l.GetPoint1().GetX(); + double deltaACx = _point1.GetX() - l.GetPoint1().GetX(); + double deltaDCy = l.GetPoint2().GetY() - l.GetPoint1().GetY(); + double deltaBAx = _point2.GetX() - _point1.GetX(); + double deltaBAy = _point2.GetY() - _point1.GetY(); - double denominator = deltaBAx * deltaDCy - deltaBAy * deltaDCx; - double numerator = deltaACy * deltaDCx - deltaACx * deltaDCy; + double denominator = deltaBAx * deltaDCy - deltaBAy * deltaDCx; + double numerator = deltaACy * deltaDCx - deltaACx * deltaDCy; - // the lines are parallel - if (denominator == 0.0) { + // the lines are parallel + if (denominator == 0.0) { - // the lines are superposed - if (numerator == 0.0) { + // the lines are superposed + if (numerator == 0.0) { - // the segment are superposed - if(IsInLineSegment(l.GetPoint1()) || - IsInLineSegment(l.GetPoint2()) ) return true; - else return false; + // the segment are superposed + if(IsInLineSegment(l.GetPoint1()) || + IsInLineSegment(l.GetPoint2()) ) return true; + else return false; - } else { // the lines are just parallel and do not share a common point + } else { // the lines are just parallel and do not share a common point - return false; - } - } + return false; + } + } - // the lines intersect - double r = numerator / denominator; - if (r < 0.0 || r > 1.0) { - return false; - } + // the lines intersect + double r = numerator / denominator; + if (r < 0.0 || r > 1.0) { + return false; + } - double s = (deltaACy * deltaBAx - deltaACx * deltaBAy) / denominator; - if (s < 0.0 || s > 1.0) { - return false; - } + double s = (deltaACy * deltaBAx - deltaACx * deltaBAy) / denominator; + if (s < 0.0 || s > 1.0) { + return false; + } - //Point PointF = Point ((float) (_point1._x + r * deltaBAx), (float) (_point1._y + r * deltaBAy)); - //cout<< l.toString() << " intersects with " << toString() <<endl; - //cout<<" at point " << PointF.toString()<<endl; - return true; + //Point PointF = Point ((float) (_point1._x + r * deltaBAx), (float) (_point1._y + r * deltaBAy)); + //cout<< l.toString() << " intersects with " << toString() <<endl; + //cout<<" at point " << PointF.toString()<<endl; + return true; } bool Line::IsHorizontal() { - return fabs (_point1._y-_point2._y ) <= J_EPS; + return fabs (_point1._y-_point2._y ) <= J_EPS; } bool Line::IsVertical() { - return fabs (_point1._x-_point2._x ) <= J_EPS; + return fabs (_point1._x-_point2._x ) <= J_EPS; } int Line::WichSide(const Point& pt) { - //special case for horizontal lines - if (IsVertical()) { - //left - if (pt._x < _point1._x) - return 0; - //right or colinear - if (pt._x >= _point1._x) - return 1; - } + //special case for horizontal lines + if (IsVertical()) { + //left + if (pt._x < _point1._x) + return 0; + //right or colinear + if (pt._x >= _point1._x) + return 1; + } - return ((_point2._x - _point1._x) * (pt._y - _point1._y) - - (_point2._y - _point1._y) * (pt._x - _point1._x)) > 0; + return ((_point2._x - _point1._x) * (pt._y - _point1._y) + - (_point2._y - _point1._y) * (pt._x - _point1._x)) > 0; } bool Line::ShareCommonPointWith(const Line& line) const { - if(line.GetPoint1()==_point1) return true; - if(line.GetPoint2()==_point1) return true; + if(line.GetPoint1()==_point1) return true; + if(line.GetPoint2()==_point1) return true; - if(line.GetPoint1()==_point2) return true; - if(line.GetPoint2()==_point2) return true; + if(line.GetPoint1()==_point2) return true; + if(line.GetPoint2()==_point2) return true; - return false; + return false; } bool Line::HasEndPoint(const Point& point) const { - if (_point1==point) return true; - if (_point2==point) return true; - return false; + if (_point1==point) return true; + if (_point2==point) return true; + return false; } bool Line::IntersectionWithCircle(const Point& centre, double radius /*cm for pedestrians*/) { - double r=radius; - double x1=_point1.GetX(); - double y1=_point1.GetY(); + double r=radius; + double x1=_point1.GetX(); + double y1=_point1.GetY(); - double x2=_point2.GetX(); - double y2=_point2.GetY(); + double x2=_point2.GetX(); + double y2=_point2.GetY(); - double xc=centre.GetX(); - double yc=centre.GetY(); + double xc=centre.GetX(); + double yc=centre.GetY(); - //this formula assumes that the circle is centered the origin. - // so we translate the complete stuff such that the circle ends up at the origin - x1=x1-xc; - y1=y1-yc; - x2=x2-xc; - y2=y2-yc; - //xc=xc-xc;yc=yc-yc; to make it perfect + //this formula assumes that the circle is centered the origin. + // so we translate the complete stuff such that the circle ends up at the origin + x1=x1-xc; + y1=y1-yc; + x2=x2-xc; + y2=y2-yc; + //xc=xc-xc;yc=yc-yc; to make it perfect - // we first check the intersection of the circle and the infinite line defined by the segment - double dr2=((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1)); - double D2=(x1*y2-x2*y1)*(x1*y2-x2*y1); - double r2=radius*radius; + // we first check the intersection of the circle and the infinite line defined by the segment + double dr2=((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1)); + double D2=(x1*y2-x2*y1)*(x1*y2-x2*y1); + double r2=radius*radius; - double delta=r2*dr2-D2; - if(delta<=0.0) return false; + double delta=r2*dr2-D2; + if(delta<=0.0) return false; - double a=(x2-x1)*(x2-x1)+(y2-y1)*(y2-y1); - double b=2*((x1*(x2-x1))+y1*(y2-y1)); - double c=x1*x1+y1*y1-r*r; + double a=(x2-x1)*(x2-x1)+(y2-y1)*(y2-y1); + double b=2*((x1*(x2-x1))+y1*(y2-y1)); + double c=x1*x1+y1*y1-r*r; - delta=b*b-4*a*c; + delta=b*b-4*a*c; - if((x1==x2)&&(y1==y2)) { - Log->Write("isLineCrossingCircle: Your line is a point"); - return false; - } - if(delta<0.0) { - char tmp[CLENGTH]; - sprintf(tmp,"there is a bug in 'isLineCrossingCircle', delta(%f) can t be <0 at this point.",delta); - Log->Write(tmp); - Log->Write("press ENTER"); - return false; //fixme - //getc(stdin); - } + if((x1==x2)&&(y1==y2)) { + Log->Write("isLineCrossingCircle: Your line is a point"); + return false; + } + if(delta<0.0) { + char tmp[CLENGTH]; + sprintf(tmp,"there is a bug in 'isLineCrossingCircle', delta(%f) can t be <0 at this point.",delta); + Log->Write(tmp); + Log->Write("press ENTER"); + return false; //fixme + //getc(stdin); + } - double t1= (-b + sqrt(delta))/(2*a); - double t2= (-b - sqrt(delta))/(2*a); - if((t1<0.0) || (t1>1.0)) return false; - if((t2<0.0) || (t2>1.0)) return false; - return true; + double t1= (-b + sqrt(delta))/(2*a); + double t2= (-b - sqrt(delta))/(2*a); + if((t1<0.0) || (t1>1.0)) return false; + if((t2<0.0) || (t2>1.0)) return false; + return true; } //TODO: Consider numerical stability and special case pt is on line // Returns true if pt is on the left side ( from point1 toward point2) bool Line::IsLeft(const Point& pt) { - double test=(_point2._x-_point1._x)*(pt.GetY()-_point1._y)-(_point2._y-_point1._y)*(pt.GetX()-_point1._x); - if (test>0.0) - return true; - else - return false; + double test=(_point2._x-_point1._x)*(pt.GetY()-_point1._y)-(_point2._y-_point1._y)*(pt.GetX()-_point1._x); + if (test>0.0) + return true; + else + return false; } const Point& Line::GetLeft(const Point& pt) { - if (IsLeft(pt)) { - return _point2; - } else { - return _point1; - } + if (IsLeft(pt)) { + return _point2; + } else { + return _point1; + } } const Point& Line::GetRight(const Point& pt) { - if (!IsLeft(pt)) { - return _point2; - } else { - return _point1; - } + if (!IsLeft(pt)) { + return _point2; + } else { + return _point1; + } } std::string Line::toString() const { - std::stringstream tmp; - tmp<<_point1.toString()<<"--"<<_point2.toString(); - return tmp.str(); + std::stringstream tmp; + tmp<<_point1.toString()<<"--"<<_point2.toString(); + return tmp.str(); +} +// get distance between first point of line with the intersection point. +//if no intersection return infinity +// this function is exactly the same as GetIntersection(), but returns the distance squared +//insteed of a boolian +double Line::GetIntersectionDistance(const Line & l) const +{ + + double deltaACy = _point1.GetY() - l.GetPoint1().GetY(); + double deltaDCx = l.GetPoint2().GetX() - l.GetPoint1().GetX(); + double deltaACx = _point1.GetX() - l.GetPoint1().GetX(); + double deltaDCy = l.GetPoint2().GetY() - l.GetPoint1().GetY(); + double deltaBAx = _point2.GetX() - _point1.GetX(); + double deltaBAy = _point2.GetY() - _point1.GetY(); + + double denominator = deltaBAx * deltaDCy - deltaBAy * deltaDCx; + double numerator = deltaACy * deltaDCx - deltaACx * deltaDCy; + double infinity =100000; + // the lines are parallel + if (denominator == 0.0) { + + // the lines are superposed + if (numerator == 0.0) { + + // the segment are superposed + if(IsInLineSegment(l.GetPoint1()) || + IsInLineSegment(l.GetPoint2()) ) return infinity;//really? + else return infinity; + + } else { // the lines are just parallel and do not share a common point + + return infinity; + } + } + + // the lines intersect + double r = numerator / denominator; + if (r < 0.0 || r > 1.0) { + return infinity; + } + + double s = (deltaACy * deltaBAx - deltaACx * deltaBAy) / denominator; + if (s < 0.0 || s > 1.0) { + return infinity; + } + + Point PointF = Point ((float) (_point1._x + r * deltaBAx), (float) (_point1._y + r * deltaBAy)); + double dist = (_point1-PointF).NormSquare(); + //cout<< " MC Line.cpp 516" << l.toString() << " intersects with " << toString() <<endl; + //cout<<" at point " << PointF.toString()<<endl; + //cout << "distance is "<< sqrt(dist)<< "... return "<< dist<<endl; + return dist; + } +//sign of the angle depends on the direction of the wall (l). +//the second point of l should be the nearest to the goal. +//the goal in the intended use case is the second point of +//the calling line +// +double Line::GetAngle(const Line & l) const +{ + const double pi= atan(1)*4; + double ax = _point1.GetX(); + double ay = _point1.GetY(); + double bx = _point2.GetX(); + double by = _point2.GetY(); + //printf("ax=%f, ay=%f --- bx=%f, by=%f\n", ax, ay, bx, by); + double diff_x1 = bx - ax; + double diff_y1 = by - ay; + // printf("diff_x1=%f, diff_y1=%f\n", diff_x1, diff_y1); + double cx =l.GetPoint1().GetX(); + double cy =l.GetPoint1().GetY(); + double dx =l.GetPoint2().GetX(); + double dy =l.GetPoint2().GetY(); + //printf("cx=%f, cy=%f --- dx=%f, dy=%f\n", cx, cy, dx, dy); + + double diff_x2 = dx - cx; + double diff_y2 = dy - cy; + // printf("diff_x2=%f, diff_y2=%f\n", diff_x2, diff_y2); + + double atanA = atan2( diff_y1, diff_x1 ); + double atanB = atan2( diff_y2, diff_x2); + +// printf("atanA %f atanB %f\n", atanA*180/pi, atanB*180/pi); + double angle = atanA - atanB; + + + double absAngle= fabs(angle); + double sign = (angle <0)? -1.0 : 1.0; + + + // if (angle>pi) + // printf( "NORMALIZE --> %.2f\n", (2*pi-angle)*180/pi); + angle = (angle>pi)? -(2*pi-absAngle): angle; + //printf("angle=%.2f, absAngle=%.2f, sign=%.1f\n", angle*180/pi, absAngle, sign); + + absAngle= fabs(angle); + double tmp = (absAngle<pi/2)? (-angle) : (pi-absAngle)*sign; + + //printf("tmp=%.2f exp=%.2f\n", tmp, (pi-absAngle)*sign); + + // 3pi/4 ----> pi/4 (sign=1) + // -3pi/4 ----> -pi/4 (sign=-1) + // pi/4 ----> -pi/4 + // -pi/4 ----> pi/4 + + return tmp; + + + + // double distPoint2ToGoalSq = (dx-bx)*(dx-bx) + (dy-by)*(dy-by); + // double distPoint1ToGoalSq = (cx-bx)*(cx-bx) + (cy-by)*(cy-by); + // if(distPoint1ToGoalSq < distPoint2ToGoalSq) //invert the line + // { + // double tx = dx, ty = dy; + // dx = cx; dy = cy; + // cx = tx; cy = ty; + // } + + // double dotp = (bx-ax)*(dx-cx)+(by-ay)*(dy-cy); + // double len, len1; + + // len = l.Length(); + // if (len < J_EPS) + // return 0; + + // len1 = this->Length(); + + // if (len1 < J_EPS) + // return 0; + + + // double angle = acos( dotp / (len * len1) ); + // double crossp = (bx-ax)*(dy-cy) - (by-ay)*(dx-cx); + // double sign = (crossp <0)? -1.0 : 1.0; + + + + // angle = (angle<pi/2)?angle:pi-angle; + // return angle*sign; + +} + +// get the angle that is needed to turn a line, so that it +// doen not intersect the nearest Wall in subroom +// double Line::GetAngle(SubRoom * subroom) const{ +// double dist; +// int inear = -1; +// int iObs = -1; +// double minDist = 20001; +// //============================ WALLS =========================== +// const vector<Wall>& walls = subroom->GetAllWalls(); +// for (int i = 0; i < subroom->GetNumberOfWalls(); i++) { +// dist = tmpDirection.GetIntersectionDistance(walls[i]); +// printf("Check wall %d. Dist = %f (%f)\n", i, dist, minDist); +// if (dist < minDist) +// { +// inear = i; +// minDist = dist; +// } +// }//walls +// //============================ WALLS =========================== + +// //============================ OBST =========================== +// const vector<Obstacle*>& obstacles = subroom->GetAllObstacles(); +// for(unsigned int obs=0; obs<obstacles.size(); ++obs){ +// const vector<Wall>& owalls = obstacles[obs]->GetAllWalls(); +// for (unsigned int i = 0; i < owalls.size(); i++) { +// dist = tmpDirection.GetIntersectionDistance(owalls[i]); +// printf("Check OBS:obs=%d, i=%d Dist = %f (%f)\n", obs, i, dist, minDist); +// if (dist < minDist) +// { +// inear = i; +// minDist = dist; +// iObs = obs; +// } +// }//walls of obstacle +// }// obstacles +// //============================ OBST =========================== +// //------------------------------------------------------------------------ + +// double angle = 0; +// if (inear >= 0) +// if(iObs >= 0) +// { +// const vector<Wall>& owalls = obstacles[iObs]->GetAllWalls(); +// angle = tmpDirection.GetAngle(owalls[inear]); +// } +// else +// angle = tmpDirection.GetAngle(walls[inear]); + + + +// return angle + +// } diff --git a/src/geometry/Line.h b/src/geometry/Line.h index 1dbf40722a37a3ecc5e4784a9fca36ae65b9f16f..6c9577fbe245e9a05234aca23faf546b3d3f68f4 100644 --- a/src/geometry/Line.h +++ b/src/geometry/Line.h @@ -1,13 +1,14 @@ /** - * File: Line.h + * \file Line.h + * \date Sep 30, 2010 + * \version v0.5 + * \copyright <2009-2014> Forschungszentrum Jülich GmbH. All rights reserved. * - * Created on 30. September 2010, 09:40 - * - * @section LICENSE + * \section License * This file is part of JuPedSim. * * JuPedSim is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by + * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * @@ -16,23 +17,26 @@ * 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 + * You should have received a copy of the GNU Lesser General Public License * along with JuPedSim. If not, see <http://www.gnu.org/licenses/>. * - * @section DESCRIPTION - * + * \section Description * * - */ + **/ + #ifndef _LINE_H -#define _LINE_H +#define _LINE_H #include "Point.h" #include "../IO/OutputHandler.h" + #include <string> +//forward declarations +class OutputHandler; // external variables extern OutputHandler* Log; @@ -40,183 +44,199 @@ extern OutputHandler* Log; class Line { private: - Point _point1; - Point _point2; - Point _centre; + Point _point1; + Point _point2; + Point _centre; - //unique identifier for all line elements - static int _static_UID; - int _uid; + //unique identifier for all line elements + static int _static_UID; + int _uid; public: - Line(); - Line(const Point& p1, const Point& p2); - Line(const Line& orig); - virtual ~Line(); - - /** - * All Line elements (also derived class) have a unique ID - * @return the unique ID of this line element. - */ - int GetUniqueID() const; - - /** - * Set/Get the first end point of the line - */ - void SetPoint1(const Point& p); - - /** - * Set/Get the second end point of the line - */ - void SetPoint2(const Point& p); - - /** - * Set/Get the first end point of the line - */ - const Point& GetPoint1(void) const; - - /** - * Set/Get the second end point of the line - */ - const Point& GetPoint2(void) const; - - /** - * Return the center of the line - */ - const Point& GetCentre(void) const; - - /** - * @return a normal vector to this line - */ - Point NormalVec() const; // Normalen_Vector zu Line - - /** - *TODO: FIXME - */ - double NormalComp(const Point& v) const; // Normale Komponente von v auf l - - /** - * Note that that result must not lie on the segment - * @return the orthogonal projection of p on the line defined by the segment points. - */ - Point LotPoint(const Point& p) const; - - /** - * @return the point on the segment with the minimum distance to p - */ - Point ShortestPoint(const Point& p) const; - - /** - * @return true if the point p lies on the line defined by the first and the second point - */ - bool IsInLine(const Point& p) const; - - /** - * @see IsInLine - * @return true if the point p is within the line segment defined the line end points - */ - bool IsInLineSegment(const Point& p) const; - - /** - * @return the distance from the line to the point p - */ - double DistTo(const Point& p) const; - - /** - * @return the distance square from the line to the point p - */ - double DistToSquare(const Point& p) const; - - /** - * @return the length (Norm) of the line - */ - double Length() const; - - /** - * @return the lenght square of the segment - */ - double LengthSquare() const; - - /** - * @return true if both segments are equal. The end points must be in the range of J_EPS. - * @see Macro.h - */ - bool operator==(const Line& l) const; - - /** - * @return true if both segments are not equal. The end points must be in the range of J_EPS. - * @see Macro.h - */ - bool operator!=(const Line& l) const; - - /** - * @see http://alienryderflex.com/intersect/ - * @see http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/e5993847-c7a9-46ec-8edc-bfb86bd689e3/ - * @return true if both segments intersect - */ - bool IntersectionWith(const Line& l) const; // check two segments for intersections - - /** - * @return true if the segment intersects with the circle of radius r - */ - bool IntersectionWithCircle(const Point& centre, double radius=0.30 /*m for pedestrians*/); - - - /** - * @return true if both segments share at least one common point - */ - bool ShareCommonPointWith(const Line& line) const; - - /** - * @return true if the given point is one end point of the segment - */ - bool HasEndPoint(const Point& point) const; - - /** - * return the same value if the checked points are all situated on the same side. - * @return 0 or 1 depending on which side of the line the point is located. - */ - int WichSide (const Point& pt); - - /** - * @return true if the point is located in the left hand side of the line. - * For horizontal lines return true if the point is above the line. - */ - bool IsLeft (const Point& pt); - - /** - * @return true for horizontal lines - */ - bool IsHorizontal(); - - /** - * @return true for vertical lines - */ - bool IsVertical(); - - /** - * @return left point wrt. the point pt - */ - const Point& GetLeft(const Point& pt); - - /** - * @return left point wrt. the point pt - */ - const Point& GetRight(const Point& pt); - - /** - * @return a nice formated string describing the line - */ - virtual std::string Write() const; - - /** - * @return a nice formated string describing the line - */ - std::string toString() const; - + Line(); + Line(const Point& p1, const Point& p2); + Line(const Line& orig); + virtual ~Line(); + + /** + * All Line elements (also derived class) have a unique ID + * @return the unique ID of this line element. + */ + int GetUniqueID() const; + + /** + * Set/Get the first end point of the line + */ + void SetPoint1(const Point& p); + + /** + * Set/Get the second end point of the line + */ + void SetPoint2(const Point& p); + + /** + * Set/Get the first end point of the line + */ + const Point& GetPoint1(void) const; + + /** + * Set/Get the second end point of the line + */ + const Point& GetPoint2(void) const; + + /** + * Return the center of the line + */ + const Point& GetCentre(void) const; + + /** + * @return a normal vector to this line + */ + Point NormalVec() const; // Normalen_Vector zu Line + + /** + *TODO: FIXME + */ + double NormalComp(const Point& v) const; // Normale Komponente von v auf l + + /** + * Note that that result must not lie on the segment + * @return the orthogonal projection of p on the line defined by the segment points. + */ + Point LotPoint(const Point& p) const; + + /** + * @return the point on the segment with the minimum distance to p + */ + Point ShortestPoint(const Point& p) const; + + /** + * @return true if the point p lies on the line defined by the first and the second point + */ + bool IsInLine(const Point& p) const; + + /** + * @see IsInLine + * @return true if the point p is within the line segment defined the line end points + */ + bool IsInLineSegment(const Point& p) const; + + /** + * @return the distance from the line to the point p + */ + double DistTo(const Point& p) const; + + /** + * @return the distance square from the line to the point p + */ + double DistToSquare(const Point& p) const; + + /** + * @return the length (Norm) of the line + */ + double Length() const; + + /** + * @return the lenght square of the segment + */ + double LengthSquare() const; + + // + // @return dot product of two lines + // bool operator*(const Line& l) const; + + /** + * @return true if both segments are equal. The end points must be in the range of J_EPS. + * @see Macro.h + */ + bool operator==(const Line& l) const; + + /** + * @return true if both segments are not equal. The end points must be in the range of J_EPS. + * @see Macro.h + */ + bool operator!=(const Line& l) const; + + /** + * @see http://alienryderflex.com/intersect/ + * @see http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/e5993847-c7a9-46ec-8edc-bfb86bd689e3/ + * @return true if both segments intersect + */ + bool IntersectionWith(const Line& l) const; // check two segments for intersections + + /** + * @return the distance squared between the first point and the intersection + * point with line l. This is exactly the same function + * as @see IntersectionWith() but returns a double insteed. + */ + double GetIntersectionDistance(const Line & l ) const; + + /** + * @return true if the segment intersects with the circle of radius r + */ + bool IntersectionWithCircle(const Point& centre, double radius=0.30 /*m for pedestrians*/); + + + /** + * @return true if both segments share at least one common point + */ + bool ShareCommonPointWith(const Line& line) const; + + /** + * @return true if the given point is one end point of the segment + */ + bool HasEndPoint(const Point& point) const; + + /** + * return the same value if the checked points are all situated on the same side. + * @return 0 or 1 depending on which side of the line the point is located. + */ + int WichSide (const Point& pt); + + /** + * @return true if the point is located in the left hand side of the line. + * For horizontal lines return true if the point is above the line. + */ + bool IsLeft (const Point& pt); + + /** + * @return true for horizontal lines + */ + bool IsHorizontal(); + + /** + * @return true for vertical lines + */ + bool IsVertical(); + + /** + * @return left point wrt. the point pt + */ + const Point& GetLeft(const Point& pt); + + /** + * @return left point wrt. the point pt + */ + const Point& GetRight(const Point& pt); + + /** + * @return a nice formated string describing the line + */ + virtual std::string Write() const; + + /** + * @return a nice formated string describing the line + */ + std::string toString() const; + + /** + * @return the angle between two lines + */ + double GetAngle(const Line& l) const; + // double GetAngle(SubRoom s) const; }; -#endif /* _LINE_H */ +#endif /* _LINE_H */ diff --git a/src/geometry/LinePlotter2D.cpp b/src/geometry/LinePlotter2D.cpp index c7cc41924180fa704c4850bb05b44d2b91a6d137..6db4b9facb66cf256a214ca32d0317a3f88034b5 100644 --- a/src/geometry/LinePlotter2D.cpp +++ b/src/geometry/LinePlotter2D.cpp @@ -100,7 +100,6 @@ LinePlotter2D::LinePlotter2D() LinePlotter2D::~LinePlotter2D() { - m_lookupTable->Delete(); assembly->Delete(); door_points->Delete(); @@ -113,6 +112,11 @@ LinePlotter2D::~LinePlotter2D() wall_lineScalars->Delete(); wall_mapper->Delete(); wall_actor->Delete(); + navline_points->Delete(); + navline_lines->Delete(); + navline_lineScalars->Delete(); + navline_mapper->Delete(); + navline_actor->Delete(); } void LinePlotter2D::SetAllLineWidth(int width) diff --git a/src/geometry/NavLine.cpp b/src/geometry/NavLine.cpp index 5f3cfc37aafc9b4e8b26c92ff51a3ad68f280b8d..1e3dfb7c9704a1768466738e4075a6922d440f98 100644 --- a/src/geometry/NavLine.cpp +++ b/src/geometry/NavLine.cpp @@ -1,14 +1,14 @@ /** - * NavLine.cpp + * \file NavLine.cpp + * \date Aug 30, 2012 + * \version v0.5 + * \copyright <2009-2014> Forschungszentrum Jülich GmbH. All rights reserved. * - * Created on: Aug 30, 2012 - * - * - * @section LICENSE + * \section License * This file is part of JuPedSim. * * JuPedSim is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by + * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * @@ -17,14 +17,14 @@ * 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 + * You should have received a copy of the GNU Lesser General Public License * along with JuPedSim. If not, see <http://www.gnu.org/licenses/>. * - * @section DESCRIPTION + * \section Description * * - * - */ + **/ + #include "NavLine.h" diff --git a/src/geometry/NavLine.h b/src/geometry/NavLine.h index 8e82cc7aa7a7c93d93b135795fe89960602abe9a..5db0e19e9694cf2a4c8a52b3d0c0be947cd0d26a 100644 --- a/src/geometry/NavLine.h +++ b/src/geometry/NavLine.h @@ -1,14 +1,14 @@ /** - * NavLine.h + * \file NavLine.h + * \date Aug 30, 2012 + * \version v0.5 + * \copyright <2009-2014> Forschungszentrum Jülich GmbH. All rights reserved. * - * Created on: Aug 30, 2012 - * - * - * @section LICENSE + * \section License * This file is part of JuPedSim. * * JuPedSim is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by + * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * @@ -17,14 +17,14 @@ * 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 + * You should have received a copy of the GNU Lesser General Public License * along with JuPedSim. If not, see <http://www.gnu.org/licenses/>. * - * @section DESCRIPTION - * + * \section Description * * - */ + **/ + #ifndef NAVLINE_H_ #define NAVLINE_H_ @@ -33,9 +33,9 @@ class NavLine: public Line { public: - NavLine(); - NavLine(Line l); - virtual ~NavLine(); + NavLine(); + NavLine(Line l); + virtual ~NavLine(); }; diff --git a/src/geometry/Obstacle.cpp b/src/geometry/Obstacle.cpp index 564527a31cc418b29822d35a19f20a95414f9585..93cd9a1b60f0df3a39732f37580c30d8b161bf9d 100644 --- a/src/geometry/Obstacle.cpp +++ b/src/geometry/Obstacle.cpp @@ -1,14 +1,14 @@ /** - * Obstacle.cpp + * \file Obstacle.cpp + * \date Jul 31, 2012 + * \version v0.5 + * \copyright <2009-2014> Forschungszentrum Jülich GmbH. All rights reserved. * - * Created on: Jul 31, 2012 - * - * - * @section LICENSE + * \section License * This file is part of JuPedSim. * * JuPedSim is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by + * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * @@ -17,14 +17,14 @@ * 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 + * You should have received a copy of the GNU Lesser General Public License * along with JuPedSim. If not, see <http://www.gnu.org/licenses/>. * - * @section DESCRIPTION - * + * \section Description * * - */ + **/ + #include "Obstacle.h" @@ -46,12 +46,12 @@ using namespace std; Obstacle::Obstacle() { - _isClosed=0.0; - _height=0.0; - _id=-1; - _caption="obstacle"; - _walls = vector<Wall > (); - _poly = vector<Point > (); + _isClosed=0.0; + _height=0.0; + _id=-1; + _caption="obstacle"; + _walls = vector<Wall > (); + _poly = vector<Point > (); } Obstacle::~Obstacle() {} @@ -59,254 +59,255 @@ Obstacle::~Obstacle() {} void Obstacle::AddWall(const Wall& w) { - _walls.push_back(w); + _walls.push_back(w); } string Obstacle::GetCaption() const { - return _caption; + return _caption; } void Obstacle::SetCaption(string caption) { - _caption = caption; + _caption = caption; } double Obstacle::GetClosed() const { - return _isClosed; + return _isClosed; } void Obstacle::SetClosed(double closed) { - _isClosed = closed; + _isClosed = closed; } double Obstacle::GetHeight() const { - return _height; + return _height; } void Obstacle::SetHeight(double height) { - _height = height; + _height = height; } int Obstacle::GetId() const { - return _id; + return _id; } void Obstacle::SetId(int id) { - _id = id; + _id = id; } const vector<Point>& Obstacle::GetPolygon() const { - return _poly; + return _poly; } string Obstacle::Write() { - string s; - //Point pos; + string s; + //Point pos; - for (unsigned int j = 0; j < _walls.size(); j++) { - const Wall& w = _walls[j]; - s.append(w.Write()); - //pos = pos + w.GetPoint1() + w.GetPoint2(); - } - //pos = pos * (0.5 / _walls.size()); + for (unsigned int j = 0; j < _walls.size(); j++) { + const Wall& w = _walls[j]; + s.append(w.Write()); + //pos = pos + w.GetPoint1() + w.GetPoint2(); + } + //pos = pos * (0.5 / _walls.size()); - Point pos = GetCentroid(); + Point pos = GetCentroid(); - //add the obstacle caption - char tmp[CLENGTH]; - //sprintf(tmp, "\t\t<label centerX=\"%.2f\" centerY=\"%.2f\" centerZ=\"0\" text=\"%s\" color=\"100\" />\n" - // , pos.GetX() * FAKTOR, pos.GetY() * FAKTOR, _caption.c_str()); + //add the obstacle caption + char tmp[CLENGTH]; + //sprintf(tmp, "\t\t<label centerX=\"%.2f\" centerY=\"%.2f\" centerZ=\"0\" text=\"%s\" color=\"100\" />\n" + // , pos.GetX() * FAKTOR, pos.GetY() * FAKTOR, _caption.c_str()); - sprintf(tmp, "\t\t<label centerX=\"%.2f\" centerY=\"%.2f\" centerZ=\"0\" text=\"%d\" color=\"100\" />\n" - , pos.GetX() * FAKTOR, pos.GetY() * FAKTOR, _id); - s.append(tmp); + sprintf(tmp, "\t\t<label centerX=\"%.2f\" centerY=\"%.2f\" centerZ=\"0\" text=\"%d\" color=\"100\" />\n" + , pos.GetX() * FAKTOR, pos.GetY() * FAKTOR, _id); + s.append(tmp); - return s; + return s; } const vector<Wall>& Obstacle::GetAllWalls() const { - return _walls; + return _walls; } int Obstacle::WhichQuad(const Point& vertex, const Point& hitPos) const { - return (vertex.GetX() > hitPos.GetX()) ? ((vertex.GetY() > hitPos.GetY()) ? 1 : 4) : - ((vertex.GetY() > hitPos.GetY()) ? 2 : 3); + return (vertex.GetX() > hitPos.GetX()) ? ((vertex.GetY() > hitPos.GetY()) ? 1 : 4) : + ((vertex.GetY() > hitPos.GetY()) ? 2 : 3); } // x-Koordinate der Linie von einer Eccke zur nächsten double Obstacle::Xintercept(const Point& point1, const Point& point2, double hitY) const { - return (point2.GetX() - (((point2.GetY() - hitY) * (point1.GetX() - point2.GetX())) / - (point1.GetY() - point2.GetY()))); + return (point2.GetX() - (((point2.GetY() - hitY) * (point1.GetX() - point2.GetX())) / + (point1.GetY() - point2.GetY()))); } bool Obstacle::Contains(const Point& ped) const { - // in the case the obstacle is not a close surface, allow - // pedestrians distribution 'inside' - if(_isClosed==0.0) { - char tmp[CLENGTH]; - sprintf(tmp, "ERROR: \tObstacle::Contains(): the obstacle [%d] is open!!!\n", _id); - Log->Write(tmp); - exit(EXIT_FAILURE); - } - - short edge, first, next; - short quad, next_quad, delta, total; - - ///////////////////////////////////////////////////////////// - edge = first = 0; - quad = WhichQuad(_poly[edge], ped); - total = 0; // COUNT OF ABSOLUTE SECTORS CROSSED - /* LOOP THROUGH THE VERTICES IN A SECTOR */ - do { - next = (edge + 1) % _poly.size(); - next_quad = WhichQuad(_poly[next], ped); - delta = next_quad - quad; // HOW MANY QUADS HAVE I MOVED - - // SPECIAL CASES TO HANDLE CROSSINGS OF MORE THEN ONE - //QUAD - - switch (delta) { - case 2: // IF WE CROSSED THE MIDDLE, FIGURE OUT IF IT - //WAS CLOCKWISE OR COUNTER - case -2: // US THE X POSITION AT THE HIT POINT TO - // DETERMINE WHICH WAY AROUND - if (Xintercept(_poly[edge], _poly[next], ped.GetY()) > ped.GetX()) - delta = -(delta); - break; - case 3: // MOVING 3 QUADS IS LIKE MOVING BACK 1 - delta = -1; - break; - case -3: // MOVING BACK 3 IS LIKE MOVING FORWARD 1 - delta = 1; - break; - } - /* ADD IN THE DELTA */ - total += delta; - quad = next_quad; // RESET FOR NEXT STEP - edge = next; - } while (edge != first); - - /* AFTER ALL IS DONE IF THE TOTAL IS 4 THEN WE ARE INSIDE */ - if (abs(total) == 4) - return true; - else - return false; + // in the case the obstacle is not a close surface, allow + // pedestrians distribution 'inside' + if(_isClosed==0.0) { + char tmp[CLENGTH]; + sprintf(tmp, "ERROR: \tObstacle::Contains(): the obstacle [%d] is open!!!\n", _id); + Log->Write(tmp); + exit(EXIT_FAILURE); + } + + short edge, first, next; + short quad, next_quad, delta, total; + + ///////////////////////////////////////////////////////////// + edge = first = 0; + quad = WhichQuad(_poly[edge], ped); + total = 0; // COUNT OF ABSOLUTE SECTORS CROSSED + /* LOOP THROUGH THE VERTICES IN A SECTOR */ + do { + next = (edge + 1) % _poly.size(); + next_quad = WhichQuad(_poly[next], ped); + delta = next_quad - quad; // HOW MANY QUADS HAVE I MOVED + + // SPECIAL CASES TO HANDLE CROSSINGS OF MORE THEN ONE + //QUAD + + switch (delta) { + case 2: // IF WE CROSSED THE MIDDLE, FIGURE OUT IF IT + //WAS CLOCKWISE OR COUNTER + case -2: // US THE X POSITION AT THE HIT POINT TO + // DETERMINE WHICH WAY AROUND + if (Xintercept(_poly[edge], _poly[next], ped.GetY()) > ped.GetX()) + delta = -(delta); + break; + case 3: // MOVING 3 QUADS IS LIKE MOVING BACK 1 + delta = -1; + break; + case -3: // MOVING BACK 3 IS LIKE MOVING FORWARD 1 + delta = 1; + break; + } + /* ADD IN THE DELTA */ + total += delta; + quad = next_quad; // RESET FOR NEXT STEP + edge = next; + } while (edge != first); + + /* AFTER ALL IS DONE IF THE TOTAL IS 4 THEN WE ARE INSIDE */ + if (abs(total) == 4) + return true; + else + return false; } bool Obstacle::ConvertLineToPoly() { - - if(_isClosed==0.0) { - char tmp[CLENGTH]; - sprintf(tmp, "INFO: \tObstacle [%d] is not closed. Not converting to polyline.\n", _id); - Log->Write(tmp); - return true; - } - vector<Line*> copy; - vector<Point> tmpPoly; - Point point; - Line* line; - // Alle Linienelemente in copy speichern - for (unsigned int i = 0; i < _walls.size(); i++) { - copy.push_back(&_walls[i]); - } - - line = copy[0]; - tmpPoly.push_back(line->GetPoint1()); - point = line->GetPoint2(); - copy.erase(copy.begin()); - // Polygon aus allen Linen erzeugen - for (int i = 0; i < (int) copy.size(); i++) { - line = copy[i]; - if ((point - line->GetPoint1()).Norm() < J_TOLERANZ) { - tmpPoly.push_back(line->GetPoint1()); - point = line->GetPoint2(); - copy.erase(copy.begin() + i); - // von vorne suchen - i = -1; - } else if ((point - line->GetPoint2()).Norm() < J_TOLERANZ) { - tmpPoly.push_back(line->GetPoint2()); - point = line->GetPoint1(); - copy.erase(copy.begin() + i); - // von vorne suchen - i = -1; - } - } - if ((tmpPoly[0] - point).Norm() > J_TOLERANZ) { - char tmp[CLENGTH]; - sprintf(tmp, "ERROR: \tObstacle::ConvertLineToPoly(): ID %d !!!\n", _id); - Log->Write(tmp); - return false; - } - _poly = tmpPoly; - return true; + if(_isClosed==0.0) + { + char tmp[CLENGTH]; + sprintf(tmp, "INFO: \tObstacle [%d] is not closed. Not converting to polyline.\n", _id); + Log->Write(tmp); + return true; + } + + vector<Line*> copy; + vector<Point> tmpPoly; + Point point; + Line* line; + // Alle Linienelemente in copy speichern + for (unsigned int i = 0; i < _walls.size(); i++) { + copy.push_back(&_walls[i]); + } + + line = copy[0]; + tmpPoly.push_back(line->GetPoint1()); + point = line->GetPoint2(); + copy.erase(copy.begin()); + // Polygon aus allen Linen erzeugen + for (int i = 0; i < (int) copy.size(); i++) { + line = copy[i]; + if ((point - line->GetPoint1()).Norm() < J_TOLERANZ) { + tmpPoly.push_back(line->GetPoint1()); + point = line->GetPoint2(); + copy.erase(copy.begin() + i); + // von vorne suchen + i = -1; + } else if ((point - line->GetPoint2()).Norm() < J_TOLERANZ) { + tmpPoly.push_back(line->GetPoint2()); + point = line->GetPoint1(); + copy.erase(copy.begin() + i); + // von vorne suchen + i = -1; + } + } + if ((tmpPoly[0] - point).Norm() > J_TOLERANZ) { + char tmp[CLENGTH]; + sprintf(tmp, "ERROR: \tObstacle::ConvertLineToPoly(): ID %d !!!\n", _id); + Log->Write(tmp); + return false; + } + _poly = tmpPoly; + return true; } const Point Obstacle::GetCentroid() const { - double px=0,py=0; - double signedArea = 0.0; - double x0 = 0.0; // Current vertex X - double y0 = 0.0; // Current vertex Y - double x1 = 0.0; // Next vertex X - double y1 = 0.0; // Next vertex Y - double a = 0.0; // Partial signed area - - // For all vertices except last - unsigned int i=0; - for (i=0; i<_poly.size()-1; ++i) { - x0 = _poly[i].GetX(); - y0 = _poly[i].GetY(); - x1 = _poly[i+1].GetX(); - y1 = _poly[i+1].GetY(); - a = x0*y1 - x1*y0; - signedArea += a; - px += (x0 + x1)*a; - py += (y0 + y1)*a; - } - - // Do last vertex - x0 = _poly[i].GetX(); - y0 = _poly[i].GetY(); - x1 = _poly[0].GetX(); - y1 = _poly[0].GetY(); - a = x0*y1 - x1*y0; - signedArea += a; - px += (x0 + x1)*a; - py += (y0 + y1)*a; - - signedArea *= 0.5; - px /= (6*signedArea); - py /= (6*signedArea); - - return Point (px,py); + double px=0,py=0; + double signedArea = 0.0; + double x0 = 0.0; // Current vertex X + double y0 = 0.0; // Current vertex Y + double x1 = 0.0; // Next vertex X + double y1 = 0.0; // Next vertex Y + double a = 0.0; // Partial signed area + + // For all vertices except last + unsigned int i=0; + for (i=0; i<_poly.size()-1; ++i) { + x0 = _poly[i].GetX(); + y0 = _poly[i].GetY(); + x1 = _poly[i+1].GetX(); + y1 = _poly[i+1].GetY(); + a = x0*y1 - x1*y0; + signedArea += a; + px += (x0 + x1)*a; + py += (y0 + y1)*a; + } + + // Do last vertex + x0 = _poly[i].GetX(); + y0 = _poly[i].GetY(); + x1 = _poly[0].GetX(); + y1 = _poly[0].GetY(); + a = x0*y1 - x1*y0; + signedArea += a; + px += (x0 + x1)*a; + py += (y0 + y1)*a; + + signedArea *= 0.5; + px /= (6*signedArea); + py /= (6*signedArea); + + return Point (px,py); } bool Obstacle::IntersectWithLine(const Line& line) const { - for (unsigned int i=0; i<_walls.size(); i++) { + for (unsigned int i=0; i<_walls.size(); i++) { - if(_walls[i].IntersectionWith(line)) return true; - } + if(_walls[i].IntersectionWith(line)) return true; + } - return false; + return false; } diff --git a/src/geometry/Obstacle.h b/src/geometry/Obstacle.h index d682707977966a04fed7696f637936817325b547..9302a9563d1c98ec1f5127487c2da81492cf1c31 100644 --- a/src/geometry/Obstacle.h +++ b/src/geometry/Obstacle.h @@ -1,14 +1,14 @@ /** - * Obstacle.h + * \file Obstacle.h + * \date Jul 31, 2012 + * \version v0.5 + * \copyright <2009-2014> Forschungszentrum Jülich GmbH. All rights reserved. * - * Created on: Jul 31, 2012 - * - * - * @section LICENSE + * \section License * This file is part of JuPedSim. * * JuPedSim is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by + * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * @@ -17,14 +17,14 @@ * 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 + * You should have received a copy of the GNU Lesser General Public License * along with JuPedSim. If not, see <http://www.gnu.org/licenses/>. * - * @section DESCRIPTION - * + * \section Description * * - */ + **/ + #ifndef OBSTACLE_H_ #define OBSTACLE_H_ @@ -32,114 +32,115 @@ #include <string> #include <vector> -#include "Point.h" -#include "Wall.h" - +//forward declarations +class Point; +class Wall; +class Line; class Obstacle { private: - double _isClosed; - double _height; - int _id; - std::string _caption; - std::vector<Wall> _walls; - std::vector<Point> _poly; + double _isClosed; + double _height; + int _id; + std::string _caption; + std::vector<Wall> _walls; + std::vector<Point> _poly; public: - Obstacle(); - virtual ~Obstacle(); - - /** - * Set/Get the obstacles' caption - */ - std::string GetCaption() const; - - /** - * Set/Get the obstacles' caption - */ - void SetCaption(std::string caption); - - /** - * Set/Get the close state of the obstacle - */ - double GetClosed() const; - - /** - * Set/Get the close state of the obstacle - */ - void SetClosed(double closed); - - /** - * Set/Get the height of the obstacle. - * Is used for computing visibility - */ - double GetHeight() const; - - /** - * Set/Get the height of the obstacle. - * Is used for computing visibility - */ - void SetHeight(double height); - - /** - * Set/Get the id of the obstacle - */ - int GetId() const; - - /** - * Set/Get the id of the obstacle - */ - void SetId(int id); - - /** - * construct the obstacle by adding more walls - */ - void AddWall(const Wall& w); - - /** - * @return All walls that constitute the obstacle - */ - const std::vector<Wall>& GetAllWalls() const; - - /** - * @return true if the point p is contained within the Closed Obstacle - * @see Setclose - */ - bool Contains(const Point& p) const; - - /** - * Create the obstacles polygonal structure from the walls - */ - bool ConvertLineToPoly(); - - /** - * @return the obstacle as a polygon - */ - const std::vector<Point>& GetPolygon() const; - - /** - * @return the centroid of the obstacle - */ - const Point GetCentroid() const; - - /** - * return true if the given line intersects - * or share common vertex with the obstacle - */ - bool IntersectWithLine(const Line & line) const; - - /** - * @return a nicely formatted string representation of the obstacle - */ - std::string Write(); + Obstacle(); + virtual ~Obstacle(); + + /** + * Set/Get the obstacles' caption + */ + std::string GetCaption() const; + + /** + * Set/Get the obstacles' caption + */ + void SetCaption(std::string caption); + + /** + * Set/Get the close state of the obstacle + */ + double GetClosed() const; + + /** + * Set/Get the close state of the obstacle + */ + void SetClosed(double closed); + + /** + * Set/Get the height of the obstacle. + * Is used for computing visibility + */ + double GetHeight() const; + + /** + * Set/Get the height of the obstacle. + * Is used for computing visibility + */ + void SetHeight(double height); + + /** + * Set/Get the id of the obstacle + */ + int GetId() const; + + /** + * Set/Get the id of the obstacle + */ + void SetId(int id); + + /** + * construct the obstacle by adding more walls + */ + void AddWall(const Wall& w); + + /** + * @return All walls that constitute the obstacle + */ + const std::vector<Wall>& GetAllWalls() const; + + /** + * @return true if the point p is contained within the Closed Obstacle + * @see Setclose + */ + bool Contains(const Point& p) const; + + /** + * Create the obstacles polygonal structure from the walls + */ + bool ConvertLineToPoly(); + + /** + * @return the obstacle as a polygon + */ + const std::vector<Point>& GetPolygon() const; + + /** + * @return the centroid of the obstacle + */ + const Point GetCentroid() const; + + /** + * return true if the given line intersects + * or share common vertex with the obstacle + */ + bool IntersectWithLine(const Line & line) const; + + /** + * @return a nicely formatted string representation of the obstacle + */ + std::string Write(); private: - int WhichQuad(const Point& vertex, const Point& hitPos) const; + int WhichQuad(const Point& vertex, const Point& hitPos) const; - // x-Koordinate der Linie von einer Eccke zur nächsten - double Xintercept(const Point& point1, const Point& point2, - double hitY) const; + // x-Koordinate der Linie von einer Eccke zur nächsten + double Xintercept(const Point& point1, const Point& point2, + double hitY) const; }; diff --git a/src/geometry/Point.cpp b/src/geometry/Point.cpp index 13821ba03c8107bd7efa8a5719965b22ad6977f7..00f425cfa910888d609ac65fb07cf98ed36295aa 100644 --- a/src/geometry/Point.cpp +++ b/src/geometry/Point.cpp @@ -1,12 +1,14 @@ /** - * File: Point.cpp + * \file Point.cpp + * \date Sep 30, 2010 + * \version v0.5 + * \copyright <2009-2014> Forschungszentrum Jülich GmbH. All rights reserved. * - * Created on 30. September 2010, 09:21 - * @section LICENSE + * \section License * This file is part of JuPedSim. * * JuPedSim is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by + * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * @@ -15,14 +17,14 @@ * 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 + * You should have received a copy of the GNU Lesser General Public License * along with JuPedSim. If not, see <http://www.gnu.org/licenses/>. * - * @section DESCRIPTION + * \section Description * * - * - */ + **/ + #include "Point.h" #include "../general/Macros.h" @@ -40,78 +42,93 @@ ************************************************************/ Point::Point() { - _x = 0.0; - _y = 0.0; + _x = 0.0; + _y = 0.0; } Point::Point(double x, double y) { - _x = x; - _y = y; + _x = x; + _y = y; } Point::Point(const Point& orig) { - _x = orig.GetX(); - _y = orig.GetY(); + _x = orig.GetX(); + _y = orig.GetY(); } std::string Point::toString() const { - std::stringstream tmp; - tmp<<"( "<<_x<<" : " <<_y<<" )"; - return tmp.str(); -}; + std::stringstream tmp; + tmp<<"( "<<_x<<" : " <<_y<<" )"; + return tmp.str(); +} void Point::SetX(double x) { - _x = x; + _x = x; } void Point::SetY(double y) { - _y = y; + _y = y; } double Point::GetX() const { - return _x; + return _x; } double Point::GetY() const { - return _y; + return _y; } double Point::Norm() const { - return sqrt(_x * _x + _y * _y); + return sqrt(_x * _x + _y * _y); +} + +double Point::NormMolified() const +{ + double const eps_sq = 0.1; + return sqrt(_x * _x + _y * _y + eps_sq); } double Point::NormSquare() const { - return (_x * _x + _y * _y); + return (_x * _x + _y * _y); } +Point Point::NormalizedMolified() const +{ + double norm = NormMolified(); + if (norm > J_EPS_GOAL) + return ( Point(_x, _y) / norm ); + else return Point(0.0, 0.0); +} + + Point Point::Normalized() const { - double norm=Norm(); - if (norm > J_EPS*J_EPS) - return ( Point(_x, _y) / norm ); - else return Point(0.0, 0.0); + double norm = Norm(); + if (norm > J_EPS) + return ( Point(_x, _y) / norm ); + else return Point(0.0, 0.0); } // scalar product double Point::ScalarP(const Point& v) const { - //return _x * v.GetX() + _y * v.GetY(); - return _x * v._x + _y * v._y; + //return _x * v.GetX() + _y * v.GetY(); + return _x * v._x + _y * v._y; } /// determinant of the square matrix formed by the vectors [ this, v] double Point::Det(const Point& v) const { - return _x * v._y - _y * v._x; + return _x * v._y - _y * v._x; } /* Transformiert die "normalen" Koordinaten in Koordinaten der Ellipse @@ -175,8 +192,8 @@ xnew = -xc + x */ Point Point::CoordTransToEllipse(const Point& center, double cphi, double sphi) const { - Point p = Point(_x, _y); - return (p - center).Rotate(cphi, -sphi); + Point p = Point(_x, _y); + return (p - center).Rotate(cphi, -sphi); } /* @@ -200,8 +217,8 @@ where the coord. of a point are transformated to cart. coord. Point Point::CoordTransToCart(const Point& center, double cphi, double sphi) const { - Point p = Point(_x, _y); - return (p.Rotate(cphi, sphi) + center); + Point p = Point(_x, _y); + return (p.Rotate(cphi, sphi) + center); } /*rotate a two-dimensional vector by an angle of theta @@ -212,53 +229,53 @@ Rotation-matrix=[cos(theta) -sin(theta)] */ Point Point::Rotate(double ctheta, double stheta) const { - return Point(_x * ctheta - _y*stheta, _x * stheta + _y * ctheta); + return Point(_x * ctheta - _y*stheta, _x * stheta + _y * ctheta); } // sum const Point Point::operator+(const Point& p) const { - //return Point(_x + p.GetX(), _y + p.GetY()); - return Point(_x + p._x, _y + p._y); + //return Point(_x + p.GetX(), _y + p.GetY()); + return Point(_x + p._x, _y + p._y); } // sub const Point Point::operator-(const Point& p) const { - // return Point(_x - p.GetX(), _y - p.GetY()); - return Point(_x - p._x, _y - p._y); + // return Point(_x - p.GetX(), _y - p.GetY()); + return Point(_x - p._x, _y - p._y); } // equal bool Point::operator==(const Point& p) const { // return (fabs(_x - p.GetX()) < J_EPS && fabs(_y - p.GetY()) < J_EPS); - return (fabs(_x - p._x) < J_EPS && fabs(_y - p._y) < J_EPS); + return (fabs(_x - p._x) < J_EPS && fabs(_y - p._y) < J_EPS); } // not equal bool Point::operator!=(const Point& p) const { - //return (fabs(_x - p.GetX()) > J_EPS || fabs(_y - p.GetY()) > J_EPS); - return (fabs(_x - p._x) > J_EPS || fabs(_y - p._y) > J_EPS); + //return (fabs(_x - p.GetX()) > J_EPS || fabs(_y - p.GetY()) > J_EPS); + return (fabs(_x - p._x) > J_EPS || fabs(_y - p._y) > J_EPS); } // multiplication with scalar const Point operator*(const Point& p, double f) { - //return Point(p.GetX() * f, p.GetY() * f); - return Point(p._x * f, p._y * f); + //return Point(p.GetX() * f, p.GetY() * f); + return Point(p._x * f, p._y * f); } // divition with scalar const Point operator/(const Point& p, double f) { - if (f>J_EPS*J_EPS) - return Point(p._x / f, p._y / f); - else { - std::cout << "Warning: Point::/operator. dividand "<<f<< " is to small. Set it to 1 instead"<<std::endl; - return Point(p._x, p._y); - } - //return Point(p.GetX() / f, p.GetY() / f); + if (f>J_EPS*J_EPS) + return Point(p._x / f, p._y / f); + else { + std::cout << "Warning: Point::/operator. dividand "<<f<< " is to small. Set it to 1 instead"<<std::endl; + return Point(p._x, p._y); + } + //return Point(p.GetX() / f, p.GetY() / f); } diff --git a/src/geometry/Point.h b/src/geometry/Point.h index 6064885fae63006240e8783c8dbb361d16b1af82..92578237d3cabb9a2d31d0f4eb928d3718ca9165 100644 --- a/src/geometry/Point.h +++ b/src/geometry/Point.h @@ -1,13 +1,14 @@ /** - * File: Point.h + * \file Point.h + * \date Sep 30, 2010 + * \version v0.5 + * \copyright <2009-2014> Forschungszentrum Jülich GmbH. All rights reserved. * - * Created on 30. September 2010, 09:21 - * - * @section LICENSE + * \section License * This file is part of JuPedSim. * * JuPedSim is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by + * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * @@ -16,82 +17,88 @@ * 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 + * You should have received a copy of the GNU Lesser General Public License * along with JuPedSim. If not, see <http://www.gnu.org/licenses/>. * - * @section DESCRIPTION - * + * \section Description * * - */ + **/ + #ifndef _POINT_H -#define _POINT_H +#define _POINT_H #include <string> class Point { public: - double _x; - double _y; + double _x; + double _y; public: - // constructors - Point(); - Point(double x, double y); - Point(const Point& orig); - - - /** - * Set/Get the x component - */ - void SetX(double x); - - /** - * Set/Get the y component - */ - void SetY(double y); - - - /** - * Set/Get the x component - */ - double GetX() const; - - /** - * Set/Get the y component - */ - double GetY() const; - - /// Norm - double Norm() const; - /// Norm square - double NormSquare() const; - /// normalized vector - Point Normalized() const; - /// dot product - double ScalarP(const Point& v) const; - /// determinant of the square matrix formed by the vectors [ this, v] - double Det(const Point& v) const; - /// translation and rotation in Ellipse coordinate system - Point CoordTransToEllipse(const Point& center, double cphi, double sphi) const; - /// translation and rotation in cartesian system - Point CoordTransToCart(const Point& center, double cphi, double sphi) const; - /// rotate the vector by theta - Point Rotate(double ctheta, double stheta) const; - - - // operators - /// addition - const Point operator+(const Point& p) const; - /// substraction - const Point operator-(const Point& p) const; - /// equal - bool operator==(const Point& p) const; - /// not equal - bool operator!=(const Point& p) const; - - /// nice formating of the point - std::string toString() const; + // constructors + Point(); + Point(double x, double y); + Point(const Point& orig); + + + /** + * Set/Get the x component + */ + void SetX(double x); + + /** + * Set/Get the y component + */ + void SetY(double y); + + + /** + * Set/Get the x component + */ + double GetX() const; + + /** + * Set/Get the y component + */ + double GetY() const; + + /// Norm + double Norm() const; + + /// Norm molified see Koester2013 + double NormMolified() const; + + /// Norm square + double NormSquare() const; + /// normalized vector + Point Normalized() const; + /// normalized vector usinf NormMolified + Point NormalizedMolified() const; + /// dot product + double ScalarP(const Point& v) const; + /// determinant of the square matrix formed by the vectors [ this, v] + double Det(const Point& v) const; + /// translation and rotation in Ellipse coordinate system + Point CoordTransToEllipse(const Point& center, double cphi, double sphi) const; + /// translation and rotation in cartesian system + Point CoordTransToCart(const Point& center, double cphi, double sphi) const; + /// rotate the vector by theta + Point Rotate(double ctheta, double stheta) const; + + + // operators + /// addition + const Point operator+(const Point& p) const; + /// substraction + const Point operator-(const Point& p) const; + /// equal + bool operator==(const Point& p) const; + /// not equal + bool operator!=(const Point& p) const; + + /// nice formating of the point + std::string toString() const; }; /// multiplication @@ -99,5 +106,5 @@ const Point operator*(const Point& p, const double f); /// division const Point operator/(const Point& p, const double f); -#endif /* _POINT_H */ +#endif /* _POINT_H */ diff --git a/src/geometry/Room.cpp b/src/geometry/Room.cpp index f2838fc3c28a5c398858af92a7710945cd2df308..75729b721eeabc1a54468d50bccbd6e570f2cb6f 100644 --- a/src/geometry/Room.cpp +++ b/src/geometry/Room.cpp @@ -1,12 +1,14 @@ /** - * File: Room.cpp + * \file Room.cpp + * \date Sep 30, 2010 + * \version v0.5 + * \copyright <2009-2014> Forschungszentrum Jülich GmbH. All rights reserved. * - * Created on 30. September 2010, 11:58 - * @section LICENSE + * \section License * This file is part of JuPedSim. * * JuPedSim is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by + * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * @@ -15,17 +17,19 @@ * 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 + * You should have received a copy of the GNU Lesser General Public License * along with JuPedSim. If not, see <http://www.gnu.org/licenses/>. * - * @section DESCRIPTION + * \section Description * * - * - */ + **/ #include "Room.h" +#include "SubRoom.h" +#include "../IO/OutputHandler.h" + #include <sstream> using namespace std; @@ -36,28 +40,28 @@ using namespace std; Room::Room() { - _id = -1; - _state=ROOM_CLEAN; //smoke-free - _caption = "no room caption"; - _zPos = -1.0; - _subRooms = vector<SubRoom* > (); - _outputFile=NULL; + _id = -1; + _state=ROOM_CLEAN; //smoke-free + _caption = "no room caption"; + _zPos = -1.0; + _subRooms = vector<SubRoom* > (); + _outputFile=NULL; } Room::Room(const Room& orig) { - _id = orig.GetID(); - _caption = orig.GetCaption(); - _zPos = orig.GetZPos(); - _subRooms = orig.GetAllSubRooms(); - _state=orig.GetState(); - _outputFile=orig.GetOutputHandler(); + _id = orig.GetID(); + _caption = orig.GetCaption(); + _zPos = orig.GetZPos(); + _subRooms = orig.GetAllSubRooms(); + _state=orig.GetState(); + _outputFile=orig.GetOutputHandler(); } Room::~Room() { - for (unsigned int i = 0; i < _subRooms.size(); i++) - delete _subRooms[i]; + for (unsigned int i = 0; i < _subRooms.size(); i++) + delete _subRooms[i]; } /************************************************************* @@ -65,32 +69,32 @@ Room::~Room() ************************************************************/ void Room::SetID(int ID) { - _id = ID; + _id = ID; } void Room::SetCaption(string s) { - _caption = s; + _caption = s; } void Room::SetZPos(double z) { - _zPos = z; + _zPos = z; } void Room::SetSubRoom(SubRoom* subroom, int index) { - if ((index >= 0) && (index < GetNumberOfSubRooms())) { - _subRooms[index] = subroom; - } else { - Log->Write("ERROR: Wrong Index in Room::SetSubRoom()"); - exit(0); - } + if ((index >= 0) && (index < GetNumberOfSubRooms())) { + _subRooms[index] = subroom; + } else { + Log->Write("ERROR: Wrong Index in Room::SetSubRoom()"); + exit(0); + } } void Room::SetState(RoomState state) { - _state=state; + _state=state; } @@ -99,59 +103,51 @@ void Room::SetState(RoomState state) ************************************************************/ int Room::GetID() const { - return _id; + return _id; } string Room::GetCaption() const { - return _caption; + return _caption; } double Room::GetZPos() const { - //if(pCaption=="070") return pZPos+1.0; - return _zPos; + //if(pCaption=="070") return pZPos+1.0; + return _zPos; } int Room::GetNumberOfSubRooms() const { - return _subRooms.size(); + return _subRooms.size(); } const vector<SubRoom*>& Room::GetAllSubRooms() const { - return _subRooms; + return _subRooms; } SubRoom* Room::GetSubRoom(int index) const { - if ((index >= 0) && (index < (int) _subRooms.size())) - return _subRooms[index]; - else { - char tmp[CLENGTH]; - sprintf(tmp,"ERROR: Room::GetSubRoom() Wrong subroom index [%d] for room index [%d] ",index,_id); - Log->Write(tmp); - exit(0); - } + if ((index >= 0) && (index < (int) _subRooms.size())) + return _subRooms[index]; + else { + char tmp[CLENGTH]; + sprintf(tmp,"ERROR: Room::GetSubRoom() No subroom id [%d] present in room id [%d] ",index,_id); + Log->Write(tmp); + return NULL; + //exit(EXIT_FAILURE); + } } #ifdef _SIMULATOR -int Room::GetNumberOfPedestrians() const -{ - int sum = 0; - for (int i = 0; i < GetNumberOfSubRooms(); i++) { - sum += GetSubRoom(i)->GetNumberOfPedestrians(); - } - return sum; -} - #endif // _SIMULATOR RoomState Room::GetState() const { - return _state; + return _state; } @@ -161,17 +157,17 @@ RoomState Room::GetState() const ************************************************************/ void Room::AddSubRoom(SubRoom* r) { - _subRooms.push_back(r); + _subRooms.push_back(r); } void Room::DeleteSubRoom(int index) { - if ((index >= 0) && (index < (int) _subRooms.size())) - _subRooms.erase(_subRooms.begin() + index); - else { - Log->Write("ERROR: Wrong Index in Room::DeleteSubRoom()"); - exit(0); - } + if ((index >= 0) && (index < (int) _subRooms.size())) + _subRooms.erase(_subRooms.begin() + index); + else { + Log->Write("ERROR: Wrong Index in Room::DeleteSubRoom()"); + exit(0); + } } /************************************************************* @@ -181,35 +177,35 @@ void Room::DeleteSubRoom(int index) void Room::WriteToErrorLog() const { - char tmp[CLENGTH]; - string s; - sprintf(tmp, "\tRaum: %d [%s]:\n", _id, _caption.c_str()); - s.append(tmp); - Log->Write(s); - // SubRooms - for (int i = 0; i < GetNumberOfSubRooms(); i++) { - SubRoom* s = GetSubRoom(i); - s->WriteToErrorLog(); - } + char tmp[CLENGTH]; + string s; + sprintf(tmp, "\tRaum: %d [%s]:\n", _id, _caption.c_str()); + s.append(tmp); + Log->Write(s); + // SubRooms + for (int i = 0; i < GetNumberOfSubRooms(); i++) { + SubRoom* s = GetSubRoom(i); + s->WriteToErrorLog(); + } } const vector<int>& Room::GetAllTransitionsIDs() const { - return _transitionsIDs; + return _transitionsIDs; } void Room::AddTransitionID(int ID) { - _transitionsIDs.push_back(ID); + _transitionsIDs.push_back(ID); } void Room::SetOutputHandler(OutputHandler* oh) { - _outputFile=oh; + _outputFile=oh; } OutputHandler* Room::GetOutputHandler() const { - return _outputFile; + return _outputFile; } diff --git a/src/geometry/Room.h b/src/geometry/Room.h index d8420813d4cc46146a1deb21e7a5aa7d725acd05..e4336f000fd8845e4af42514e37ff592bf504904 100644 --- a/src/geometry/Room.h +++ b/src/geometry/Room.h @@ -1,12 +1,14 @@ /** - * \file File: Room.h + * \file Room.h + * \date Sep 30, 2010 + * \version v0.5 + * \copyright <2009-2014> Forschungszentrum Jülich GmbH. All rights reserved. * - * Created on 30. September 2010, 11:58 - * @section LICENSE + * \section License * This file is part of JuPedSim. * * JuPedSim is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by + * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * @@ -15,149 +17,149 @@ * 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 + * You should have received a copy of the GNU Lesser General Public License * along with JuPedSim. If not, see <http://www.gnu.org/licenses/>. * - * @section DESCRIPTION * * - */ + **/ + #ifndef _ROOM_H -#define _ROOM_H +#define _ROOM_H #include <string> #include <algorithm> +#include "../general/Macros.h" -#include "../geometry/SubRoom.h" -//class SubRoom; +//forward declarations +class OutputHandler; +class SubRoom; + + +// external variables +extern OutputHandler* Log; class Room { private: - /// room ID and index - int _id; - /// room state - RoomState _state; - /// room caption - std::string _caption; - /// room elevation - double _zPos; - /// all subrooms/partitions of the room - std::vector<SubRoom*> _subRooms; - /// all transitions ids - std::vector<int> _transitionsIDs; - /// needed if the trajectories for this room are to be write in a special way - OutputHandler* _outputFile; + /// room ID and index + int _id; + /// room state + RoomState _state; + /// room caption + std::string _caption; + /// room elevation + double _zPos; + /// all subrooms/partitions of the room + std::vector<SubRoom*> _subRooms; + /// all transitions ids + std::vector<int> _transitionsIDs; + /// needed if the trajectories for this room are to be write in a special way + OutputHandler* _outputFile; public: - Room(); - Room(const Room& orig); - virtual ~Room(); - - - /** - * Set/Get the id of the room which is also used as index - */ - void SetID(int ID); - - /** - * Set/Get the caption of the room - */ - void SetCaption(std::string s); - - /** - * Set/Get the elevation of the room - */ - void SetZPos(double z); - - /** - * Add a SubRoom at the given index - */ - void SetSubRoom(SubRoom* subroom, int index); - - /** - * Set/Get the state of the room as defined in the macro.h file - */ - void SetState(RoomState state); - - /** - * Set/Get the id of the room which is also used as index - */ - int GetID() const; - - /** - * Set/Get the caption of the room - */ - std::string GetCaption() const; - - /** - * Set/Get the elevation of the room - */ - double GetZPos() const; - - /** - * @return the number of subrooms - */ - int GetNumberOfSubRooms() const; - - /** - * @return a vector containing all subrooms - */ - const std::vector<SubRoom*>& GetAllSubRooms() const; - - /** - * @return a vector containing all transitions Ids - */ - const std::vector<int>& GetAllTransitionsIDs() const; - - /** - * @return the Subroom with the corresponding index - */ - SubRoom* GetSubRoom(int index) const; - - /** - * @return the number of pedestrians in the rooms (all subrooms) - */ - int GetNumberOfPedestrians() const; - - /** - * @return the state for this room - */ - RoomState GetState()const; - - /** - * Push a new subroom in the vector - */ - void AddSubRoom(SubRoom* r); - - /** - * Delete the subroom at the specified index - */ - void DeleteSubRoom(int index); - - /** - * Add a new transition id - */ - void AddTransitionID(int ID); - - - /** - * Debug output for this class - */ - void WriteToErrorLog() const; - - /** - * Used by MPI in the case each room should be written in a specific file - */ - void SetOutputHandler(OutputHandler* oh); - - /** - * Used by MPI in the case each room should be written in a specific file - */ - OutputHandler* GetOutputHandler() const; + Room(); + Room(const Room& orig); + virtual ~Room(); + + + /** + * Set/Get the id of the room which is also used as index + */ + void SetID(int ID); + + /** + * Set/Get the caption of the room + */ + void SetCaption(std::string s); + + /** + * Set/Get the elevation of the room + */ + void SetZPos(double z); + + /** + * Add a SubRoom at the given index + */ + void SetSubRoom(SubRoom* subroom, int index); + + /** + * Set/Get the state of the room as defined in the macro.h file + */ + void SetState(RoomState state); + + /** + * Set/Get the id of the room which is also used as index + */ + int GetID() const; + + /** + * Set/Get the caption of the room + */ + std::string GetCaption() const; + + /** + * Set/Get the elevation of the room + */ + double GetZPos() const; + + /** + * @return the number of subrooms + */ + int GetNumberOfSubRooms() const; + + /** + * @return a vector containing all subrooms + */ + const std::vector<SubRoom*>& GetAllSubRooms() const; + + /** + * @return a vector containing all transitions Ids + */ + const std::vector<int>& GetAllTransitionsIDs() const; + + /** + * @return the Subroom with the corresponding index + */ + SubRoom* GetSubRoom(int index) const; + + /** + * @return the state for this room + */ + RoomState GetState()const; + + /** + * Push a new subroom in the vector + */ + void AddSubRoom(SubRoom* r); + + /** + * Delete the subroom at the specified index + */ + void DeleteSubRoom(int index); + + /** + * Add a new transition id + */ + void AddTransitionID(int ID); + + /** + * Debug output for this class + */ + void WriteToErrorLog() const; + + /** + * Used by MPI in the case each room should be written in a specific file + */ + void SetOutputHandler(OutputHandler* oh); + + /** + * Used by MPI in the case each room should be written in a specific file + */ + OutputHandler* GetOutputHandler() const; }; -#endif /* _ROOM_H */ +#endif /* _ROOM_H */ diff --git a/src/geometry/SubRoom.cpp b/src/geometry/SubRoom.cpp index 198f532a0c1a7dec5aaf85971bbea9db86efb283..557301e8f74228f429c7496090ebcf98a7270a8a 100644 --- a/src/geometry/SubRoom.cpp +++ b/src/geometry/SubRoom.cpp @@ -1,14 +1,14 @@ /** - * File: SubRoom.cpp - * - * Created on 8. October 2010, 10:56 - * - * @section LICENSE + * \file SubRoom.cpp + * \date Oct 8, 2010 + * \version v0.5 + * \copyright <2009-2014> Forschungszentrum Jülich GmbH. All rights reserved. * + * \section License * This file is part of JuPedSim. * * JuPedSim is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by + * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * @@ -17,20 +17,23 @@ * 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 + * You should have received a copy of the GNU Lesser General Public License * along with JuPedSim. If not, see <http://www.gnu.org/licenses/>. * - * @section DESCRIPTION - * + * \section Description * * - */ + **/ + +#include "Point.h" +#include "Line.h" +#include "Wall.h" #include "Obstacle.h" #include "SubRoom.h" #include "Transition.h" #include "Hline.h" -#include "Wall.h" + #ifdef _SIMULATOR #include "../pedestrian/Pedestrian.h" @@ -48,147 +51,118 @@ int SubRoom::_static_uid=0; SubRoom::SubRoom() { - _id = -1; - _roomID=-1; - _walls = vector<Wall > (); - _poly = vector<Point > (); - _obstacles=vector<Obstacle*> (); - - _crossings = vector<Crossing*>(); - _transitions = vector<Transition*>(); - _hlines = vector<Hline*>(); + _id = -1; + _roomID=-1; + _walls = vector<Wall > (); + _poly = vector<Point > (); + _obstacles=vector<Obstacle*> (); - _planeEquation[0]=0.0; - _planeEquation[1]=0.0; - _planeEquation[2]=0.0; - _cosAngleWithHorizontalPlane=0; + _crossings = vector<Crossing*>(); + _transitions = vector<Transition*>(); + _hlines = vector<Hline*>(); - _goalIDs = vector<int> (); - _area = 0.0; - _closed=false; - _uid = _static_uid++; - -#ifdef _SIMULATOR - _peds = vector<Pedestrian* > (); -#endif //_SIMULATOR + _planeEquation[0]=0.0; + _planeEquation[1]=0.0; + _planeEquation[2]=0.0; + _cosAngleWithHorizontalPlane=0; -} - -SubRoom::SubRoom(const SubRoom& orig) -{ - _id = orig.GetSubRoomID(); - _walls = orig.GetAllWalls(); - _poly = orig.GetPolygon(); - _goalIDs = orig.GetAllGoalIDs(); - _area = orig.GetArea(); - _closed=orig.GetClosed(); - _roomID=orig.GetRoomID(); - _uid = orig.GetUID(); - _cosAngleWithHorizontalPlane=orig.GetCosAngleWithHorizontal(); - -#ifdef _SIMULATOR - _peds = orig.GetAllPedestrians(); -#endif //_SIMULATOR + _goalIDs = vector<int> (); + _area = 0.0; + _closed=false; + _uid = _static_uid++; } SubRoom::~SubRoom() { - if (_walls.size() > 0) _walls.clear(); - if (_poly.size() > 0) _poly.clear(); - for (unsigned int i = 0; i < _obstacles.size(); i++) { - delete _obstacles[i]; - } - _obstacles.clear(); - -#ifdef _SIMULATOR - for (unsigned int i = 0; i < _peds.size(); i++) { - delete _peds[i]; - } -#endif //_SIMULATOR - + if (_walls.size() > 0) _walls.clear(); + if (_poly.size() > 0) _poly.clear(); + for (unsigned int i = 0; i < _obstacles.size(); i++) { + delete _obstacles[i]; + } + _obstacles.clear(); } // Setter -Funktionen void SubRoom::SetSubRoomID(int ID) { - _id = ID; + _id = ID; } void SubRoom::SetClosed(double closed) { - _closed = closed; + _closed = closed; } void SubRoom::SetRoomID(int ID) { - _roomID = ID; + _roomID = ID; } int SubRoom::GetSubRoomID() const { - return _id; + return _id; } double SubRoom::GetClosed() const { - return _closed; + return _closed; } // unique identifier for this subroom int SubRoom::GetUID() const { - return _uid; - //return pRoomID * 1000 + pID; + return _uid; + //return pRoomID * 1000 + pID; } double SubRoom::GetArea() const { - return _area; + return _area; } int SubRoom::GetRoomID() const { - return _roomID; + return _roomID; } int SubRoom::GetNumberOfWalls() const { - return _walls.size(); + return _walls.size(); } const vector<Wall>& SubRoom::GetAllWalls() const { - return _walls; + return _walls; } const Wall& SubRoom::GetWall(int index) const { - if ((index >= 0) && (index < GetNumberOfWalls())) - return _walls[index]; - else { - Log->Write("ERROR: Wrong 'index' in SubRoom::GetWall()"); - exit(0); - } + if ((index >= 0) && (index < GetNumberOfWalls())) + return _walls[index]; + else { + Log->Write("ERROR: Wrong 'index' in SubRoom::GetWall()"); + exit(0); + } } const vector<Point>& SubRoom::GetPolygon() const { - return _poly; + return _poly; } const vector<Obstacle*>& SubRoom::GetAllObstacles() const { - return _obstacles; + return _obstacles; } int SubRoom::GetNumberOfGoalIDs() const { - return _goalIDs.size(); + return _goalIDs.size(); } const vector<int>& SubRoom::GetAllGoalIDs() const { - return _goalIDs; + return _goalIDs; } @@ -196,211 +170,227 @@ const vector<int>& SubRoom::GetAllGoalIDs() const void SubRoom::AddWall(const Wall& w) { - _walls.push_back(w); + _walls.push_back(w); } void SubRoom::AddObstacle(Obstacle* obs) { - _obstacles.push_back(obs); - CheckObstacles(); + _obstacles.push_back(obs); + CheckObstacles(); } void SubRoom::AddGoalID(int ID) { - _goalIDs.push_back(ID); + _goalIDs.push_back(ID); } void SubRoom::AddCrossing(Crossing* line) { - _crossings.push_back(line); - _goalIDs.push_back(line->GetUniqueID()); + _crossings.push_back(line); + _goalIDs.push_back(line->GetUniqueID()); } void SubRoom::AddTransition(Transition* line) { - _transitions.push_back(line); - _goalIDs.push_back(line->GetUniqueID()); + _transitions.push_back(line); + _goalIDs.push_back(line->GetUniqueID()); } void SubRoom::AddHline(Hline* line) { + for(unsigned int i=0;i<_hlines.size();i++){ + if (line->GetID()==_hlines[i]->GetID()){ + Log->Write("INFO:\tskipping duplicate hline [%d] in subroom [%d]",_id,line->GetID()); + return; + } + } + _hlines.push_back(line); _goalIDs.push_back(line->GetUniqueID()); } const vector<Crossing*>& SubRoom::GetAllCrossings() const { - return _crossings; + return _crossings; } const vector<Transition*>& SubRoom::GetAllTransitions() const { - return _transitions; + return _transitions; } const vector<Hline*>& SubRoom::GetAllHlines() const { - return _hlines; + return _hlines; } const Crossing* SubRoom::GetCrossing(int i) const { - return _crossings[i]; + return _crossings[i]; } const Transition* SubRoom::GetTransition(int i) const { - return _transitions[i]; + return _transitions[i]; } const Hline* SubRoom::GetHline(int i) const { - return _hlines[i]; + return _hlines[i]; } void SubRoom::RemoveGoalID(int ID) { - for (unsigned int i=0; i<_goalIDs.size(); i++) { - if(_goalIDs[i]==ID) { - Log->Write("Removing goal"); - _goalIDs.erase(_goalIDs.begin()+i); - return; - } - } - Log->Write("There is no goal with that id to remove"); + for (unsigned int i=0; i<_goalIDs.size(); i++) { + if(_goalIDs[i]==ID) { + Log->Write("Removing goal"); + _goalIDs.erase(_goalIDs.begin()+i); + return; + } + } + Log->Write("There is no goal with that id to remove"); } void SubRoom::CalculateArea() { - double sum = 0; - int n = (int) _poly.size(); - for (int i = 0; i < n; i++) { - sum += (_poly[i].GetY() + _poly[(i + 1) % n].GetY())*(_poly[i].GetX() - _poly[(i + 1) % n].GetX()); - } - _area=(0.5 * fabs(sum)); + double sum = 0; + int n = (int) _poly.size(); + for (int i = 0; i < n; i++) { + sum += (_poly[i].GetY() + _poly[(i + 1) % n].GetY())*(_poly[i].GetX() - _poly[(i + 1) % n].GetX()); + } + _area=(0.5 * fabs(sum)); } Point SubRoom::GetCentroid() const { - double px=0,py=0; - double signedArea = 0.0; - double x0 = 0.0; // Current vertex X - double y0 = 0.0; // Current vertex Y - double x1 = 0.0; // Next vertex X - double y1 = 0.0; // Next vertex Y - double a = 0.0; // Partial signed area - - // For all vertices except last - unsigned int i=0; - for (i=0; i<_poly.size()-1; ++i) { - x0 = _poly[i].GetX(); - y0 = _poly[i].GetY(); - x1 = _poly[i+1].GetX(); - y1 = _poly[i+1].GetY(); - a = x0*y1 - x1*y0; - signedArea += a; - px += (x0 + x1)*a; - py += (y0 + y1)*a; - } - - // Do last vertex - x0 = _poly[i].GetX(); - y0 = _poly[i].GetY(); - x1 = _poly[0].GetX(); - y1 = _poly[0].GetY(); - a = x0*y1 - x1*y0; - signedArea += a; - px += (x0 + x1)*a; - py += (y0 + y1)*a; - - signedArea *= 0.5; - px /= (6.0*signedArea); - py /= (6.0*signedArea); - - return Point(px,py); + double px=0,py=0; + double signedArea = 0.0; + double x0 = 0.0; // Current vertex X + double y0 = 0.0; // Current vertex Y + double x1 = 0.0; // Next vertex X + double y1 = 0.0; // Next vertex Y + double a = 0.0; // Partial signed area + + // For all vertices except last + unsigned int i=0; + for (i=0; i<_poly.size()-1; ++i) { + x0 = _poly[i].GetX(); + y0 = _poly[i].GetY(); + x1 = _poly[i+1].GetX(); + y1 = _poly[i+1].GetY(); + a = x0*y1 - x1*y0; + signedArea += a; + px += (x0 + x1)*a; + py += (y0 + y1)*a; + } + + // Do last vertex + x0 = _poly[i].GetX(); + y0 = _poly[i].GetY(); + x1 = _poly[0].GetX(); + y1 = _poly[0].GetY(); + a = x0*y1 - x1*y0; + signedArea += a; + px += (x0 + x1)*a; + py += (y0 + y1)*a; + + signedArea *= 0.5; + px /= (6.0*signedArea); + py /= (6.0*signedArea); + + return Point(px,py); } bool SubRoom::IsVisible(const Point& p1, const Point& p2, bool considerHlines) { - // generate certain connection lines - // connecting p1 with p2 - Line cl = Line(p1,p2); - bool temp = true; - //check intersection with Walls - for(unsigned int i = 0; i < _walls.size(); i++) { - if(temp && cl.IntersectionWith(_walls[i])) - temp = false; - } - - - //check intersection with obstacles - for(unsigned int i = 0; i < _obstacles.size(); i++) { - Obstacle * obs = _obstacles[i]; - for(unsigned int k = 0; k<obs->GetAllWalls().size(); k++) { - const Wall& w = obs->GetAllWalls()[k]; - if(temp && cl.IntersectionWith(w)) - temp = false; - } - } - - - // check intersection with other hlines in room - if(considerHlines) - for(unsigned int i = 0; i < _hlines.size(); i++) { - if(temp && cl.IntersectionWith(*(Line*)_hlines[i])) - temp = false; - } - - return temp; + // generate certain connection lines + // connecting p1 with p2 + Line cl = Line(p1,p2); + Line L1=cl, L2; + bool temp = true; + //check intersection with Walls + for(unsigned int i = 0; i < _walls.size(); i++) { + if(temp && cl.IntersectionWith(_walls[i])){ + L2 = _walls[i]; + // fprintf (stdout, "INTERSECTION WALL L1_P1(%.2f, %.2f), L1_P2(%.2f, %.2f), L2_P1(%.2f, %.2f) L2_P2(%.2f, %.2f)\n", L1.GetPoint1().GetX(),L1.GetPoint1().GetY(),L1.GetPoint2().GetX(),L1.GetPoint2().GetY(), L2.GetPoint1().GetX(),L2.GetPoint1().GetY(),L2.GetPoint2().GetX(),L2.GetPoint2().GetY()); + temp = false; + } + } + + + //check intersection with obstacles + for(unsigned int i = 0; i < _obstacles.size(); i++) { + Obstacle * obs = _obstacles[i]; + for(unsigned int k = 0; k<obs->GetAllWalls().size(); k++) { + const Wall& w = obs->GetAllWalls()[k]; + if(temp && cl.IntersectionWith(w)){ + L2 = w; + // fprintf (stdout, "INTERSECTION OBS; L1_P1(%.2f, %.2f), L1_P2(%.2f, %.2f), L2_P1(%.2f, %.2f) L2_P2(%.2f, %.2f)\n", L1.GetPoint1().GetX(),L1.GetPoint1().GetY(),L1.GetPoint2().GetX(),L1.GetPoint2().GetY(), L2.GetPoint1().GetX(),L2.GetPoint1().GetY(),L2.GetPoint2().GetX(),L2.GetPoint2().GetY()); + temp = false; + + } + } + } + + + // check intersection with other hlines in room + if(considerHlines) + for(unsigned int i = 0; i < _hlines.size(); i++) { + if(_hlines[i]->IsInLineSegment(p1)|| _hlines[i]->IsInLineSegment(p2)) continue; + if(temp && cl.IntersectionWith(*(Line*)_hlines[i])) + temp = false; + } + + return temp; } bool SubRoom::IsVisible(Line* l1, Line* l2, bool considerHlines) { - // generate certain connection lines - // connecting p1 mit p1, p1 mit p2, p2 mit p1, p2 mit p2 und center mit center - Line cl[5]; - cl[0] = Line(l1->GetPoint1(), l2->GetPoint1()); - cl[1] = Line(l1->GetPoint1(), l2->GetPoint2()); - cl[2] = Line(l1->GetPoint2(), l2->GetPoint1()); - cl[3] = Line(l1->GetPoint2(), l2->GetPoint2()); - cl[4] = Line(l1->GetCentre(), l2->GetCentre()); - bool temp[5] = {true, true, true, true, true}; - //check intersection with Walls - for(unsigned int i = 0; i < GetAllWalls().size(); i++) { - for(int k = 0; k < 5; k++) { - if(temp[k] && cl[k].IntersectionWith(_walls[i]) && (cl[k].NormalVec() != _walls[i].NormalVec() || l1->NormalVec() != l2->NormalVec())) - temp[k] = false; - } - } - - //check intersection with obstacles - for(unsigned int i = 0; i < GetAllObstacles().size(); i++) { - Obstacle * obs = GetAllObstacles()[i]; - for(unsigned int k = 0; k<obs->GetAllWalls().size(); k++) { - const Wall& w = obs->GetAllWalls()[k]; - if((w.operator !=(*l1)) && (w.operator !=(*l2))) - for(int j = 0; j < 5; j++) { - if(temp[j] && cl[j].IntersectionWith(w)) - temp[j] = false; - } - } - } - - // check intersection with other hlines in room - if(considerHlines) - for(unsigned int i = 0; i < _hlines.size(); i++) { - if ( (l1->operator !=(*(Line*)_hlines[i])) && (l2->operator !=(*(Line*)_hlines[i])) ) { - for(int k = 0; k < 5; k++) { - if(temp[k] && cl[k].IntersectionWith(*(Line*)_hlines[i])) - temp[k] = false; - } - } - } - return temp[0] || temp[1] || temp[2] || temp[3] || temp[4]; + // generate certain connection lines + // connecting p1 mit p1, p1 mit p2, p2 mit p1, p2 mit p2 und center mit center + Line cl[5]; + cl[0] = Line(l1->GetPoint1(), l2->GetPoint1()); + cl[1] = Line(l1->GetPoint1(), l2->GetPoint2()); + cl[2] = Line(l1->GetPoint2(), l2->GetPoint1()); + cl[3] = Line(l1->GetPoint2(), l2->GetPoint2()); + cl[4] = Line(l1->GetCentre(), l2->GetCentre()); + bool temp[5] = {true, true, true, true, true}; + //check intersection with Walls + for(unsigned int i = 0; i < GetAllWalls().size(); i++) { + for(int k = 0; k < 5; k++) { + if(temp[k] && cl[k].IntersectionWith(_walls[i]) && (cl[k].NormalVec() != _walls[i].NormalVec() || l1->NormalVec() != l2->NormalVec())) + temp[k] = false; + } + } + + //check intersection with obstacles + for(unsigned int i = 0; i < GetAllObstacles().size(); i++) { + Obstacle * obs = GetAllObstacles()[i]; + for(unsigned int k = 0; k<obs->GetAllWalls().size(); k++) { + const Wall& w = obs->GetAllWalls()[k]; + if((w.operator !=(*l1)) && (w.operator !=(*l2))) + for(int j = 0; j < 5; j++) { + if(temp[j] && cl[j].IntersectionWith(w)) + temp[j] = false; + } + } + } + + // check intersection with other hlines in room + if(considerHlines) + for(unsigned int i = 0; i < _hlines.size(); i++) { + if ( (l1->operator !=(*(Line*)_hlines[i])) && (l2->operator !=(*(Line*)_hlines[i])) ) { + for(int k = 0; k < 5; k++) { + if(temp[k] && cl[k].IntersectionWith(*(Line*)_hlines[i])) + temp[k] = false; + } + } + } + return temp[0] || temp[1] || temp[2] || temp[3] || temp[4]; } @@ -410,143 +400,143 @@ bool SubRoom::IsVisible(Line* l1, Line* l2, bool considerHlines) bool SubRoom::IsDirectlyConnectedWith(const SubRoom* sub) const { - //check the crossings - const vector<Crossing*>& crossings = sub->GetAllCrossings(); - for (unsigned int i = 0; i < crossings.size(); i++) { - for (unsigned int j = 0; j < _crossings.size(); j++) { - int uid1 = crossings[i]->GetUniqueID(); - int uid2 = _crossings[j]->GetUniqueID(); - // ignore my transition - if (uid1 == uid2) - return true; - } - } - - // and finally the transitions - const vector<Transition*>& transitions = sub->GetAllTransitions(); - for (unsigned int i = 0; i < transitions.size(); i++) { - for (unsigned int j = 0; j < _transitions.size(); j++) { - int uid1 = transitions[i]->GetUniqueID(); - int uid2 = _transitions[j]->GetUniqueID(); - // ignore my transition - if (uid1 == uid2) - return true; - } - } - - return false; + //check the crossings + const vector<Crossing*>& crossings = sub->GetAllCrossings(); + for (unsigned int i = 0; i < crossings.size(); i++) { + for (unsigned int j = 0; j < _crossings.size(); j++) { + int uid1 = crossings[i]->GetUniqueID(); + int uid2 = _crossings[j]->GetUniqueID(); + // ignore my transition + if (uid1 == uid2) + return true; + } + } + + // and finally the transitions + const vector<Transition*>& transitions = sub->GetAllTransitions(); + for (unsigned int i = 0; i < transitions.size(); i++) { + for (unsigned int j = 0; j < _transitions.size(); j++) { + int uid1 = transitions[i]->GetUniqueID(); + int uid2 = _transitions[j]->GetUniqueID(); + // ignore my transition + if (uid1 == uid2) + return true; + } + } + + return false; } void SubRoom::SetPlanEquation(double A, double B, double C) { - _planeEquation[0]=A; - _planeEquation[1]=B; - _planeEquation[2]=C; - //compute and cache the cosine of angle with the plane z=h - _cosAngleWithHorizontalPlane= (1.0/sqrt(A*A+B*B+1)); + _planeEquation[0]=A; + _planeEquation[1]=B; + _planeEquation[2]=C; + //compute and cache the cosine of angle with the plane z=h + _cosAngleWithHorizontalPlane= (1.0/sqrt(A*A+B*B+1)); } -const double* SubRoom::GetPlanEquation() const +const double* SubRoom::GetPlaneEquation() const { - return _planeEquation; + return _planeEquation; } double SubRoom::GetElevation(const Point& p) const { - return _planeEquation[0] * p._x + _planeEquation[1] * p._y + _planeEquation[2]; + return _planeEquation[0] * p._x + _planeEquation[1] * p._y + _planeEquation[2]; } double SubRoom::GetCosAngleWithHorizontal() const { - return _cosAngleWithHorizontalPlane; + return _cosAngleWithHorizontalPlane; } void SubRoom::CheckObstacles() { - for(unsigned int i = 0; i<_walls.size(); i++) { - for(unsigned int j = 0; j<_obstacles.size(); j++) { - if(_obstacles[j]->IntersectWithLine(_walls[i])) { - Log->Write("INFO: \tthe obstacle id [%d] is intersection with subroom [%d]",_obstacles[j]->GetId(),_id); - Log->Write("INFO: \tthe triangulation will not work."); - exit(EXIT_FAILURE); - } - } - } -} - -void SubRoom::SanityCheck() -{ - if(_obstacles.size()==0) { - if((IsConvex()==false) && (_hlines.size()==0)) { - Log->Write("WARNING:\t Room [%d] Subroom [%d] is not convex!",_roomID,_id); - Log->Write("\t\t you might consider adding extra hlines in your routing.xml file"); - } else { - // everything is fine - } - } else { - if(_hlines.size()==0) { - Log->Write("WARNING:\t you have obstacles in room [%d] Subroom [%d]!",_roomID,_id); - Log->Write("\t\t you might consider adding extra hlines in your routing.xml file"); - } else { - // everything is fine - } - } - + for(unsigned int i = 0; i<_walls.size(); i++) { + for(unsigned int j = 0; j<_obstacles.size(); j++) { + if(_obstacles[j]->IntersectWithLine(_walls[i])) { + Log->Write("INFO: \tthe obstacle id [%d] is intersection with subroom [%d]",_obstacles[j]->GetId(),_id); + Log->Write("INFO: \tthe triangulation will not work."); + exit(EXIT_FAILURE); + } + } + } +} + +bool SubRoom::SanityCheck() +{ + if(_obstacles.size()==0) { + if((IsConvex()==false) && (_hlines.size()==0)) { + Log->Write("WARNING:\t Room [%d] Subroom [%d] is not convex!",_roomID,_id); + Log->Write("\t\t you might consider adding extra hlines in your routing.xml file"); + } else { + // everything is fine + } + } else { + if(_hlines.size()==0) { + Log->Write("WARNING:\t you have obstacles in room [%d] Subroom [%d]!",_roomID,_id); + Log->Write("\t\t you might consider adding extra hlines in your routing.xml file"); + } else { + // everything is fine + } + } + return true; } ///http://stackoverflow.com/questions/471962/how-do-determine-if-a-polygon-is-complex-convex-nonconvex bool SubRoom::IsConvex() { - unsigned int hsize=_poly.size(); - unsigned int pos=0; - unsigned int neg=0; + unsigned int hsize=_poly.size(); + unsigned int pos=0; + unsigned int neg=0; - if(hsize==0) { - Log->Write("WARNING:\t cannot check empty polygon for convexification"); - Log->Write("WARNING:\t Did you forget to tall ConvertLineToPoly() ?"); - return false; - } + if(hsize==0) { + Log->Write("WARNING:\t cannot check empty polygon for convexification"); + Log->Write("WARNING:\t Did you forget to tall ConvertLineToPoly() ?"); + return false; + } - for(unsigned int i=0; i<hsize; i++) { - Point vecAB= _poly[(i+1)%hsize]-_poly[i%hsize]; - Point vecBC= _poly[(i+2)%hsize]-_poly[(i+1)%hsize]; - double det= vecAB.Det(vecBC); - if(fabs(det)<J_EPS) det=0.0; - - if(det<0.0) { - neg++; - } else if(det>0.0) { - pos++; - } else { - pos++; - neg++; - } + for(unsigned int i=0; i<hsize; i++) { + Point vecAB= _poly[(i+1)%hsize]-_poly[i%hsize]; + Point vecBC= _poly[(i+2)%hsize]-_poly[(i+1)%hsize]; + double det= vecAB.Det(vecBC); + if(fabs(det)<J_EPS) det=0.0; - } + if(det<0.0) { + neg++; + } else if(det>0.0) { + pos++; + } else { + pos++; + neg++; + } - if ( (pos==hsize ) || (neg==hsize) ) { - return true; - } - return false; + } + + if ( (pos==hsize ) || (neg==hsize) ) { + return true; + } + return false; } ///http://stackoverflow.com/questions/9473570/polygon-vertices-clockwise-or-counterclockwise/ bool SubRoom::IsClockwise() { - if(_poly.size()<3) { - Log->Write("ERROR:\tYou need at least 3 vertices to check for orientation. Subroom ID [%d]"); - return false; - //exit(EXIT_FAILURE); - } + if(_poly.size()<3) { + Log->Write("ERROR:\tYou need at least 3 vertices to check for orientation. Subroom ID [%d]"); + return false; + //exit(EXIT_FAILURE); + } - Point vecAB= _poly[1]-_poly[0]; - Point vecBC= _poly[2]-_poly[1]; + Point vecAB= _poly[1]-_poly[0]; + Point vecBC= _poly[2]-_poly[1]; - double det=vecAB.Det(vecBC); - if(fabs(det)<J_EPS) det=0.0; + double det=vecAB.Det(vecBC); + if(fabs(det)<J_EPS) det=0.0; - return ( det<=0.0 ); + return ( det<=0.0 ); } @@ -558,10 +548,6 @@ NormalSubRoom::NormalSubRoom() : SubRoom() } -NormalSubRoom::NormalSubRoom(const NormalSubRoom& orig) : SubRoom(orig) -{ - -} NormalSubRoom::~NormalSubRoom() { @@ -569,119 +555,119 @@ NormalSubRoom::~NormalSubRoom() string NormalSubRoom::WriteSubRoom() const { - string s; - for (int j = 0; j < GetNumberOfWalls(); j++) { - - const Wall& w = GetWall(j); - string geometry; - char wall[CLENGTH] = ""; - geometry.append("\t\t<wall>\n"); - sprintf(wall, "\t\t\t<point xPos=\"%.2f\" yPos=\"%.2f\" zPos=\"%.2f\"/>\n", - (w.GetPoint1().GetX()) * FAKTOR, - (w.GetPoint1().GetY()) * FAKTOR, - GetElevation(w.GetPoint1())*FAKTOR); - geometry.append(wall); - sprintf(wall, "\t\t\t<point xPos=\"%.2f\" yPos=\"%.2f\" zPos=\"%.2f\"/>\n", - (w.GetPoint2().GetX()) * FAKTOR, - (w.GetPoint2().GetY()) * FAKTOR, - GetElevation(w.GetPoint2())*FAKTOR); - geometry.append(wall); - geometry.append("\t\t</wall>\n"); - - s.append(geometry); - //s.append(GetWall(j).Write()); - } - //add the subroom caption - Point pos = GetCentroid(); - char tmp[CLENGTH]; - sprintf(tmp, "\t\t<label centerX=\"%.2f\" centerY=\"%.2f\" centerZ=\"0\" text=\"%d\" color=\"100\" />\n" - , pos.GetX() * FAKTOR, pos.GetY() * FAKTOR, GetSubRoomID()); - s.append(tmp); - - //write the obstacles - for( unsigned int j=0; j<GetAllObstacles().size(); j++) { - s.append(GetAllObstacles()[j]->Write()); - } - - return s; + string s; + for (int j = 0; j < GetNumberOfWalls(); j++) { + + const Wall& w = GetWall(j); + string geometry; + char wall[CLENGTH] = ""; + geometry.append("\t\t<wall>\n"); + sprintf(wall, "\t\t\t<point xPos=\"%.2f\" yPos=\"%.2f\" zPos=\"%.2f\"/>\n", + (w.GetPoint1().GetX()) * FAKTOR, + (w.GetPoint1().GetY()) * FAKTOR, + GetElevation(w.GetPoint1())*FAKTOR); + geometry.append(wall); + sprintf(wall, "\t\t\t<point xPos=\"%.2f\" yPos=\"%.2f\" zPos=\"%.2f\"/>\n", + (w.GetPoint2().GetX()) * FAKTOR, + (w.GetPoint2().GetY()) * FAKTOR, + GetElevation(w.GetPoint2())*FAKTOR); + geometry.append(wall); + geometry.append("\t\t</wall>\n"); + + s.append(geometry); + //s.append(GetWall(j).Write()); + } + //add the subroom caption + Point pos = GetCentroid(); + char tmp[CLENGTH]; + sprintf(tmp, "\t\t<label centerX=\"%.2f\" centerY=\"%.2f\" centerZ=\"0\" text=\"%d\" color=\"100\" />\n" + , pos.GetX() * FAKTOR, pos.GetY() * FAKTOR, GetSubRoomID()); + s.append(tmp); + + //write the obstacles + for( unsigned int j=0; j<GetAllObstacles().size(); j++) { + s.append(GetAllObstacles()[j]->Write()); + } + + return s; } string NormalSubRoom::WritePolyLine() const { - string s; - char tmp[CLENGTH]; + string s; + char tmp[CLENGTH]; - s.append("\t<Obstacle closed=\"1\" boundingbox=\"0\" class=\"1\">\n"); - for (unsigned int j = 0; j < _poly.size(); j++) { - sprintf(tmp, "\t\t<Vertex p_x = \"%.2lf\" p_y = \"%.2lf\"/>\n",_poly[j].GetX(),_poly[j].GetY()); - s.append(tmp); - } - s.append("\t</Obstacle>\n"); + s.append("\t<Obstacle closed=\"1\" boundingbox=\"0\" class=\"1\">\n"); + for (unsigned int j = 0; j < _poly.size(); j++) { + sprintf(tmp, "\t\t<Vertex p_x = \"%.2lf\" p_y = \"%.2lf\"/>\n",_poly[j].GetX()* FAKTOR,_poly[j].GetY()* FAKTOR); + s.append(tmp); + } + s.append("\t</Obstacle>\n"); - //write the obstacles - for( unsigned int j=0; j<GetAllObstacles().size(); j++) { - s.append(GetAllObstacles()[j]->Write()); - } + //write the obstacles + for( unsigned int j=0; j<GetAllObstacles().size(); j++) { + s.append(GetAllObstacles()[j]->Write()); + } - return s; + return s; } void NormalSubRoom::WriteToErrorLog() const { - Log->Write("\t\tNormal SubRoom:\n"); - for (int i = 0; i < GetNumberOfWalls(); i++) { - Wall w = GetWall(i); - w.WriteToErrorLog(); - } + Log->Write("\t\tNormal SubRoom:\n"); + for (int i = 0; i < GetNumberOfWalls(); i++) { + Wall w = GetWall(i); + w.WriteToErrorLog(); + } } bool NormalSubRoom::ConvertLineToPoly(vector<Line*> goals) { - vector<Line*> copy; - vector<Point> tmpPoly; - Point point; - Line* line; - // Alle Linienelemente in copy speichern - for (int i = 0; i < GetNumberOfWalls(); i++) { - copy.push_back(&_walls[i]); - } - // Transitions und Crossings sind in goal abgespeichert - copy.insert(copy.end(), goals.begin(), goals.end()); - - line = copy[0]; - tmpPoly.push_back(line->GetPoint1()); - point = line->GetPoint2(); - copy.erase(copy.begin()); - // Polygon aus allen Linen erzeugen - for (int i = 0; i < (int) copy.size(); i++) { - line = copy[i]; - if ((point - line->GetPoint1()).Norm() < J_TOLERANZ) { - tmpPoly.push_back(line->GetPoint1()); - point = line->GetPoint2(); - copy.erase(copy.begin() + i); - // von vorne suchen - i = -1; - } else if ((point - line->GetPoint2()).Norm() < J_TOLERANZ) { - tmpPoly.push_back(line->GetPoint2()); - point = line->GetPoint1(); - copy.erase(copy.begin() + i); - // von vorne suchen - i = -1; - } - } - if ((tmpPoly[0] - point).Norm() > J_TOLERANZ) { - char tmp[CLENGTH]; - sprintf(tmp, "ERROR: \tNormalSubRoom::ConvertLineToPoly(): SubRoom %d Room %d Anfangspunkt ungleich Endpunkt!!!\n" - "\t(%f, %f) != (%f, %f)\n", GetSubRoomID(), GetRoomID(), tmpPoly[0].GetX(), tmpPoly[0].GetY(), point.GetX(), - point.GetY()); - Log->Write(tmp); - sprintf(tmp, "ERROR: \tDistance between the points: %lf !!!\n", (tmpPoly[0] - point).Norm()); - Log->Write(tmp); - return false; - } - _poly = tmpPoly; - return true; + vector<Line*> copy; + vector<Point> tmpPoly; + Point point; + Line* line; + // Alle Linienelemente in copy speichern + for (int i = 0; i < GetNumberOfWalls(); i++) { + copy.push_back(&_walls[i]); + } + // Transitions und Crossings sind in goal abgespeichert + copy.insert(copy.end(), goals.begin(), goals.end()); + + line = copy[0]; + tmpPoly.push_back(line->GetPoint1()); + point = line->GetPoint2(); + copy.erase(copy.begin()); + // Polygon aus allen Linen erzeugen + for (int i = 0; i < (int) copy.size(); i++) { + line = copy[i]; + if ((point - line->GetPoint1()).Norm() < J_TOLERANZ) { + tmpPoly.push_back(line->GetPoint1()); + point = line->GetPoint2(); + copy.erase(copy.begin() + i); + // von vorne suchen + i = -1; + } else if ((point - line->GetPoint2()).Norm() < J_TOLERANZ) { + tmpPoly.push_back(line->GetPoint2()); + point = line->GetPoint1(); + copy.erase(copy.begin() + i); + // von vorne suchen + i = -1; + } + } + if ((tmpPoly[0] - point).Norm() > J_TOLERANZ) { + char tmp[CLENGTH]; + sprintf(tmp, "ERROR: \tNormalSubRoom::ConvertLineToPoly(): SubRoom %d Room %d Anfangspunkt ungleich Endpunkt!!!\n" + "\t(%f, %f) != (%f, %f)\n", GetSubRoomID(), GetRoomID(), tmpPoly[0].GetX(), tmpPoly[0].GetY(), point.GetX(), + point.GetY()); + Log->Write(tmp); + sprintf(tmp, "ERROR: \tDistance between the points: %lf !!!\n", (tmpPoly[0] - point).Norm()); + Log->Write(tmp); + return false; + } + _poly = tmpPoly; + return true; } @@ -691,8 +677,8 @@ bool NormalSubRoom::ConvertLineToPoly(vector<Line*> goals) int NormalSubRoom::WhichQuad(const Point& vertex, const Point& hitPos) const { - return (vertex.GetX() > hitPos.GetX()) ? ((vertex.GetY() > hitPos.GetY()) ? 1 : 4) : - ((vertex.GetY() > hitPos.GetY()) ? 2 : 3); + return (vertex.GetX() > hitPos.GetX()) ? ((vertex.GetY() > hitPos.GetY()) ? 1 : 4) : + ((vertex.GetY() > hitPos.GetY()) ? 2 : 3); } @@ -700,8 +686,8 @@ int NormalSubRoom::WhichQuad(const Point& vertex, const Point& hitPos) const double NormalSubRoom::Xintercept(const Point& point1, const Point& point2, double hitY) const { - return (point2.GetX() - (((point2.GetY() - hitY) * (point1.GetX() - point2.GetX())) / - (point1.GetY() - point2.GetY()))); + return (point2.GetX() - (((point2.GetY() - hitY) * (point1.GetX() - point2.GetX())) / + (point1.GetY() - point2.GetY()))); } @@ -709,48 +695,48 @@ double NormalSubRoom::Xintercept(const Point& point1, const Point& point2, doubl bool NormalSubRoom::IsInSubRoom(const Point& ped) const { - short edge, first, next; - short quad, next_quad, delta, total; - - ///////////////////////////////////////////////////////////// - edge = first = 0; - quad = WhichQuad(_poly[edge], ped); - total = 0; // COUNT OF ABSOLUTE SECTORS CROSSED - /* LOOP THROUGH THE VERTICES IN A SECTOR */ - do { - next = (edge + 1) % _poly.size(); - next_quad = WhichQuad(_poly[next], ped); - delta = next_quad - quad; // HOW MANY QUADS HAVE I MOVED - - // SPECIAL CASES TO HANDLE CROSSINGS OF MORE THEN ONE - //QUAD - - switch (delta) { - case 2: // IF WE CROSSED THE MIDDLE, FIGURE OUT IF IT - //WAS CLOCKWISE OR COUNTER - case -2: // US THE X POSITION AT THE HIT POINT TO - // DETERMINE WHICH WAY AROUND - if (Xintercept(_poly[edge], _poly[next], ped._y) > ped._x) - delta = -(delta); - break; - case 3: // MOVING 3 QUADS IS LIKE MOVING BACK 1 - delta = -1; - break; - case -3: // MOVING BACK 3 IS LIKE MOVING FORWARD 1 - delta = 1; - break; - } - /* ADD IN THE DELTA */ - total += delta; - quad = next_quad; // RESET FOR NEXT STEP - edge = next; - } while (edge != first); - - /* AFTER ALL IS DONE IF THE TOTAL IS 4 THEN WE ARE INSIDE */ - if (abs(total) == 4) - return true; - else - return false; + short edge, first, next; + short quad, next_quad, delta, total; + + ///////////////////////////////////////////////////////////// + edge = first = 0; + quad = WhichQuad(_poly[edge], ped); + total = 0; // COUNT OF ABSOLUTE SECTORS CROSSED + /* LOOP THROUGH THE VERTICES IN A SECTOR */ + do { + next = (edge + 1) % _poly.size(); + next_quad = WhichQuad(_poly[next], ped); + delta = next_quad - quad; // HOW MANY QUADS HAVE I MOVED + + // SPECIAL CASES TO HANDLE CROSSINGS OF MORE THEN ONE + //QUAD + + switch (delta) { + case 2: // IF WE CROSSED THE MIDDLE, FIGURE OUT IF IT + //WAS CLOCKWISE OR COUNTER + case -2: // US THE X POSITION AT THE HIT POINT TO + // DETERMINE WHICH WAY AROUND + if (Xintercept(_poly[edge], _poly[next], ped._y) > ped._x) + delta = -(delta); + break; + case 3: // MOVING 3 QUADS IS LIKE MOVING BACK 1 + delta = -1; + break; + case -3: // MOVING BACK 3 IS LIKE MOVING FORWARD 1 + delta = 1; + break; + } + /* ADD IN THE DELTA */ + total += delta; + quad = next_quad; // RESET FOR NEXT STEP + edge = next; + } while (edge != first); + + /* AFTER ALL IS DONE IF THE TOTAL IS 4 THEN WE ARE INSIDE */ + if (abs(total) == 4) + return true; + else + return false; } /************************************************************ @@ -759,15 +745,10 @@ bool NormalSubRoom::IsInSubRoom(const Point& ped) const Stair::Stair() : NormalSubRoom() { - pUp = Point(); - pDown = Point(); + pUp = Point(); + pDown = Point(); } -Stair::Stair(const Stair & orig) : NormalSubRoom(orig) -{ - pUp = orig.GetUp(); - pDown = orig.GetDown(); -} Stair::~Stair() { @@ -777,94 +758,94 @@ Stair::~Stair() void Stair::SetUp(const Point & p) { - pUp = p; + pUp = p; } void Stair::SetDown(const Point & p) { - pDown = p; + pDown = p; } // Getter-Funktionen const Point & Stair::GetUp() const { - return pUp; + return pUp; } const Point & Stair::GetDown() const { - return pDown; + return pDown; } string Stair::WriteSubRoom() const { - string s; - - for (int j = 0; j < GetNumberOfWalls(); j++) { - const Wall& w = GetWall(j); - - string geometry; - char wall[CLENGTH] = ""; - geometry.append("\t\t<wall>\n"); - sprintf(wall, "\t\t\t<point xPos=\"%.2f\" yPos=\"%.2f\" zPos=\"%.2f\"/>\n", - (w.GetPoint1().GetX()) * FAKTOR, - (w.GetPoint1().GetY()) * FAKTOR, - GetElevation(w.GetPoint1())*FAKTOR); - geometry.append(wall); - sprintf(wall, "\t\t\t<point xPos=\"%.2f\" yPos=\"%.2f\" zPos=\"%.2f\"/>\n", - (w.GetPoint2().GetX()) * FAKTOR, - (w.GetPoint2().GetY()) * FAKTOR, - GetElevation(w.GetPoint2())*FAKTOR); - geometry.append(wall); - geometry.append("\t\t</wall>\n"); - - s.append(geometry); - //s.append(w.Write()); - } - //Line tmp = Line(GetUp(), GetDown()); - // s.append(tmp.Write()); - Point pos = GetCentroid(); - char tmp_c[CLENGTH]; - sprintf(tmp_c, "\t\t<sphere centerX=\"%.2f\" centerY=\"%.2f\" centerZ=\"%.2f\" radius=\"20\" color=\"100\" />\n" - , GetUp().GetX() * FAKTOR, GetUp().GetY() * FAKTOR, GetElevation(GetUp())*FAKTOR); - s.append(tmp_c); - - //add the subroom caption - sprintf(tmp_c, "\t\t<label centerX=\"%.2f\" centerY=\"%.2f\" centerZ=\"%.2f\" text=\"%d\" color=\"100\" />\n" - , pos.GetX() * FAKTOR, pos.GetY() * FAKTOR,GetElevation(pos)*FAKTOR ,GetSubRoomID()); - s.append(tmp_c); - - return s; + string s; + + for (int j = 0; j < GetNumberOfWalls(); j++) { + const Wall& w = GetWall(j); + + string geometry; + char wall[CLENGTH] = ""; + geometry.append("\t\t<wall>\n"); + sprintf(wall, "\t\t\t<point xPos=\"%.2f\" yPos=\"%.2f\" zPos=\"%.2f\"/>\n", + (w.GetPoint1().GetX()) * FAKTOR, + (w.GetPoint1().GetY()) * FAKTOR, + GetElevation(w.GetPoint1())*FAKTOR); + geometry.append(wall); + sprintf(wall, "\t\t\t<point xPos=\"%.2f\" yPos=\"%.2f\" zPos=\"%.2f\"/>\n", + (w.GetPoint2().GetX()) * FAKTOR, + (w.GetPoint2().GetY()) * FAKTOR, + GetElevation(w.GetPoint2())*FAKTOR); + geometry.append(wall); + geometry.append("\t\t</wall>\n"); + + s.append(geometry); + //s.append(w.Write()); + } + //Line tmp = Line(GetUp(), GetDown()); + // s.append(tmp.Write()); + Point pos = GetCentroid(); + char tmp_c[CLENGTH]; + sprintf(tmp_c, "\t\t<sphere centerX=\"%.2f\" centerY=\"%.2f\" centerZ=\"%.2f\" radius=\"%.2f\" color=\"100\" />\n" + , GetUp().GetX() * FAKTOR, GetUp().GetY() * FAKTOR,GetElevation(GetUp())*FAKTOR, 0.2*FAKTOR); + s.append(tmp_c); + + //add the subroom caption + sprintf(tmp_c, "\t\t<label centerX=\"%.2f\" centerY=\"%.2f\" centerZ=\"%.2f\" text=\"%d\" color=\"100\" />\n" + , pos.GetX() * FAKTOR, pos.GetY() * FAKTOR,GetElevation(pos)*FAKTOR ,GetSubRoomID()); + s.append(tmp_c); + + return s; } string Stair::WritePolyLine() const { - string s; - char tmp[CLENGTH]; + string s; + char tmp[CLENGTH]; - s.append("\t<Obstacle closed=\"1\" boundingbox=\"0\" class=\"1\">\n"); - for (unsigned int j = 0; j < _poly.size(); j++) { - sprintf(tmp, "\t\t<Vertex p_x = \"%.2lf\" p_y = \"%.2lf\"/>\n",_poly[j].GetX(),_poly[j].GetY()); - s.append(tmp); - } - s.append("\t</Obstacle>\n"); + s.append("\t<Obstacle closed=\"1\" boundingbox=\"0\" class=\"1\">\n"); + for (unsigned int j = 0; j < _poly.size(); j++) { + sprintf(tmp, "\t\t<Vertex p_x = \"%.2lf\" p_y = \"%.2lf\"/>\n",_poly[j].GetX()* FAKTOR,_poly[j].GetY()* FAKTOR); + s.append(tmp); + } + s.append("\t</Obstacle>\n"); - //write the obstacles - for( unsigned int j=0; j<GetAllObstacles().size(); j++) { - s.append(GetAllObstacles()[j]->Write()); - } + //write the obstacles + for( unsigned int j=0; j<GetAllObstacles().size(); j++) { + s.append(GetAllObstacles()[j]->Write()); + } - return s; + return s; } void Stair::WriteToErrorLog() const { - Log->Write("\t\tStair:\n"); - for (int i = 0; i < GetNumberOfWalls(); i++) { - Wall w = GetWall(i); - w.WriteToErrorLog(); - } + Log->Write("\t\tStair:\n"); + for (int i = 0; i < GetNumberOfWalls(); i++) { + Wall w = GetWall(i); + w.WriteToErrorLog(); + } } /* prüft ob die Punkte p1, p2 und p3 auf einer Linie liegen, oder eine Ecke bilden. @@ -872,219 +853,153 @@ void Stair::WriteToErrorLog() const * */ const Point* Stair::CheckCorner(const Point** otherPoint, const Point** aktPoint, const Point* nextPoint) { - - Point l1 = **otherPoint - **aktPoint; - Point l2 = *nextPoint - **aktPoint; - const Point* rueck = NULL; - // Punkte bilden eine Linie - if (fabs(fabs(l1.ScalarP(l2) / (l1.Norm() * l2.Norm())) - 1) < 0.1) { - *aktPoint = nextPoint; - } else { // aktPoint/p2 ist eine Ecke - rueck = *aktPoint; - *otherPoint = *aktPoint; - *aktPoint = nextPoint; - } - return rueck; + Point l1 = **otherPoint - **aktPoint; + Point l2 = *nextPoint - **aktPoint; + const Point* rueck = NULL; + // Punkte bilden eine Linie + if (fabs(fabs(l1.ScalarP(l2) / (l1.Norm() * l2.Norm())) - 1) < 0.1) { + *aktPoint = nextPoint; + } else { // aktPoint/p2 ist eine Ecke + rueck = *aktPoint; + *otherPoint = *aktPoint; + *aktPoint = nextPoint; + } + return rueck; } bool Stair::ConvertLineToPoly(vector<Line*> goals) { - //return NormalSubRoom::ConvertLineToPoly(goals); - - vector<Line*> copy; - vector<Point> orgPoly = vector<Point > (); - const Point* aktPoint; - const Point* otherPoint; - const Point* nextPoint; - const Point* firstAktPoint; - const Point* firstOtherPoint; - Line *nextLine; - - // Alle Linienelemente in copy speichern - for (int i = 0; i < GetNumberOfWalls(); i++) { - copy.push_back(&_walls[i]); - } - // Transitions und Crossings sind in goal abgespeichert - copy.insert(copy.end(), goals.begin(), goals.end()); - - aktPoint = ©[0]->GetPoint1(); - firstAktPoint = aktPoint; - otherPoint = ©[0]->GetPoint2(); - firstOtherPoint = otherPoint; - copy.erase(copy.begin()); - - // Polygon aus allen Linen erzeugen - for (int i = 0; i < (int) copy.size(); i++) { - nextLine = copy[i]; - nextPoint = NULL; - if ((*aktPoint - nextLine->GetPoint1()).Norm() < J_TOLERANZ) { - nextPoint = &nextLine->GetPoint2(); - } else if ((*aktPoint - nextLine->GetPoint2()).Norm() < J_TOLERANZ) { - nextPoint = &nextLine->GetPoint1(); - } - if (nextPoint != NULL) { - const Point* rueck = CheckCorner(&otherPoint, &aktPoint, nextPoint); - if (rueck != NULL) - orgPoly.push_back(*rueck); - copy.erase(copy.begin() + i); - i = -1; // von vorne suchen - } - } - if ((*aktPoint - *firstOtherPoint).Norm() < J_TOLERANZ) { - const Point* rueck = CheckCorner(&otherPoint, &aktPoint, firstAktPoint); - if (rueck != NULL) - orgPoly.push_back(*rueck); - } else { - char tmp[CLENGTH]; - double x1, y1, x2, y2; - x1 = firstOtherPoint->GetX(); - y1 = firstOtherPoint->GetY(); - x2 = aktPoint->GetX(); - y2 = aktPoint->GetY(); - sprintf(tmp, "ERROR: \tStair::ConvertLineToPoly(): SubRoom %d Room %d Anfangspunkt ungleich Endpunkt!!!\n" - "\t(%f, %f) != (%f, %f)\n", GetSubRoomID(), GetRoomID(), x1, y1, x2, y2); - Log->Write(tmp); - return false; - } - - if (orgPoly.size() != 4) { - char tmp[CLENGTH]; - sprintf(tmp, "ERROR: \tStair::ConvertLineToPoly(): Stair %d Room %d ist kein Viereck!!!\n" - "Anzahl Ecken: %d\n", GetSubRoomID(), GetRoomID(), orgPoly.size()); - Log->Write(tmp); - return false; - } - vector<Point> neuPoly = (orgPoly); - // ganz kleine Treppen (nur eine Stufe) nicht - if ((neuPoly[0] - neuPoly[1]).Norm() > 0.9 && (neuPoly[1] - neuPoly[2]).Norm() > 0.9) { - for (int i1 = 0; i1 < (int) orgPoly.size(); i1++) { - int i2 = (i1 + 1) % orgPoly.size(); - int i3 = (i2 + 1) % orgPoly.size(); - int i4 = (i3 + 1) % orgPoly.size(); - Point p1 = neuPoly[i1]; - Point p2 = neuPoly[i2]; - Point p3 = neuPoly[i3]; - Point p4 = neuPoly[i4]; - - Point l1 = p2 - p1; - Point l2 = p3 - p2; - - if (l1.Norm() < l2.Norm()) { - neuPoly[i2] = neuPoly[i2] + l1.Normalized() * 2 * J_EPS_GOAL; - l2 = p3 - p4; - neuPoly[i3] = neuPoly[i3] + l2.Normalized() * 2 * J_EPS_GOAL; - } - } - } - _poly = neuPoly; - return true; + //return NormalSubRoom::ConvertLineToPoly(goals); + vector<Line*> copy; + vector<Point> orgPoly = vector<Point > (); + const Point* aktPoint; + const Point* otherPoint; + const Point* nextPoint; + const Point* firstAktPoint; + const Point* firstOtherPoint; + Line *nextLine; + + // Alle Linienelemente in copy speichern + for (int i = 0; i < GetNumberOfWalls(); i++) { + copy.push_back(&_walls[i]); + } + // Transitions und Crossings sind in goal abgespeichert + copy.insert(copy.end(), goals.begin(), goals.end()); + + aktPoint = ©[0]->GetPoint1(); + firstAktPoint = aktPoint; + otherPoint = ©[0]->GetPoint2(); + firstOtherPoint = otherPoint; + copy.erase(copy.begin()); + + // Polygon aus allen Linen erzeugen + for (int i = 0; i < (int) copy.size(); i++) { + nextLine = copy[i]; + nextPoint = NULL; + if ((*aktPoint - nextLine->GetPoint1()).Norm() < J_TOLERANZ) { + nextPoint = &nextLine->GetPoint2(); + } else if ((*aktPoint - nextLine->GetPoint2()).Norm() < J_TOLERANZ) { + nextPoint = &nextLine->GetPoint1(); + } + if (nextPoint != NULL) { + const Point* rueck = CheckCorner(&otherPoint, &aktPoint, nextPoint); + if (rueck != NULL) + orgPoly.push_back(*rueck); + copy.erase(copy.begin() + i); + i = -1; // von vorne suchen + } + } + if ((*aktPoint - *firstOtherPoint).Norm() < J_TOLERANZ) { + const Point* rueck = CheckCorner(&otherPoint, &aktPoint, firstAktPoint); + if (rueck != NULL) + orgPoly.push_back(*rueck); + } else { + char tmp[CLENGTH]; + double x1, y1, x2, y2; + x1 = firstOtherPoint->GetX(); + y1 = firstOtherPoint->GetY(); + x2 = aktPoint->GetX(); + y2 = aktPoint->GetY(); + sprintf(tmp, "ERROR: \tStair::ConvertLineToPoly(): SubRoom %d Room %d Anfangspunkt ungleich Endpunkt!!!\n" + "\t(%f, %f) != (%f, %f)\n", GetSubRoomID(), GetRoomID(), x1, y1, x2, y2); + Log->Write(tmp); + return false; + } + + if (orgPoly.size() != 4) { + char tmp[CLENGTH]; + sprintf(tmp, "ERROR: \tStair::ConvertLineToPoly(): Stair %d Room %d ist kein Viereck!!!\n" + "Anzahl Ecken: %d\n", GetSubRoomID(), (int)GetRoomID(), (int)orgPoly.size()); + Log->Write(tmp); + return false; + } + vector<Point> neuPoly = (orgPoly); + // ganz kleine Treppen (nur eine Stufe) nicht + if ((neuPoly[0] - neuPoly[1]).Norm() > 0.9 && (neuPoly[1] - neuPoly[2]).Norm() > 0.9) { + for (int i1 = 0; i1 < (int) orgPoly.size(); i1++) { + int i2 = (i1 + 1) % orgPoly.size(); + int i3 = (i2 + 1) % orgPoly.size(); + int i4 = (i3 + 1) % orgPoly.size(); + Point p1 = neuPoly[i1]; + Point p2 = neuPoly[i2]; + Point p3 = neuPoly[i3]; + Point p4 = neuPoly[i4]; + + Point l1 = p2 - p1; + Point l2 = p3 - p2; + + if (l1.Norm() < l2.Norm()) { + neuPoly[i2] = neuPoly[i2] + l1.Normalized() * 2 * J_EPS_GOAL; + l2 = p3 - p4; + neuPoly[i3] = neuPoly[i3] + l2.Normalized() * 2 * J_EPS_GOAL; + } + } + } + _poly = neuPoly; + + return true; } bool Stair::IsInSubRoom(const Point& ped) const { - bool rueck = false; - int N = (int) _poly.size(); - int sum = 0; + bool rueck = false; + int N = (int) _poly.size(); + int sum = 0; - for (int i = 0; i < N; i++) { - Line l = Line(_poly[i], _poly[(i + 1) % N]); - Point s = l.LotPoint(ped); - if (l.IsInLineSegment(s)) - sum++; - } - if (sum == 4) - rueck = true; + for (int i = 0; i < N; i++) { + Line l = Line(_poly[i], _poly[(i + 1) % N]); + Point s = l.LotPoint(ped); + if (l.IsInLineSegment(s)) + sum++; + } + if (sum == 4) + rueck = true; - return rueck; + return rueck; } + void SubRoom::SetType(const std::string& type) { - _type = type; + _type = type; } const std::string& SubRoom::GetType() const { - return _type; + return _type; } - #ifdef _SIMULATOR -void SubRoom::SetAllPedestrians(const vector<Pedestrian*>& peds) -{ - _peds = peds; -} - -void SubRoom::SetPedestrian(Pedestrian* ped, int index) -{ - if ((index >= 0) && (index < GetNumberOfPedestrians())) { - _peds[index] = ped; - } else { - Log->Write("ERROR: Wrong Index in SubRoom::SetPedestrian()"); - exit(0); - } -} - bool SubRoom::IsInSubRoom(Pedestrian* ped) const { - //TODO: reference ? - Point pos = ped->GetPos(); - if (ped->GetExitLine()->DistTo(pos) <= J_EPS_GOAL) - return true; - else - return IsInSubRoom(pos); + const Point& pos = ped->GetPos(); + if (ped->GetExitLine()->DistTo(pos) <= J_EPS_GOAL) + return true; + else + return IsInSubRoom(pos); } -int SubRoom::GetNumberOfPedestrians() const -{ - return _peds.size(); -} - -const vector<Pedestrian*>& SubRoom::GetAllPedestrians() const -{ - return _peds; -} - - - -Pedestrian* SubRoom::GetPedestrian(int index) const -{ - if ((index >= 0) && (index < (int) GetNumberOfPedestrians())) - return _peds[index]; - else { - Log->Write("ERROR: Wrong 'index' in SubRoom::GetPedestrian()"); - exit(0); - } -} - - -void SubRoom::AddPedestrian(Pedestrian* ped) -{ - _peds.push_back(ped); -} - - -void SubRoom::DeletePedestrian(int index) -{ - if ((index >= 0) && (index < (int) GetNumberOfPedestrians())) { - _peds.erase(_peds.begin() + index); - - } else { - Log->Write("ERROR: Wrong Index in SubRoom::DeletePedestrian()"); - exit(0); - } -} - - -void SubRoom::ClearAllPedestrians() -{ - for(unsigned int p=0; p<_peds.size(); p++) { - delete _peds[p]; - } - _peds.clear(); -} - #endif // _SIMULATOR diff --git a/src/geometry/SubRoom.h b/src/geometry/SubRoom.h index e035453a1a3b0cd12601de3190d426f653b811a6..72e640e070e4f0e570d90863192ec659a27acdb4 100644 --- a/src/geometry/SubRoom.h +++ b/src/geometry/SubRoom.h @@ -1,13 +1,14 @@ /** - * File: SubRoom.h + * \file SubRoom.h + * \date Oct 8, 2010 + * \version v0.5 + * \copyright <2009-2014> Forschungszentrum Jülich GmbH. All rights reserved. * - * Created on 8. October 2010, 10:56 - * - * @section LICENSE + * \section License * This file is part of JuPedSim. * * JuPedSim is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by + * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * @@ -16,29 +17,34 @@ * 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 + * You should have received a copy of the GNU Lesser General Public License * along with JuPedSim. If not, see <http://www.gnu.org/licenses/>. * - * @section DESCRIPTION - * + * \section Description * * - */ + **/ + #ifndef _SUBROOM_H -#define _SUBROOM_H +#define _SUBROOM_H -#include "Line.h" +//#include "Line.h" #include "Wall.h" +//#include "Point.h" #include <vector> #include <string> +//forward declarations class Transition; class Hline; class Obstacle; class Crossing; +class Line; +class Point; +class Wall; #ifdef _SIMULATOR class Pedestrian; @@ -47,287 +53,255 @@ class Pedestrian; /************************************************************ SubRoom - ************************************************************/ +************************************************************/ class SubRoom { private: - /// the id set using the SetID method - int _id; - /// the unique id resulting from the count of all subrooms in the system - int _uid; - int _roomID; - std::vector<int> _goalIDs; // all navigation lines contained in this subroom - double _area; - double _closed; - //defined by: Z = Ax + By + C - double _planeEquation[3]; - double _cosAngleWithHorizontalPlane; - std::string _type; - - std::vector<Obstacle*> _obstacles; // obstacles - - //different types of navigation lines - std::vector<Crossing*> _crossings; - std::vector<Transition*> _transitions; - std::vector<Hline*> _hlines; - - /// storing and incrementing the total number of subrooms - static int _static_uid; - - -#ifdef _SIMULATOR - std::vector<Pedestrian*> _peds; // pedestrians container -#endif + /// the id set using the SetID method + int _id; + /// the unique id resulting from the count of all subrooms in the system + int _uid; + int _roomID; + std::vector<int> _goalIDs; // all navigation lines contained in this subroom + double _area; + double _closed; + //defined by: Z = Ax + By + C + double _planeEquation[3]; + double _cosAngleWithHorizontalPlane; + std::string _type; + + std::vector<Obstacle*> _obstacles; // obstacles + + //different types of navigation lines + std::vector<Crossing*> _crossings; + std::vector<Transition*> _transitions; + std::vector<Hline*> _hlines; + + /// storing and incrementing the total number of subrooms + static int _static_uid; protected: - std::vector<Wall> _walls; - std::vector<Point> _poly; // Polygonal representation of the subroom + std::vector<Wall> _walls; + std::vector<Point> _poly; // Polygonal representation of the subroom public: - // constructors - SubRoom(); - SubRoom(const SubRoom& orig); - virtual ~SubRoom(); - - /** - * Set/Get the subroom id - */ - void SetSubRoomID(int ID); - - /** - * Set/Get the associated room id - */ - void SetRoomID(int ID); - //void SetAllWalls(const std::vector<Wall>& walls); - //void SetWall(const Wall& wall, int index); - //void SetPolygon(const std::vector<Point>& poly); - //void SetArea(double a); - - void SetClosed(double c); - - /** - * Set the plane equation for this subroom. - * defined by: Z = Ax + By + C - */ - void SetPlanEquation(double A, double B, double C); - - /** - * Set/Get the subroom id - */ - int GetSubRoomID() const; - - /** - * @return the number of walls forming this subroom - */ - int GetNumberOfWalls() const; - - /** - * @return all walls - */ - const std::vector<Wall>& GetAllWalls() const; - - /** - * @return a reference to the wall at position index - */ - const Wall& GetWall(int index) const; - - /** - * @return the polygonal representation of the subroom - * counterclockwise - */ - const std::vector<Point>& GetPolygon() const; - - /** - * @return a reference to all obstacles contained - */ - const std::vector<Obstacle*>& GetAllObstacles() const; - - /** - * @return the number of hlines+transitions+crossings - */ - int GetNumberOfGoalIDs() const; - - /** - * @return a vector containing all Ids - */ - const std::vector<int>& GetAllGoalIDs() const; - - /** - * @return the room containing this subroom - */ - int GetRoomID() const; - - /** - * @return the unique identifier for this subroom - */ - int GetUID() const; - - /** - * Set/Get the type of the subroom. - * Possible types are: stairs, room and floor. - * @return the type of the subroom. - */ - const std::string& GetType() const; - - /** - * Set/Get the type of the subroom. - * Possible types are: stairs, room and floor. - * @return the type of the subroom. - */ - void SetType(const std::string& type); - - - /** - * @return the status - */ - double GetClosed() const; - - /** - * @return the area - */ - double GetArea() const; - - /** - * @return the centroid of the subroom - * @see http://en.wikipedia.org/wiki/Centroid - */ - Point GetCentroid() const; - - /** - * @return the three coefficients of the plane equation. - * defined by: Z = Ax + By + C - */ - const double * GetPlanEquation () const; - - /** - * @return the elevation of a 2Dimensional point using the plane equation. - * @see GetPlanEquation - */ - double GetElevation(const Point & p1) const; - - - /** - * compute the cosine of the dihedral angle with the Horizontal plane Z=h - * @return the cosine of the angle - */ - double GetCosAngleWithHorizontal() const; - - /** - * Compute the area of the subroom. - * @see GetArea() - */ - void CalculateArea(); - - /** - * @return true if the polygon is convex - * @see http://stackoverflow.com/questions/471962/how-do-determine-if-a-polygon-is-complex-convex-nonconvex - */ - bool IsConvex(); - - /** - * @return true if the polygon is clockwise oriented - * @see http://stackoverflow.com/questions/9473570/polygon-vertices-clockwise-or-counterclockwise/ - */ - bool IsClockwise(); - - - /** - * check the subroom for some inconsistencies. - * e.g. simple polygons - * no intersection between the walls and the obstacles. - */ - void CheckObstacles(); - - /** - * Check the subroom for possible errors and - * output user specific informations. - */ - void SanityCheck(); - - //navigation - void AddCrossing(Crossing* line); - void AddTransition(Transition* line); - void AddHline(Hline* line); - - const std::vector<Crossing*>& GetAllCrossings() const; - const std::vector<Transition*>& GetAllTransitions() const; - const std::vector<Hline*>& GetAllHlines() const; - const Crossing* GetCrossing(int i) const; - const Transition* GetTransition(int i) const; - const Hline* GetHline(int i) const; - - - /** - * Add a wall to the subroom - */ - void AddWall(const Wall& w); - - /** - * Adds an obstacle to the subroom. - * They are used for the triangulation/convexifivation process - */ - void AddObstacle(Obstacle* obs); - - /** - * Remove the pedestrian from the subroom. - * @param index, the index of the peds in the vector (NOT THE ID !) - */ - void DeletePedestrian(int index); - //void DeletePedestrian(Pedestrian* ped); - void AddGoalID(int ID); - void RemoveGoalID(int ID); - - - - /** - * @return true if the two subrooms share a common walkable Edge (crossing or transition) - */ - bool IsDirectlyConnectedWith(const SubRoom* sub) const; - - /** - * @return true if the two segments are visible from each other. - * Alls walls and transitions and crossings are used in this check. - * The use of hlines is optional, because they are not real, can can be considered transparent - */ - bool IsVisible(Line* l1, Line* l2, bool considerHlines=false); - - /** - * @return true if the two points are visible from each other. - * Alls walls and transitions and crossings are used in this check. - * The use of hlines is optional, because they are not real, can be considered transparent - */ - bool IsVisible(const Point& p1, const Point& p2, bool considerHlines=false); - - - - // virtual functions - virtual std::string WriteSubRoom() const = 0; - virtual void WriteToErrorLog() const = 0; - virtual std::string WritePolyLine() const=0; - - /// convert all walls and transitions(doors) into a polygon representing the subroom - virtual bool ConvertLineToPoly(std::vector<Line*> goals) = 0; - - ///check whether the pedestrians is still in the subroom - virtual bool IsInSubRoom(const Point& ped) const = 0; - - - // MPI: - void ClearAllPedestrians(); + // constructors + SubRoom(); + virtual ~SubRoom(); + + /** + * Set/Get the subroom id + */ + void SetSubRoomID(int ID); + + /** + * Set/Get the associated room id + */ + void SetRoomID(int ID); + + void SetClosed(double c); + + /** + * Set the plane equation for this subroom. + * defined by: Z = Ax + By + C + */ + void SetPlanEquation(double A, double B, double C); + + /** + * Set/Get the subroom id + */ + int GetSubRoomID() const; + + /** + * @return the number of walls forming this subroom + */ + int GetNumberOfWalls() const; + + /** + * @return all walls + */ + const std::vector<Wall>& GetAllWalls() const; + + /** + * @return a reference to the wall at position index + */ + const Wall& GetWall(int index) const; + + /** + * @return the polygonal representation of the subroom + * counterclockwise + */ + const std::vector<Point>& GetPolygon() const; + + /** + * @return a reference to all obstacles contained + */ + const std::vector<Obstacle*>& GetAllObstacles() const; + + /** + * @return the number of hlines+transitions+crossings + */ + int GetNumberOfGoalIDs() const; + + /** + * @return a vector containing all Ids + */ + const std::vector<int>& GetAllGoalIDs() const; + + /** + * @return the room containing this subroom + */ + int GetRoomID() const; + + /** + * @return the unique identifier for this subroom + */ + int GetUID() const; + + /** + * Set/Get the type of the subroom. + * Possible types are: stairs, room and floor. + * @return the type of the subroom. + */ + const std::string& GetType() const; + + /** + * Set/Get the type of the subroom. + * Possible types are: stairs, room and floor. + * @return the type of the subroom. + */ + void SetType(const std::string& type); + + + /** + * @return the status + */ + double GetClosed() const; + + /** + * @return the area + */ + double GetArea() const; + + /** + * @return the centroid of the subroom + * @see http://en.wikipedia.org/wiki/Centroid + */ + Point GetCentroid() const; + + /** + * @return the three coefficients of the plane equation. + * defined by: Z = Ax + By + C + */ + const double * GetPlaneEquation () const; + + /** + * @return the elevation of a 2Dimensional point using the plane equation. + * @see GetPlanEquation + */ + double GetElevation(const Point & p1) const; + + /** + * compute the cosine of the dihedral angle with the Horizontal plane Z=h + * @return the cosine of the angle + */ + double GetCosAngleWithHorizontal() const; + + /** + * Compute the area of the subroom. + * @see GetArea() + */ + void CalculateArea(); + + /** + * @return true if the polygon is convex + * @see http://stackoverflow.com/questions/471962/how-do-determine-if-a-polygon-is-complex-convex-nonconvex + */ + bool IsConvex(); + + /** + * @return true if the polygon is clockwise oriented + * @see http://stackoverflow.com/questions/9473570/polygon-vertices-clockwise-or-counterclockwise/ + */ + bool IsClockwise(); + + /** + * check the subroom for some inconsistencies. + * e.g. simple polygons + * no intersection between the walls and the obstacles. + */ + void CheckObstacles(); + + /** + * Check the subroom for possible errors and + * output user specific informations. + */ + bool SanityCheck(); + + //navigation + void AddCrossing(Crossing* line); + void AddTransition(Transition* line); + void AddHline(Hline* line); + + const std::vector<Crossing*>& GetAllCrossings() const; + const std::vector<Transition*>& GetAllTransitions() const; + const std::vector<Hline*>& GetAllHlines() const; + const Crossing* GetCrossing(int i) const; + const Transition* GetTransition(int i) const; + const Hline* GetHline(int i) const; + + /** + * Add a wall to the subroom + */ + void AddWall(const Wall& w); + + /** + * Adds an obstacle to the subroom. + * They are used for the triangulation/convexifivation process + */ + void AddObstacle(Obstacle* obs); + + void AddGoalID(int ID); + void RemoveGoalID(int ID); + + /** + * @return true if the two subrooms share a common walkable Edge (crossing or transition) + */ + bool IsDirectlyConnectedWith(const SubRoom* sub) const; + + /** + * @return true if the two segments are visible from each other. + * Alls walls and transitions and crossings are used in this check. + * The use of hlines is optional, because they are not real, can can be considered transparent + */ + bool IsVisible(Line* l1, Line* l2, bool considerHlines=false); + + /** + * @return true if the two points are visible from each other. + * Alls walls and transitions and crossings are used in this check. + * The use of hlines is optional, because they are not real, can be considered transparent + */ + bool IsVisible(const Point& p1, const Point& p2, bool considerHlines=false); + + + // virtual functions + virtual std::string WriteSubRoom() const = 0; + virtual void WriteToErrorLog() const = 0; + virtual std::string WritePolyLine() const=0; + + /// convert all walls and transitions(doors) into a polygon representing the subroom + virtual bool ConvertLineToPoly(std::vector<Line*> goals) = 0; + + ///check whether the pedestrians is still in the subroom + virtual bool IsInSubRoom(const Point& ped) const = 0; + + // MPI: + void ClearAllPedestrians(); #ifdef _SIMULATOR - /** - * @return the number of pedestrians in this subroom - */ - int GetNumberOfPedestrians() const; - void AddPedestrian(Pedestrian* ped); - virtual bool IsInSubRoom(Pedestrian* ped) const; - void SetAllPedestrians(const std::vector<Pedestrian*>& peds); - void SetPedestrian(Pedestrian* ped, int index); - const std::vector<Pedestrian*>& GetAllPedestrians() const; - Pedestrian* GetPedestrian(int index) const; + virtual bool IsInSubRoom(Pedestrian* ped) const; #endif @@ -335,62 +309,62 @@ public: /************************************************************ NormalSubroom - ************************************************************/ +************************************************************/ class NormalSubRoom : public SubRoom { private: - ///@see IsInSubRoom - int WhichQuad(const Point& vertex, const Point& hitPos) const; - double Xintercept(const Point& point1, const Point& point2, double hitY) const; + ///@see IsInSubRoom + int WhichQuad(const Point& vertex, const Point& hitPos) const; + double Xintercept(const Point& point1, const Point& point2, double hitY) const; public: - NormalSubRoom(); - NormalSubRoom(const NormalSubRoom& orig); - virtual ~NormalSubRoom(); + NormalSubRoom(); + NormalSubRoom(const NormalSubRoom& orig); + virtual ~NormalSubRoom(); - std::string WriteSubRoom() const; - std::string WritePolyLine() const; + std::string WriteSubRoom() const; + std::string WritePolyLine() const; - virtual void WriteToErrorLog() const; - virtual bool ConvertLineToPoly(std::vector<Line*> goals); - bool IsInSubRoom(const Point& ped) const; + void WriteToErrorLog() const; + bool ConvertLineToPoly(std::vector<Line*> goals); + bool IsInSubRoom(const Point& ped) const; }; /************************************************************ Stair - ************************************************************/ +************************************************************/ class Stair : public NormalSubRoom { private: - Point pUp; /// Punkt der den oberen Bereich der Treppe markiert - Point pDown; /// Punkt der den unteren Bereich der Treppe markiert + Point pUp; /// Punkt der den oberen Bereich der Treppe markiert + Point pDown; /// Punkt der den unteren Bereich der Treppe markiert - const Point* CheckCorner(const Point** otherPoint, const Point** aktPoint, const Point* nextPoint); + const Point* CheckCorner(const Point** otherPoint, const Point** aktPoint, const Point* nextPoint); public: - Stair(); - Stair(const Stair& orig); - virtual ~Stair(); - - // Setter-Funktionen - void SetUp(const Point& p); - void SetDown(const Point& p); - - // Getter-Funktionen - const Point& GetUp() const; - const Point& GetDown() const; - - /// pedestrians are going the stairs downwards - bool IsUpStairs() const; - /// pedestrians are going the stairs upwards - bool IsDownStair() const; - - std::string WriteSubRoom() const; - std::string WritePolyLine() const; - virtual void WriteToErrorLog() const; - virtual bool ConvertLineToPoly(std::vector<Line*> goals); - bool IsInSubRoom(const Point& ped) const; + Stair(); + Stair(const Stair& orig); + virtual ~Stair(); + + // Setter-Funktionen + void SetUp(const Point& p); + void SetDown(const Point& p); + + // Getter-Funktionen + const Point& GetUp() const; + const Point& GetDown() const; + + /// pedestrians are going the stairs downwards + bool IsUpStairs() const; + /// pedestrians are going the stairs upwards + bool IsDownStair() const; + + std::string WriteSubRoom() const; + std::string WritePolyLine() const; + virtual void WriteToErrorLog() const; + virtual bool ConvertLineToPoly(std::vector<Line*> goals); + bool IsInSubRoom(const Point& ped) const; }; -#endif /* _SUBROOM_H */ +#endif /* _SUBROOM_H */ diff --git a/src/geometry/Transition.cpp b/src/geometry/Transition.cpp index df12dffbc3f5fdafe1104ba77a248927db6a8ad6..f27e39ed9bcf0060d4370806ac73518b1359dd8c 100644 --- a/src/geometry/Transition.cpp +++ b/src/geometry/Transition.cpp @@ -1,13 +1,14 @@ /** - * File: Transition.cpp + * \file Transition.cpp + * \date Nov 16, 2010 + * \version v0.5 + * \copyright <2009-2014> Forschungszentrum Jülich GmbH. All rights reserved. * - * Created on 16. November 2010, 12:57 - * - * @section LICENSE + * \section License * This file is part of JuPedSim. * * JuPedSim is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by + * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * @@ -16,18 +17,19 @@ * 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 + * You should have received a copy of the GNU Lesser General Public License * along with JuPedSim. If not, see <http://www.gnu.org/licenses/>. * - * @section DESCRIPTION - * + * \section Description * * - */ + **/ + #include "Transition.h" #include "Room.h" #include "SubRoom.h" +#include "../IO/OutputHandler.h" using namespace std; @@ -37,8 +39,10 @@ using namespace std; Transition::Transition() : Crossing() { - _isOpen = true; - _room2 = NULL; + _isOpen = true; + _doorUsage=0; + _lastPassingTime=0; + _room2 = NULL; } Transition::~Transition() @@ -49,56 +53,56 @@ Transition::~Transition() void Transition::Close() { - _isOpen = false; + _isOpen = false; } void Transition::Open() { - _isOpen = true; + _isOpen = true; } void Transition::SetType(string type) { - _type=type; + _type=type; } void Transition::SetRoom2(Room* r) { - _room2 = r; + _room2 = r; } // Getter-Funktionen bool Transition::IsOpen() const { - return _isOpen; + return _isOpen; } Room* Transition::GetRoom2() const { - return _room2; + return _room2; } string Transition::GetType() const { - return _type; + return _type; } // Sonstiges // gibt den ANDEREN room != roomID zurück Room* Transition::GetOtherRoom(int roomID) const { - if (GetRoom1()!=NULL && GetRoom1()->GetID() == roomID) { - return GetRoom2(); - } else if (GetRoom2()!=NULL && GetRoom2()->GetID() == roomID) { - return GetRoom1(); - } else { - char msg[CLENGTH]; - sprintf(msg,"ERROR: \tTransition::GetOtherRoom() wrong roomID [%d]",roomID); - Log->Write(msg); - exit(0); - } + if (GetRoom1()!=NULL && GetRoom1()->GetID() == roomID) { + return GetRoom2(); + } else if (GetRoom2()!=NULL && GetRoom2()->GetID() == roomID) { + return GetRoom1(); + } else { + char msg[CLENGTH]; + sprintf(msg,"ERROR: \tTransition::GetOtherRoom() wrong roomID [%d]",roomID); + Log->Write(msg); + exit(0); + } } // virtuelle Funktionen @@ -106,26 +110,26 @@ Room* Transition::GetOtherRoom(int roomID) const // prüft ob Ausgang nach draußen bool Transition::IsExit() const { - if(GetRoom1()!=NULL && _room2!=NULL) - return false; - else - return true; + if(GetRoom1()!=NULL && _room2!=NULL) + return false; + else + return true; } // prüft, ob Transition in Raum mit roomID bool Transition::IsInRoom(int roomID) const { - bool c1 = false; - bool c2 = false; - if (GetRoom1() != NULL && GetRoom1()->GetID() == roomID) - c1 = true; - if (GetRoom2() != NULL && GetRoom2()->GetID() == roomID) - c2 = true; - return c1 || c2; + bool c1 = false; + bool c2 = false; + if (GetRoom1() != NULL && GetRoom1()->GetID() == roomID) + c1 = true; + if (GetRoom2() != NULL && GetRoom2()->GetID() == roomID) + c2 = true; + return c1 || c2; } bool Transition::IsTransition() const { - return true; + return true; } @@ -134,65 +138,79 @@ bool Transition::IsTransition() const * (virtuelle Funktion) */ SubRoom* Transition::GetOtherSubRoom(int roomID, int subroomID) const { - if ((GetRoom1() != NULL) && (GetRoom1()->GetID() == roomID)) - return GetSubRoom2(); - else if ((GetRoom2() != NULL) && (GetRoom2()->GetID() == roomID)) - return GetSubRoom1(); - else { - char tmp[CLENGTH]; - sprintf(tmp,"ERROR: \tTransition::GetOtherSubRoom No exit found " - "on the other side\n ID=%hd, roomID=%hd, subroomID=%hd\n",GetUniqueID(),roomID,subroomID); - Log->Write(tmp); - exit(0); - } + if ((GetRoom1() != NULL) && (GetRoom1()->GetID() == roomID)) + return GetSubRoom2(); + else if ((GetRoom2() != NULL) && (GetRoom2()->GetID() == roomID)) + return GetSubRoom1(); + else { + Log->Write("ERROR: \tTransition::GetOtherSubRoom No exit found " + "on the other side\n ID=%d, roomID=%d, subroomID=%d\n",GetUniqueID(),roomID,subroomID); + exit(EXIT_FAILURE); + } } // Ein-Ausgbae void Transition::WriteToErrorLog() const { - string s; - char tmp[CLENGTH]; - sprintf(tmp, "\t\tTRANS: %d [%s] (%f, %f) -- (%f, %f)\n", GetID(), GetCaption().c_str(), - GetPoint1().GetX(), GetPoint1().GetY(), GetPoint2().GetX(), GetPoint2().GetY()); - s.append(tmp); - // erster Raum - if (GetRoom1() != NULL) { - sprintf(tmp, "\t\t\t\tRoom: %d [%s] SubRoom: %d", GetRoom1()->GetID(), - GetRoom1()->GetCaption().c_str(), GetSubRoom1()->GetSubRoomID()); - } else { - sprintf(tmp, "\t\t\t\tAusgang"); - } - s.append(tmp); - // zweiter Raum - if (GetRoom2() != NULL) { - sprintf(tmp, " <->\tRoom: %d [%s] SubRoom: %d\n", GetRoom2()->GetID(), - GetRoom2()->GetCaption().c_str(), GetSubRoom2()->GetSubRoomID()); - } else { - sprintf(tmp, " <->\tAusgang\n"); - } - s.append(tmp); - Log->Write(s); + string s; + char tmp[CLENGTH]; + sprintf(tmp, "\t\tTRANS: %d [%s] (%f, %f) -- (%f, %f)\n", GetID(), GetCaption().c_str(), + GetPoint1().GetX(), GetPoint1().GetY(), GetPoint2().GetX(), GetPoint2().GetY()); + s.append(tmp); + // erster Raum + if (GetRoom1() != NULL) { + sprintf(tmp, "\t\t\t\tRoom: %d [%s] SubRoom: %d", GetRoom1()->GetID(), + GetRoom1()->GetCaption().c_str(), GetSubRoom1()->GetSubRoomID()); + } else { + sprintf(tmp, "\t\t\t\tAusgang"); + } + s.append(tmp); + // zweiter Raum + if (GetRoom2() != NULL) { + sprintf(tmp, " <->\tRoom: %d [%s] SubRoom: %d\n", GetRoom2()->GetID(), + GetRoom2()->GetCaption().c_str(), GetSubRoom2()->GetSubRoomID()); + } else { + sprintf(tmp, " <->\tAusgang\n"); + } + s.append(tmp); + Log->Write(s); } // TraVisTo Ausgabe string Transition::WriteElement() const { - string geometry; - char tmp[CLENGTH] = ""; - - sprintf(tmp,"\t\t<door ID=\"%d\" color=\"180\" caption=\"%d_%d_%s\">\n",GetUniqueID(),GetID(),GetUniqueID(),GetCaption().c_str()); - geometry.append(tmp); - sprintf(tmp, "\t\t\t<point xPos=\"%.2f\" yPos=\"%.2f\" zPos=\"%.2f\"/>\n", - (GetPoint1().GetX()) * FAKTOR, - (GetPoint1().GetY()) * FAKTOR, - GetSubRoom1()->GetElevation(GetPoint1())*FAKTOR); - geometry.append(tmp); - sprintf(tmp, "\t\t\t<point xPos=\"%.2f\" yPos=\"%.2f\" zPos=\"%.2f\"/>\n", - (GetPoint2().GetX()) * FAKTOR, - (GetPoint2().GetY()) * FAKTOR, - GetSubRoom1()->GetElevation(GetPoint2())*FAKTOR); - geometry.append(tmp); - geometry.append("\t\t</door>\n"); - return geometry; + string geometry; + char tmp[CLENGTH] = ""; + + sprintf(tmp,"\t\t<door ID=\"%d\" color=\"180\" caption=\"%d_%d_%s\">\n",GetUniqueID(),GetID(),GetUniqueID(),GetCaption().c_str()); + geometry.append(tmp); + sprintf(tmp, "\t\t\t<point xPos=\"%.2f\" yPos=\"%.2f\" zPos=\"%.2f\"/>\n", + (GetPoint1().GetX()) * FAKTOR, + (GetPoint1().GetY()) * FAKTOR, + GetSubRoom1()->GetElevation(GetPoint1())*FAKTOR); + geometry.append(tmp); + sprintf(tmp, "\t\t\t<point xPos=\"%.2f\" yPos=\"%.2f\" zPos=\"%.2f\"/>\n", + (GetPoint2().GetX()) * FAKTOR, + (GetPoint2().GetY()) * FAKTOR, + GetSubRoom1()->GetElevation(GetPoint2())*FAKTOR); + geometry.append(tmp); + geometry.append("\t\t</door>\n"); + return geometry; +} + +void Transition::IncreaseDoorUsage(int number, double time) +{ + _doorUsage+=number; + _lastPassingTime=time; +} + +int Transition::GetDoorUsage() const +{ + return _doorUsage; +} + +double Transition::GetLastPassingTime() const +{ + return _lastPassingTime; } diff --git a/src/geometry/Transition.h b/src/geometry/Transition.h index e8fcb604e710ca20ebc292d3c0e739fc4284a43e..0ee3e76c50713bb244dd668cc6699d57a603a3a3 100644 --- a/src/geometry/Transition.h +++ b/src/geometry/Transition.h @@ -1,13 +1,14 @@ /** - * File: Transition.h + * \file Transition.h + * \date Nov 16, 2010 + * \version v0.5 + * \copyright <2009-2014> Forschungszentrum Jülich GmbH. All rights reserved. * - * Created on 16. November 2010, 12:57 - * - * @section LICENSE + * \section License * This file is part of JuPedSim. * * JuPedSim is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by + * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * @@ -16,16 +17,17 @@ * 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 + * You should have received a copy of the GNU Lesser General Public License * along with JuPedSim. If not, see <http://www.gnu.org/licenses/>. * - * @section DESCRIPTION + * \section Description * * - */ + **/ + #ifndef _TRANSITION_H -#define _TRANSITION_H +#define _TRANSITION_H #include "Crossing.h" #include <string> @@ -35,67 +37,84 @@ class Subroom; class Transition : public Crossing { private: - Room* _room2; - bool _isOpen; - std::string _type; + Room* _room2; + bool _isOpen; + std::string _type; + // number of agents that passed that exit + int _doorUsage; + double _lastPassingTime; public: - Transition(); - virtual ~Transition(); - - /** - * Close the transition/door - */ - void Close(); - - /** - * Open the transition/door - */ - void Open(); - - /** - * Set/Get the type of the transition - * TODO: where is type defined? - */ - void SetType(std::string s); - - /** - * Set/Get the second room associated with this transition. - * The first one is set in the crossing class. - */ - void SetRoom2(Room* ID); - - - /** - * Set/Get the type of the transition - * TODO: where is type defined? - */ - std::string GetType() const; - - /** - * Set/Get the second room associated with this transition. - * The first one is set in the crossing class. - */ - Room* GetRoom2() const; - - - /** - * @return the other room. - */ - Room* GetOtherRoom(int room_id) const; - - // virtual functions - virtual bool IsOpen() const; - virtual bool IsExit() const; - virtual bool IsTransition() const; - virtual bool IsInRoom(int roomID) const; - virtual SubRoom* GetOtherSubRoom(int roomID, int subroomID) const; - - - virtual void WriteToErrorLog() const; - virtual std::string WriteElement() const; // TraVisTo Ausgabe + Transition(); + virtual ~Transition(); + + /** + * Close the transition/door + */ + void Close(); + + /** + * Open the transition/door + */ + void Open(); + + /** + * Set/Get the type of the transition + */ + void SetType(std::string s); + + /** + * Set/Get the second room associated with this transition. + * The first one is set in the crossing class. + */ + void SetRoom2(Room* ID); + + /** + * Increment the number of persons that used that exit + * @param number, how many person have passed the door + * @param time, at which time + */ + void IncreaseDoorUsage(int number, double time); + + /** + * @return the number of pedestrians that used that exit. + */ + int GetDoorUsage() const; + + /** + * @return the last time this door was crossed + */ + double GetLastPassingTime() const; + + /** + * Set/Get the type of the transition + */ + std::string GetType() const; + + /** + * Set/Get the second room associated with this transition. + * The first one is set in the crossing class. + */ + Room* GetRoom2() const; + + + /** + * @return the other room. + */ + Room* GetOtherRoom(int room_id) const; + + // virtual functions + virtual bool IsOpen() const; + virtual bool IsExit() const; + virtual bool IsTransition() const; + virtual bool IsInRoom(int roomID) const; + virtual SubRoom* GetOtherSubRoom(int roomID, int subroomID) const; + + + virtual void WriteToErrorLog() const; + virtual std::string WriteElement() const; // TraVisTo Ausgabe }; -#endif /* _TRANSITION_H */ +#endif /* _TRANSITION_H */ diff --git a/src/geometry/Wall.cpp b/src/geometry/Wall.cpp index e3c02f4675e04b874c4e694905c2207ef51ebde4..b4a85122503ec8c5683bdbe8c642730613ea20f5 100644 --- a/src/geometry/Wall.cpp +++ b/src/geometry/Wall.cpp @@ -1,12 +1,14 @@ /** - * File: Wall.cpp + * \file Wall.cpp + * \date Nov 16, 2010 + * \version v0.5 + * \copyright <2009-2014> Forschungszentrum Jülich GmbH. All rights reserved. * - * Created on 16. November 2010, 12:55 - * @section LICENSE + * \section License * This file is part of JuPedSim. * * JuPedSim is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by + * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * @@ -15,14 +17,14 @@ * 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 + * You should have received a copy of the GNU Lesser General Public License * along with JuPedSim. If not, see <http://www.gnu.org/licenses/>. * - * @section DESCRIPTION + * \section Description * * - * - */ + **/ + #include "Wall.h" @@ -36,36 +38,46 @@ Wall::Wall() : Line() { } -Wall::Wall(const Point& p1, const Point& p2) : Line(p1, p2) +Wall::Wall(const Point& p1, const Point& p2, const std::string& type) : Line(p1, p2), _type(type) { - } Wall::Wall(const Wall& orig) : Line(orig) { + _type=orig.GetType(); } void Wall::WriteToErrorLog() const { - char tmp[CLENGTH]; - sprintf(tmp, "\t\tWALL: (%f, %f) -- (%f, %f)\n", GetPoint1().GetX(), - GetPoint1().GetY(), GetPoint2().GetX(), GetPoint2().GetY()); - Log->Write(tmp); + char tmp[CLENGTH]; + sprintf(tmp, "\t\tWALL: (%f, %f) -- (%f, %f)\n", GetPoint1().GetX(), + GetPoint1().GetY(), GetPoint2().GetX(), GetPoint2().GetY()); + Log->Write(tmp); } string Wall::Write() const { - string geometry; - char wall[500] = ""; - geometry.append("\t\t<wall>\n"); - sprintf(wall, "\t\t\t<point xPos=\"%.2f\" yPos=\"%.2f\"/>\n", - (GetPoint1().GetX()) * FAKTOR, - (GetPoint1().GetY()) * FAKTOR); - geometry.append(wall); - sprintf(wall, "\t\t\t<point xPos=\"%.2f\" yPos=\"%.2f\"/>\n", - (GetPoint2().GetX()) * FAKTOR, - (GetPoint2().GetY()) * FAKTOR); - geometry.append(wall); - geometry.append("\t\t</wall>\n"); - return geometry; + string geometry; + char wall[500] = ""; + geometry.append("\t\t<wall>\n"); + sprintf(wall, "\t\t\t<point xPos=\"%.2f\" yPos=\"%.2f\"/>\n", + (GetPoint1().GetX()) * FAKTOR, + (GetPoint1().GetY()) * FAKTOR); + geometry.append(wall); + sprintf(wall, "\t\t\t<point xPos=\"%.2f\" yPos=\"%.2f\"/>\n", + (GetPoint2().GetX()) * FAKTOR, + (GetPoint2().GetY()) * FAKTOR); + geometry.append(wall); + geometry.append("\t\t</wall>\n"); + return geometry; +} + +const std::string& Wall::GetType() const +{ + return _type; +} + +void Wall::SetType(const std::string& type) +{ + _type=type; } diff --git a/src/geometry/Wall.h b/src/geometry/Wall.h index 85e2ba51ee11a6bd166f5f0f7c7d5e79f93e3a0c..42829e20711ff9b0c0e866a0f89b3c5fc21d5305 100644 --- a/src/geometry/Wall.h +++ b/src/geometry/Wall.h @@ -1,13 +1,14 @@ /** - * File: Wall.h + * \file Wall.h + * \date Nov 16, 2010 + * \version v0.5 + * \copyright <2009-2014> Forschungszentrum Jülich GmbH. All rights reserved. * - * Created on 16. November 2010, 12:55 - * - * @section LICENSE + * \section License * This file is part of JuPedSim. * * JuPedSim is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by + * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * @@ -16,38 +17,51 @@ * 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 + * You should have received a copy of the GNU Lesser General Public License * along with JuPedSim. If not, see <http://www.gnu.org/licenses/>. * - * @section DESCRIPTION - * + * \section Description * * - */ + **/ + #ifndef _WALL_H -#define _WALL_H +#define _WALL_H #include "Line.h" class Wall : public Line { public: - Wall(); - Wall(const Point& p1, const Point& p2); - Wall(const Wall& orig); - - /** - * Debug output from the object - */ - void WriteToErrorLog() const; - - /** - * @return a nicely formated string of the object - */ - virtual std::string Write() const; + Wall(); + Wall(const Point& p1, const Point& p2, const std::string& type="internal"); + Wall(const Wall& orig); + + /** + * set/get the wall type. Values are external and internal + */ + const std::string& GetType() const; + + /** + * set/get the wall type. Values are external and internal + */ + void SetType(const std::string& type); + + /** + * Debug output from the object + */ + void WriteToErrorLog() const; + + /** + * @return a nicely formated string of the object + */ + virtual std::string Write() const; + +private: + std::string _type; }; -#endif /* _WALL_H */ +#endif /* _WALL_H */