worked on floorplan (v2)
worked on grid-generation (v2) new helper methods for geometry new test cases
This commit is contained in:
@@ -11,7 +11,28 @@
|
||||
|
||||
namespace Floorplan {
|
||||
|
||||
/** 3D polygon */
|
||||
|
||||
/** a free key-value meta element */
|
||||
struct Meta {
|
||||
|
||||
const std::string EMPTY = "";
|
||||
std::unordered_map<std::string, std::string> params;
|
||||
|
||||
const std::string& getVal(const std::string& key) const {
|
||||
const auto it = params.find(key);
|
||||
return (it == params.end()) ? (EMPTY) : (it->second);
|
||||
}
|
||||
void setVal(const std::string& key, const std::string& val) {params[key] = val;}
|
||||
|
||||
float getFloat(const std::string& key) const { return std::stof(getVal(key)); }
|
||||
void setFloat(const std::string& key, const float val) { params[key] = std::to_string(val); }
|
||||
|
||||
int getInt(const std::string& key) const { return std::stoi(getVal(key)); }
|
||||
void setInt(const std::string& key, const int val) { params[key] = std::to_string(val); }
|
||||
|
||||
};
|
||||
|
||||
/** 2D polygon */
|
||||
struct Polygon2 {
|
||||
std::vector<Point2> points;
|
||||
Polygon2() : points() {;}
|
||||
@@ -19,17 +40,37 @@ namespace Floorplan {
|
||||
bool operator == (const Polygon2& o) const {return std::equal(o.points.begin(), o.points.end(), this->points.begin());}
|
||||
};
|
||||
|
||||
/** 3D quad */
|
||||
struct Quad3 {
|
||||
Point3 p1;
|
||||
Point3 p2;
|
||||
Point3 p3;
|
||||
Point3 p4;
|
||||
Quad3(const Point3 p1, const Point3 p2, const Point3 p3, const Point3 p4) : p1(p1), p2(p2), p3(p3), p4(p4) {;}
|
||||
Quad3 operator * (const float v) const {return Quad3(p1*v, p2*v, p3*v, p4*v);}
|
||||
};
|
||||
|
||||
/** additional type-info for obstacles */
|
||||
enum class ObstacleType {
|
||||
UNKNOWN,
|
||||
WALL,
|
||||
DOOR,
|
||||
WINDOW,
|
||||
HANDRAIL,
|
||||
PILLAR,
|
||||
_END,
|
||||
};
|
||||
|
||||
/** available door types */
|
||||
enum class DoorType {
|
||||
UNKNOWN,
|
||||
SWING, // normal
|
||||
DOUBLE_SWING,
|
||||
SLIDE, // schiebetuer
|
||||
DOUBLE_SLIDE,
|
||||
REVOLVING, // drehtuer
|
||||
_END,
|
||||
};
|
||||
|
||||
/** all supported material types */
|
||||
enum class Material {
|
||||
UNKNOWN,
|
||||
@@ -40,6 +81,10 @@ namespace Floorplan {
|
||||
_END,
|
||||
};
|
||||
|
||||
enum class POIType {
|
||||
ROOM,
|
||||
};
|
||||
|
||||
/** types of outlines. either add or remove the selected region */
|
||||
enum class OutlineMethod {
|
||||
ADD,
|
||||
@@ -47,23 +92,78 @@ namespace Floorplan {
|
||||
_END,
|
||||
};
|
||||
|
||||
struct Floor;
|
||||
struct FloorOutlinePolygon;
|
||||
struct FloorObstacle;
|
||||
struct AccessPoint;
|
||||
struct Beacon;
|
||||
struct FloorRegion;
|
||||
struct UnderlayImage;
|
||||
struct POI;
|
||||
struct Stair;
|
||||
|
||||
using FloorOutline = std::vector<FloorOutlinePolygon*>;
|
||||
using FloorObstacles = std::vector<FloorObstacle*>;
|
||||
using FloorAccessPoints = std::vector<AccessPoint*>;
|
||||
using FloorBeacons = std::vector<Beacon*>;
|
||||
using FloorRegions = std::vector<FloorRegion*>;
|
||||
using FloorUnderlays = std::vector<UnderlayImage*>;
|
||||
using FloorPOIs = std::vector<POI*>;
|
||||
using FloorStairs = std::vector<Stair*>;
|
||||
|
||||
/** describes one floor within the map, starting at a given height */
|
||||
struct Floor {
|
||||
|
||||
float atHeight; // the floor's starting height
|
||||
float height; // the floor's total height (from start)
|
||||
std::string name; // the floor's name
|
||||
FloorOutline outline; // the floor's outline (ground)
|
||||
FloorObstacles obstacles; // all obstacles (wall, door, window, ..) within the floor
|
||||
FloorRegions regions; // all regions within the floor (rooms, ...)
|
||||
FloorAccessPoints accesspoints;
|
||||
FloorBeacons beacons;
|
||||
FloorUnderlays underlays; // underlay images (used for map-building)
|
||||
FloorPOIs pois; // POIs within the floor
|
||||
FloorStairs stairs; // all stairs within one floor
|
||||
//FloorKeyValue other; // other, free elements
|
||||
|
||||
Floor() {;}
|
||||
|
||||
Floor(const Floor& o) = delete;
|
||||
void operator = (const Floor& o) = delete;
|
||||
|
||||
float getStartingZ() const {return atHeight;}
|
||||
float getEndingZ() const {return atHeight + height;}
|
||||
|
||||
};
|
||||
|
||||
|
||||
/** an AccessPoint located somewhere within the map */
|
||||
/** a POI located somewhere on a floor */
|
||||
struct POI {
|
||||
POIType type;
|
||||
std::string name;
|
||||
Point2 pos;
|
||||
POI() : type(), name(), pos() {;}
|
||||
POI(const POIType type, const std::string& name, const Point2& pos) : type(type), name(name), pos(pos) {;}
|
||||
bool operator == (const POI& o) const {return (o.type == type) && (o.name == name) && (o.pos == pos);}
|
||||
};
|
||||
|
||||
/** an AccessPoint located somewhere on a floor */
|
||||
struct AccessPoint {
|
||||
std::string name;
|
||||
std::string mac;
|
||||
Point3 pos;
|
||||
Point3 pos; // z is relative to the floor's height
|
||||
AccessPoint() : name(), mac(), pos() {;}
|
||||
AccessPoint(const std::string& name, const std::string& mac, const Point3& pos) : name(name), mac(mac), pos(pos) {;}
|
||||
bool operator == (const AccessPoint& o) const {return (o.name == name) && (o.mac == mac) && (o.pos == pos);}
|
||||
Point3 getPos(const Floor* f) const {return pos + Point3(0,0,f->atHeight);} // relative to the floor's ground
|
||||
};
|
||||
|
||||
/** a beacon located somewhere within the map */
|
||||
/** a beacon located somewhere on a floor */
|
||||
struct Beacon {
|
||||
std::string name;
|
||||
std::string mac;
|
||||
Point3 pos;
|
||||
Point3 pos; // z is relative to the floor's height
|
||||
Beacon() : name(), mac(), pos() {;}
|
||||
Beacon(const std::string& name, const std::string& mac, const Point3& pos) : name(name), mac(mac), pos(pos) {;}
|
||||
bool operator == (const Beacon& o) const {return (o.name == name) && (o.mac == mac) && (o.pos == pos);}
|
||||
@@ -80,31 +180,51 @@ namespace Floorplan {
|
||||
bool operator == (const FloorOutlinePolygon& o) const {return (o.method == method) && (o.name == name) && (o.poly == poly);}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/** base-class for one obstacle (wall, door, window, pillar, ..) within a floor */
|
||||
struct FloorObstacle {
|
||||
ObstacleType type;
|
||||
Material material;
|
||||
FloorObstacle() : type(), material() {;}
|
||||
FloorObstacle(const ObstacleType type, const Material material) : type(type), material(material) {;}
|
||||
FloorObstacle() : material() {;}
|
||||
FloorObstacle(const Material material) : material(material) {;}
|
||||
virtual ~FloorObstacle() {;}
|
||||
};
|
||||
|
||||
/** line obstacle */
|
||||
struct FloorObstacleLine : public FloorObstacle {
|
||||
ObstacleType type;
|
||||
Point2 from;
|
||||
Point2 to;
|
||||
FloorObstacleLine(const ObstacleType type, const Material material, const Point2 from, const Point2 to) : FloorObstacle(type, material), from(from), to(to) {;}
|
||||
FloorObstacleLine(const ObstacleType type, const Material material, const float x1, const float y1, const float x2, const float y2) : FloorObstacle(type, material), from(x1,y1), to(x2,y2) {;}
|
||||
FloorObstacleLine(const ObstacleType type, const Material material, const Point2 from, const Point2 to) : FloorObstacle(material), type(type), from(from), to(to) {;}
|
||||
FloorObstacleLine(const ObstacleType type, const Material material, const float x1, const float y1, const float x2, const float y2) : FloorObstacle(material), type(type), from(x1,y1), to(x2,y2) {;}
|
||||
};
|
||||
|
||||
/** circle obstacle */
|
||||
struct FloorObstacleCircle : public FloorObstacle {
|
||||
Point2 center;
|
||||
float radius;
|
||||
FloorObstacleCircle(const ObstacleType type, const Material material, const Point2 center, const float radius) : FloorObstacle(type, material), center(center), radius(radius) {;}
|
||||
FloorObstacleCircle(const ObstacleType type, const Material material, const float cx, const float cy, const float radius) : FloorObstacle(type, material), center(cx,cy), radius(radius) {;}
|
||||
FloorObstacleCircle(const Material material, const Point2 center, const float radius) : FloorObstacle(material), center(center), radius(radius) {;}
|
||||
FloorObstacleCircle(const Material material, const float cx, const float cy, const float radius) : FloorObstacle(material), center(cx,cy), radius(radius) {;}
|
||||
};
|
||||
|
||||
/** door obstacle */
|
||||
struct FloorObstacleDoor : public FloorObstacle {
|
||||
DoorType type;
|
||||
Point2 from;
|
||||
Point2 to;
|
||||
float height;
|
||||
bool swap;
|
||||
FloorObstacleDoor(const DoorType type, const Material material, const Point2 from, const Point2 to) : FloorObstacle(material), type(type), from(from), to(to), height(2.1), swap(false) {;}
|
||||
FloorObstacleDoor(const DoorType type, const Material material, const float x1, const float y1, const float x2, const float y2, const float height, const bool swap) : FloorObstacle(material), type(type), from(x1,y1), to(x2,y2), height(height), swap(swap) {;}
|
||||
float getSize() const {return (to-from).length();}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/** one region (e.g. a room) within the floor, described using a polygon */
|
||||
struct FloorRegion {
|
||||
std::string name;
|
||||
@@ -115,6 +235,158 @@ namespace Floorplan {
|
||||
|
||||
|
||||
|
||||
static Point3 xy0(const Point2 p) {
|
||||
return Point3(p.x, p.y, 0);
|
||||
}
|
||||
|
||||
/** describes a plane as starting point, ending point and fixed width */
|
||||
struct StairPart {
|
||||
|
||||
/** z is relative to the floor's height */
|
||||
Point3 start;
|
||||
|
||||
/** z is relative to the floor's height */
|
||||
Point3 end;
|
||||
|
||||
/** the width for this element */
|
||||
float width;
|
||||
|
||||
/** whether to connect this element with the previous one */
|
||||
bool connectWithPrev;
|
||||
|
||||
StairPart() {;}
|
||||
|
||||
StairPart(const Point3 start, const Point3 end, const float width) : start(start), end(end), width(width), connectWithPrev(false) {;}
|
||||
|
||||
StairPart(Point3 center, float deg, float length, float width, float height) {
|
||||
this->start = Point3(-length/2, 0, -height/2);
|
||||
this->end = Point3(+length/2, 0, +height/2);
|
||||
this->width = width;
|
||||
rotate(deg/180.0*M_PI);
|
||||
move(center);
|
||||
}
|
||||
|
||||
/** convenience method for array access [0:1] to start and end */
|
||||
Point3& operator [] (const int idx) {
|
||||
switch (idx) {
|
||||
case 0: return start;
|
||||
case 1: return end;
|
||||
default: throw "error";
|
||||
}
|
||||
}
|
||||
|
||||
void rotate(const float rad) {
|
||||
const float ca = std::cos(rad);
|
||||
const float sa = std::sin(rad);
|
||||
start = Point3(ca*start.x - sa*start.y, sa*start.x + ca * start.y, start.z);
|
||||
end = Point3(ca*end.x - sa*end.y, sa*end.x + ca * end.y, end.z);;
|
||||
}
|
||||
|
||||
void move(const Point3 p) {
|
||||
start += p;
|
||||
end += p;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
static std::vector<Quad3> getQuads(const std::vector<StairPart>& parts, const Floor* floor) {
|
||||
|
||||
std::vector<Quad3> vec;
|
||||
|
||||
for (const StairPart& part : parts) {
|
||||
|
||||
const float width = part.width;
|
||||
const Point3 start = part.start;
|
||||
const Point3 end = part.end;
|
||||
const Point3 dir = end - start; // direction vector
|
||||
const Point2 dir2(dir.x, dir.y); // direction without height (just 2D)
|
||||
const Point2 perp = dir2.perpendicular(); // perendicular vector
|
||||
const Point2 perpN = perp / perp.length(); // normalized perpendicular vector
|
||||
const Point3 p1 = start + xy0(perpN * width / 2) + Point3(0,0,floor->atHeight);
|
||||
const Point3 p2 = start - xy0(perpN * width / 2) + Point3(0,0,floor->atHeight);
|
||||
const Point3 p3 = end - xy0(perpN * width / 2) + Point3(0,0,floor->atHeight);
|
||||
const Point3 p4 = end + xy0(perpN * width / 2) + Point3(0,0,floor->atHeight);
|
||||
const Quad3 q(p1,p2,p3,p4);
|
||||
vec.push_back(q);
|
||||
|
||||
// connect
|
||||
if (part.connectWithPrev) {
|
||||
if (vec.size() >= 2) {
|
||||
Quad3& a = vec[vec.size()-2];
|
||||
Quad3& b = vec[vec.size()-1];
|
||||
Point3 pa = (a.p3 + b.p2)/2; a.p3 = pa; b.p2 = pa;
|
||||
Point3 pb = (a.p4 + b.p1)/2; a.p4 = pb; b.p1 = pb;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return vec;
|
||||
|
||||
}
|
||||
|
||||
// /**
|
||||
// * get the ABSOLUTE quad for this stair-part
|
||||
// * (relative-height + floor-height = absolute-height
|
||||
// */
|
||||
// Quad3 getQuad(const Floor* floor) const {
|
||||
|
||||
// }
|
||||
|
||||
/** base-class for stairs */
|
||||
struct Stair {
|
||||
Meta* meta = nullptr;
|
||||
virtual std::vector<StairPart> getParts() const = 0;
|
||||
};
|
||||
|
||||
// /** just a normal, straigt stair */
|
||||
// struct StairNormal : public Stair {
|
||||
// Point2 center;
|
||||
// float angleDeg;
|
||||
// float atHeight;
|
||||
// float height;
|
||||
// float width;
|
||||
// float length;
|
||||
// StairNormal(const Point2 center, const float atHeight, const float angleDeg, const float height, const float width, const float length) :
|
||||
// center(center), angleDeg(angleDeg), atHeight(atHeight), height(height), width(width), length(length) {
|
||||
|
||||
|
||||
// }
|
||||
// std::vector<StairPart> getParts() const {
|
||||
// std::vector<StairPart> parts;
|
||||
// Point3 cen(center.x, center.y, atHeight);
|
||||
// parts.push_back(StairPart(cen, angleDeg, length, width, height));
|
||||
// return parts;
|
||||
// }
|
||||
// };
|
||||
|
||||
// /** OLD 3-part stair, up[left]->platform->up[right] */
|
||||
// struct StairFreeformOLD : public Stair {
|
||||
// float width;
|
||||
// std::vector<Point3> nodes;
|
||||
// StairFreeformOLD() {;}
|
||||
// std::vector<StairPart> getParts() const {
|
||||
// std::vector<StairPart> parts;
|
||||
// for (int i = 1; i < (int)nodes.size(); ++i) {
|
||||
// const Point3 p1 = nodes[i-1];
|
||||
// const Point3 p2 = nodes[i ];
|
||||
// parts.push_back(StairPart(p1, p2, width));
|
||||
// }
|
||||
// return parts;
|
||||
// }
|
||||
// };
|
||||
|
||||
/** 3-part stair, up[left]->platform->up[right] */
|
||||
struct StairFreeform : public Stair {
|
||||
std::vector<StairPart> parts;
|
||||
StairFreeform() {;}
|
||||
std::vector<StairPart> getParts() const {return parts;}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/** an image file that can be added to the map */
|
||||
struct UnderlayImage {
|
||||
std::string name;
|
||||
@@ -124,50 +396,7 @@ namespace Floorplan {
|
||||
float scaleY;
|
||||
};
|
||||
|
||||
/** a free key-value element */
|
||||
struct KeyValueElement {
|
||||
std::string empty;
|
||||
std::unordered_map<std::string, std::string> params;
|
||||
const std::string& getVal(const std::string& key) const {
|
||||
auto it = params.find(key);
|
||||
return (it == params.end()) ? (empty) : (it->second);
|
||||
}
|
||||
float getFloat(const std::string& key) const { return std::stof(getVal(key)); }
|
||||
void setVal(const std::string& key, const std::string& val) {
|
||||
params[key] = val;
|
||||
}
|
||||
void setFloat(const std::string& key, const float val) {
|
||||
params[key] = std::to_string(val);
|
||||
}
|
||||
};
|
||||
|
||||
using FloorOutline = std::vector<FloorOutlinePolygon*>;
|
||||
using FloorObstacles = std::vector<FloorObstacle*>;
|
||||
using FloorAccessPoints = std::vector<AccessPoint*>;
|
||||
using FloorBeacons = std::vector<Beacon*>;
|
||||
using FloorRegions = std::vector<FloorRegion*>;
|
||||
using FloorUnderlays = std::vector<UnderlayImage*>;
|
||||
|
||||
/** describes one floor within the map, starting at a given height */
|
||||
struct Floor {
|
||||
|
||||
float atHeight; // the floor's starting height
|
||||
float height; // the floor's total height (from start)
|
||||
std::string name; // the floor's name
|
||||
FloorOutline outline; // the floor's outline (ground)
|
||||
FloorObstacles obstacles; // all obstacles (wall, door, window, ..) within the floor
|
||||
FloorRegions regions; // all regions within the floor (rooms, ...)
|
||||
FloorAccessPoints accesspoints;
|
||||
FloorBeacons beacons;
|
||||
FloorUnderlays underlays; // underlay images (used for map-building)
|
||||
//FloorKeyValue other; // other, free elements
|
||||
|
||||
Floor() {;}
|
||||
|
||||
Floor(const Floor& o) = delete;
|
||||
void operator = (const Floor& o) = delete;
|
||||
|
||||
};
|
||||
|
||||
/** describes the whole indoor map */
|
||||
struct IndoorMap {
|
||||
|
||||
Reference in New Issue
Block a user