zoomedit: ?berschlagene Polygone werden jetzt korrekt gerendert
This commit is contained in:
parent
62e4240848
commit
1e9704dca9
15 changed files with 259 additions and 179 deletions
52
Line.cpp
52
Line.cpp
|
@ -3,52 +3,52 @@
|
|||
|
||||
|
||||
bool Line::contains(const Vertex &v) const {
|
||||
if(v1.getX() == v2.getX() && v1.getY() == v2.getY()) {
|
||||
if(v1.getX() == v.getX() && v1.getY() == v.getY())
|
||||
if(fabs(v1.getX() - v2.getX()) < 1E-6 && fabs(v1.getY() - v2.getY()) < 1E-6) {
|
||||
if(fabs(v1.getX() - v.getX()) < 1E-6 && fabs(v1.getY() - v.getY()) < 1E-6)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
if(v1.getX() == v2.getX()) {
|
||||
if(v1.getX() != v.getX())
|
||||
if(fabs(v1.getX() - v2.getX()) < 1E-6) {
|
||||
if(fabs(v1.getX() - v.getX()) >= 1E-6)
|
||||
return false;
|
||||
else if(v.getY() >= fmin(v1.getY(), v2.getY()) && v.getY() <= fmax(v1.getY(), v2.getY()))
|
||||
else if(v.getY() - fmin(v1.getY(), v2.getY()) > -1E-6 && v.getY() - fmax(v1.getY(), v2.getY()) < 1E-6)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
if(v1.getY() == v2.getY()) {
|
||||
if(v1.getY() != v.getY())
|
||||
if(fabs(v1.getY() - v2.getY()) < 1E-6) {
|
||||
if(fabs(v1.getY() - v.getY()) >= 1E-6)
|
||||
return false;
|
||||
else if(v.getX() >= fmin(v1.getX(), v2.getX()) && v.getX() <= fmax(v1.getX(), v2.getX()))
|
||||
else if(v.getX() - fmin(v1.getX(), v2.getX()) > -1E-6 && v.getX() - fmax(v1.getX(), v2.getX()) < 1E-6)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
if((v.getX()-v1.getX())/(v2.getX()-v1.getX()) - (v.getY()-v1.getY())/(v2.getY()-v1.getY()) == 0)
|
||||
if(fabs((v.getX()-v1.getX())/(v2.getX()-v1.getX()) - (v.getY()-v1.getY())/(v2.getY()-v1.getY())) < 1E-6)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
int Line::intersects(const Line &l, Vertex *v) const {
|
||||
double xa1 = v1.getX(), ya1 = v1.getY();
|
||||
double xa2 = v2.getX(), ya2 = v2.getY();
|
||||
double xb1 = l.v1.getX(), yb1 = l.v1.getY();
|
||||
double xb2 = l.v2.getX(), yb2 = l.v2.getY();
|
||||
double temp;
|
||||
float xa1 = v1.getX(), ya1 = v1.getY();
|
||||
float xa2 = v2.getX(), ya2 = v2.getY();
|
||||
float xb1 = l.v1.getX(), yb1 = l.v1.getY();
|
||||
float xb2 = l.v2.getX(), yb2 = l.v2.getY();
|
||||
float temp;
|
||||
int switched = 0;
|
||||
Vertex v2;
|
||||
|
||||
|
||||
if(!v) v = &v2;
|
||||
|
||||
if(xa1 == xa2 && ya1 == ya2) return INTERSECTION_ERROR;
|
||||
if(xb1 == xb2 && yb1 == yb2) return INTERSECTION_ERROR;
|
||||
if(fabs(xa1 - xa2) < 1E-6 && fabs(ya1 - ya2) < 1E-6) return INTERSECTION_ERROR;
|
||||
if(fabs(xb1 - xb2) < 1E-6 && fabs(yb1 - yb2) < 1E-6) return INTERSECTION_ERROR;
|
||||
|
||||
if(xa1 == xa2 || xb1 == xb2) {
|
||||
if(fabs(xa1 - xa2) < 1E-6 || fabs(xb1 - xb2) < 1E-6) {
|
||||
temp = xa1; xa1 = ya1; ya1 = temp;
|
||||
temp = xa2; xa2 = ya2; ya2 = temp;
|
||||
temp = xb1; xb1 = yb1; yb1 = temp;
|
||||
|
@ -57,24 +57,24 @@ int Line::intersects(const Line &l, Vertex *v) const {
|
|||
switched = 1;
|
||||
}
|
||||
|
||||
if(xa1 == xa2 && xb1 == xb2)
|
||||
return (xa1 == xb1) ? INTERSECTION_IDENTICAL : INTERSECTION_NONE;
|
||||
if(fabs(xa1 - xa2) < 1E-6 && fabs(xb1 - xb2) < 1E-6)
|
||||
return (fabs(xa1 - xb1) < 1E-6) ? INTERSECTION_IDENTICAL : INTERSECTION_NONE;
|
||||
|
||||
if(xa1 == xa2) {
|
||||
if(fabs(xa1 - xa2) < 1E-6) {
|
||||
v->setX(xa1);
|
||||
v->setY(yb1);
|
||||
}
|
||||
else if(xb1 == xb2) {
|
||||
else if(fabs(xb1 - xb2) < 1E-6) {
|
||||
v->setX(xb1);
|
||||
v->setY(ya1);
|
||||
}
|
||||
else {
|
||||
double ma = (ya2-ya1)/(xa2-xa1);
|
||||
double mb = (yb2-yb1)/(xb2-xb1);
|
||||
double ba = ya1 - ma*xa1;
|
||||
double bb = yb1 - mb*xb1;
|
||||
float ma = (ya2-ya1)/(xa2-xa1);
|
||||
float mb = (yb2-yb1)/(xb2-xb1);
|
||||
float ba = ya1 - ma*xa1;
|
||||
float bb = yb1 - mb*xb1;
|
||||
|
||||
if(ma == mb) return (ba == bb) ? INTERSECTION_IDENTICAL : INTERSECTION_NONE;
|
||||
if(fabs(ma - mb) < 1E-6) return (fabs(ba - bb) < 1E-6) ? INTERSECTION_IDENTICAL : INTERSECTION_NONE;
|
||||
|
||||
v->setX((bb-ba)/(ma-mb));
|
||||
v->setY(ma*v->getX() + ba);
|
||||
|
|
15
Line.h
15
Line.h
|
@ -19,13 +19,10 @@ class Line {
|
|||
Vertex v1, v2;
|
||||
public:
|
||||
Line() {}
|
||||
Line(const Vertex& v1, const Vertex& v2) {
|
||||
this->v1 = v1; this->v2 = v2;
|
||||
}
|
||||
Line(double x1, double y1, double x2, double y2) {
|
||||
v1.setLocation(x1, y1);
|
||||
v2.setLocation(x2, y2);
|
||||
}
|
||||
Line(const Vertex& vertex1, const Vertex& vertex2) :
|
||||
v1(vertex1), v2(vertex2) {}
|
||||
Line(float x1, float y1, float x2, float y2) :
|
||||
v1(x1, y1), v2(x2, y2) {}
|
||||
|
||||
Vertex &getVertex1() {return v1;}
|
||||
const Vertex &getVertex1() const {return v1;}
|
||||
|
@ -35,8 +32,8 @@ class Line {
|
|||
const Vertex &getVertex2() const {return v2;}
|
||||
void setVertex2(const Vertex &v) {v2 = v;}
|
||||
|
||||
double lengthSq() const {return v1.distanceSq(v2);}
|
||||
double length() const {return sqrt(lengthSq());}
|
||||
float lengthSq() const {return v1.distanceSq(v2);}
|
||||
float length() const {return sqrtf(lengthSq());}
|
||||
|
||||
bool contains(const Vertex &v) const;
|
||||
|
||||
|
|
91
Polygon.cpp
91
Polygon.cpp
|
@ -1,10 +1,11 @@
|
|||
#include "Polygon.h"
|
||||
#include "Line.h"
|
||||
#include <list>
|
||||
#include <math.h>
|
||||
|
||||
|
||||
double Polygon::signedArea() const {
|
||||
double d = 0.0;
|
||||
float Polygon::signedArea() const {
|
||||
float d = 0.0;
|
||||
|
||||
for(const_iterator it = begin(); it != end(); it++) {
|
||||
const_iterator it2 = it+1;
|
||||
|
@ -17,17 +18,17 @@ double Polygon::signedArea() const {
|
|||
}
|
||||
|
||||
Polygon::Direction Polygon::getDirection() const {
|
||||
double area = signedArea();
|
||||
float area = signedArea();
|
||||
|
||||
return (area > 0) ? Triangle::CW : (area < 0) ? Triangle::CCW : Triangle::Unknown;
|
||||
}
|
||||
|
||||
double Polygon::area() const {
|
||||
float Polygon::area() const {
|
||||
return fabs(signedArea());
|
||||
}
|
||||
|
||||
double Polygon::perimeter() const {
|
||||
double d = 0.0;
|
||||
float Polygon::perimeter() const {
|
||||
float d = 0.0;
|
||||
|
||||
for(const_iterator it = begin(); it != end(); it++) {
|
||||
const_iterator it2 = it+1;
|
||||
|
@ -173,8 +174,9 @@ bool Polygon::isSimple() const {
|
|||
return !intersections();
|
||||
}
|
||||
|
||||
bool Polygon::simplify(Polygon &polygon) const {
|
||||
bool Polygon::simplify(std::list<Polygon> &polygons) const {
|
||||
std::vector<Intersection> ins;
|
||||
std::vector<Intersection*> inlist;
|
||||
|
||||
if(!intersections(&ins)) return false;
|
||||
|
||||
|
@ -194,6 +196,8 @@ bool Polygon::simplify(Polygon &polygon) const {
|
|||
const Vertex *v2 = &at(i2);
|
||||
bool intersected;
|
||||
|
||||
polygons.push_back(Polygon());
|
||||
|
||||
do {
|
||||
intersected = false;
|
||||
|
||||
|
@ -207,51 +211,86 @@ bool Polygon::simplify(Polygon &polygon) const {
|
|||
const Vertex *v1 = v2;
|
||||
v2 = &at(i2);
|
||||
|
||||
float dl = v2->distanceSq(*v1);
|
||||
|
||||
Intersection *intr = NULL;
|
||||
Vertex *v = NULL;
|
||||
float dv = 0;
|
||||
int v3, v4;
|
||||
|
||||
for(std::vector<Intersection>::iterator in = ins.begin(); in != ins.end(); ++in) {
|
||||
if(v2->distanceSq(in->v) >= v2->distanceSq(*v1) || v1 == &in->v)
|
||||
float di = v2->distanceSq(in->v);
|
||||
|
||||
if(di >= dl || v1 == &in->v)
|
||||
continue;
|
||||
|
||||
if(v) {
|
||||
if(v1->distanceSq(in->v) >= v1->distanceSq(*v))
|
||||
continue;
|
||||
}
|
||||
if(v && di < dv)
|
||||
continue;
|
||||
|
||||
if((i == in->va1 && i2 == in->va2) || (i == in->va2 && i2 == in->va1)) {
|
||||
intr = &*in;
|
||||
|
||||
v = &in->v;
|
||||
dv = di;
|
||||
v3 = in->vb1;
|
||||
v4 = in->vb2;
|
||||
}
|
||||
else if((i == in->vb1 && i2 == in->vb2) || (i == in->vb2 && i2 == in->vb1)) {
|
||||
intr = &*in;
|
||||
|
||||
v = &in->v;
|
||||
dv = di;
|
||||
v3 = in->va1;
|
||||
v4 = in->va2;
|
||||
}
|
||||
}
|
||||
|
||||
if(v) {
|
||||
if(intr) {
|
||||
if(isConcave(Triangle::CW, *v1, *v2, at(v4))) {
|
||||
if(!Line(*v1, *v2).contains(at(v3))) {
|
||||
i2 = v3;
|
||||
dir = Triangle::CW;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(!Line(*v1, *v2).contains(at(v4))) {
|
||||
i2 = v4;
|
||||
dir = Triangle::CCW;
|
||||
}
|
||||
}
|
||||
|
||||
v2 = v;
|
||||
intersected = true;
|
||||
|
||||
if(isConcave(Triangle::CW, *v1, *v2, at(v4))) {
|
||||
i2 = v3;
|
||||
dir = Triangle::CW;
|
||||
std::vector<Intersection*>::reverse_iterator it = inlist.rbegin();
|
||||
for(; it != inlist.rend(); it++) {
|
||||
if(*it == intr) break;
|
||||
}
|
||||
|
||||
if(it != inlist.rend()) {
|
||||
inlist.erase(it.base()-1, inlist.end());
|
||||
|
||||
polygons.push_back(Polygon());
|
||||
|
||||
while(!polygons.front().empty()) {
|
||||
polygons.back().push_back(polygons.front().back());
|
||||
polygons.front().pop_back();
|
||||
|
||||
if(v->distanceSq(polygons.back().back()) < 1E-6)
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
i2 = v4;
|
||||
dir = Triangle::CCW;
|
||||
inlist.push_back(intr);
|
||||
}
|
||||
}
|
||||
|
||||
polygon.push_back(*v2);
|
||||
polygons.front().push_back(*v2);
|
||||
} while(i2 != start || intersected);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// FIXME: has still some problems...
|
||||
void Polygon::doTriangulate(std::vector<Triangle> &triangles) const {
|
||||
size_t s = size();
|
||||
|
||||
|
@ -277,12 +316,14 @@ void Polygon::doTriangulate(std::vector<Triangle> &triangles) const {
|
|||
const Vertex *v3 = &at(p[(i+3)%s2]);
|
||||
const Vertex *v4 = &at(p[(i+4)%s2]);
|
||||
|
||||
|
||||
if(isConcave(dir, *v1, *v2, *v3))
|
||||
continue;
|
||||
|
||||
Triangle t(*v1, *v2, *v3);
|
||||
|
||||
std::list<size_t>::iterator it = concave.begin();
|
||||
|
||||
for(; it != concave.end(); it++) {
|
||||
if(*it != p[(i+1)%s2] && *it != p[(i+3)%s2] && t.contains(at(*it)))
|
||||
break;
|
||||
|
@ -301,15 +342,19 @@ void Polygon::doTriangulate(std::vector<Triangle> &triangles) const {
|
|||
}
|
||||
|
||||
p.erase(p.begin()+(i+2)%s2);
|
||||
i = 0;
|
||||
i = -1;
|
||||
}
|
||||
|
||||
|
||||
triangles.push_back(Triangle(at(p[0]), at(p[1]), at(p[2])));
|
||||
}
|
||||
|
||||
void Polygon::triangulate(std::vector<Triangle> &triangles) const {
|
||||
Polygon p;
|
||||
std::list<Polygon> polygons;
|
||||
|
||||
if(simplify(p)) p.doTriangulate(triangles);
|
||||
if(simplify(polygons)) {
|
||||
for(std::list<Polygon>::iterator p = polygons.begin(); p != polygons.end(); p++)
|
||||
p->doTriangulate(triangles);
|
||||
}
|
||||
else doTriangulate(triangles);
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include "Line.h"
|
||||
#include "Triangle.h"
|
||||
#include <vector>
|
||||
#include <list>
|
||||
|
||||
class Polygon : public std::vector<Vertex> {
|
||||
private:
|
||||
|
@ -17,7 +18,7 @@ class Polygon : public std::vector<Vertex> {
|
|||
|
||||
int quadrant(const Vertex &v) const;
|
||||
|
||||
double signedArea() const;
|
||||
float signedArea() const;
|
||||
|
||||
Triangle::Direction getDirection() const;
|
||||
bool isConcave(const Triangle::Direction &dir, const Vertex &v1, const Vertex &v2, const Vertex &v3) const;
|
||||
|
@ -26,14 +27,14 @@ class Polygon : public std::vector<Vertex> {
|
|||
|
||||
void doTriangulate(std::vector<Triangle> &triangles) const;
|
||||
public:
|
||||
double area() const;
|
||||
double perimeter() const;
|
||||
float area() const;
|
||||
float perimeter() const;
|
||||
|
||||
bool contains(const Vertex &v) const;
|
||||
bool intersects(const Line &l) const;
|
||||
|
||||
bool isSimple() const;
|
||||
bool simplify(Polygon &polygon) const;
|
||||
bool simplify(std::list<Polygon> &polygons) const;
|
||||
|
||||
void triangulate(std::vector<Triangle> &triangles) const;
|
||||
};
|
||||
|
|
12
Rectangle.h
12
Rectangle.h
|
@ -19,7 +19,7 @@ class Rectangle {
|
|||
public:
|
||||
Rectangle() {}
|
||||
Rectangle(const Vertex& vertex1, const Vertex& vertex2) : v1(vertex1), v2(vertex2) {}
|
||||
Rectangle(double x, double y, double width, double height)
|
||||
Rectangle(float x, float y, float width, float height)
|
||||
: v1(x, y), v2(x+width, y+height) {}
|
||||
|
||||
Vertex &getVertex1() {return v1;}
|
||||
|
@ -30,13 +30,13 @@ class Rectangle {
|
|||
const Vertex &getVertex2() const {return v2;}
|
||||
void setVertex2(const Vertex &v) {v2 = v;}
|
||||
|
||||
double getWidth() const {return v2.getX()-v1.getX();}
|
||||
void setWidth(double width) {v2.setX(v1.getX()+width);}
|
||||
float getWidth() const {return v2.getX()-v1.getX();}
|
||||
void setWidth(float width) {v2.setX(v1.getX()+width);}
|
||||
|
||||
double getHeight() const {return v2.getY()-v1.getY();}
|
||||
void setHeight(double height) {v2.setY(v1.getY()+height);}
|
||||
float getHeight() const {return v2.getY()-v1.getY();}
|
||||
void setHeight(float height) {v2.setY(v1.getY()+height);}
|
||||
|
||||
double area() const {return getWidth()*getHeight();}
|
||||
float area() const {return getWidth()*getHeight();}
|
||||
|
||||
bool contains(const Vertex &v) const;
|
||||
|
||||
|
|
20
Room.h
20
Room.h
|
@ -6,16 +6,16 @@
|
|||
|
||||
|
||||
class Room : public Polygon {
|
||||
private:
|
||||
std::string name;
|
||||
public:
|
||||
Room() {}
|
||||
Room(std::string name) {this->name = name;}
|
||||
|
||||
|
||||
std::string &getName() {return name;}
|
||||
const std::string &getName() const {return name;}
|
||||
void setName(const std::string &name) {this->name = name;}
|
||||
private:
|
||||
std::string name;
|
||||
public:
|
||||
Room() {}
|
||||
Room(std::string name) {this->name = name;}
|
||||
|
||||
|
||||
std::string &getName() {return name;}
|
||||
const std::string &getName() const {return name;}
|
||||
void setName(const std::string &name) {this->name = name;}
|
||||
};
|
||||
|
||||
#endif /*ROOM_H_*/
|
||||
|
|
56
Triangle.cpp
56
Triangle.cpp
|
@ -1,36 +1,70 @@
|
|||
#include "Triangle.h"
|
||||
#include "Line.h"
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
Triangle::Direction Triangle::getDirection() const {
|
||||
double c = (va.getX()-vb.getX())*(vc.getY()-vb.getY()) - (vc.getX()-vb.getX())*(va.getY()-vb.getY());
|
||||
float c = (va.getX()-vb.getX())*(vc.getY()-vb.getY()) - (vc.getX()-vb.getX())*(va.getY()-vb.getY());
|
||||
|
||||
return (c < 0) ? CW : (c > 0) ? CCW : Unknown;
|
||||
}
|
||||
|
||||
double Triangle::area() const {
|
||||
double a = vb.distanceSq(vc);
|
||||
double b = vc.distanceSq(va);
|
||||
double c = va.distanceSq(vb);
|
||||
float Triangle::area() const {
|
||||
float a = vb.distanceSq(vc);
|
||||
float b = vc.distanceSq(va);
|
||||
float c = va.distanceSq(vb);
|
||||
|
||||
return sqrt((a+b+c)*a+b+c - 2*(a*a+b*b+c*c))/4;
|
||||
}
|
||||
|
||||
double Triangle::perimeter() const {
|
||||
float Triangle::perimeter() const {
|
||||
return va.distance(vb) + vb.distance(vc) + vc.distance(va);
|
||||
}
|
||||
|
||||
bool Triangle::contains(const Vertex &v) const {
|
||||
double a = (v.getX()-vb.getX())*(vc.getY()-vb.getY()) - (vc.getX()-vb.getX())*(v.getY()-vb.getY());
|
||||
double b = (v.getX()-vc.getX())*(va.getY()-vc.getY()) - (va.getX()-vc.getX())*(v.getY()-vc.getY());
|
||||
double c = (v.getX()-va.getX())*(vb.getY()-va.getY()) - (vb.getX()-va.getX())*(v.getY()-va.getY());
|
||||
float a = (v.getX()-vb.getX())*(vc.getY()-vb.getY()) - (vc.getX()-vb.getX())*(v.getY()-vb.getY());
|
||||
float b = (v.getX()-vc.getX())*(va.getY()-vc.getY()) - (va.getX()-vc.getX())*(v.getY()-vc.getY());
|
||||
float c = (v.getX()-va.getX())*(vb.getY()-va.getY()) - (vb.getX()-va.getX())*(v.getY()-va.getY());
|
||||
|
||||
switch(getDirection()) {
|
||||
case CW:
|
||||
return ((a < 0) && (b < 0) && (c < 0));
|
||||
return ((a < 1E-6) && (b < 1E-6) && (c < 1E-6));
|
||||
case CCW:
|
||||
return ((a > 0) && (b > 0) && (c > 0));
|
||||
return ((a > -1E-6) && (b > -1E-6) && (c > -1E-6));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Triangle::onEdge(const Vertex &v) const {
|
||||
return (Line(va, vb).contains(v) || Line(vb, vc).contains(v) || Line(vc, va).contains(v));
|
||||
}
|
||||
|
||||
int Triangle::intersectionCount(const Line &l) const {
|
||||
int ret = 0;
|
||||
Vertex v1, v2, v3;
|
||||
|
||||
printf("Testing line: (%f %f) (%f %f)\n", l.getVertex1().getX(), l.getVertex1().getY(), l.getVertex2().getX(), l.getVertex2().getY());
|
||||
if(Line(va, vb).intersects(l, &v1) == INTERSECTION_SEGMENT_SEGMENT) {
|
||||
printf("Intersection: (%f %f)\n", v1.getX(), v1.getY());
|
||||
ret++;
|
||||
}
|
||||
|
||||
if(Line(vb, vc).intersects(l, &v2) == INTERSECTION_SEGMENT_SEGMENT) {
|
||||
printf("Intersection: (%f %f)\n", v2.getX(), v2.getY());
|
||||
if(v2.distanceSq(v1) >= 1E-6)
|
||||
ret++;
|
||||
}
|
||||
|
||||
if(Line(vc, va).intersects(l, &v3) == INTERSECTION_SEGMENT_SEGMENT) {
|
||||
printf("Intersection: (%f %f)\n", v3.getX(), v3.getY());
|
||||
if(v3.distanceSq(v1) >= 1E-6 && v3.distanceSq(v2) >= 1E-6)
|
||||
ret++;
|
||||
}
|
||||
|
||||
printf("Found %i intersections.\n", ret);
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
|
||||
#include "Vertex.h"
|
||||
#include "Line.h"
|
||||
|
||||
class Triangle {
|
||||
private:
|
||||
|
@ -30,10 +31,12 @@ class Triangle {
|
|||
|
||||
Direction getDirection() const;
|
||||
|
||||
double area() const;
|
||||
double perimeter() const;
|
||||
float area() const;
|
||||
float perimeter() const;
|
||||
|
||||
bool contains(const Vertex &v) const;
|
||||
bool onEdge(const Vertex &v) const;
|
||||
int intersectionCount(const Line &l) const;
|
||||
};
|
||||
|
||||
#endif /*TRIANGLE_H_*/
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
#include "Vertex.h"
|
||||
#include <math.h>
|
||||
|
||||
double Vertex::distanceSq(const Vertex &v) const {
|
||||
float Vertex::distanceSq(const Vertex &v) const {
|
||||
return (x - v.x)*(x - v.x) + (y - v.y)*(y - v.y);
|
||||
}
|
||||
|
||||
double Vertex::distance(const Vertex &v) const {
|
||||
return sqrt(distanceSq(v));
|
||||
float Vertex::distance(const Vertex &v) const {
|
||||
return sqrtf(distanceSq(v));
|
||||
}
|
||||
|
||||
|
||||
|
|
18
Vertex.h
18
Vertex.h
|
@ -3,23 +3,23 @@
|
|||
|
||||
class Vertex {
|
||||
private:
|
||||
double x, y;
|
||||
float x, y;
|
||||
public:
|
||||
Vertex() {x = y = 0.0;}
|
||||
Vertex(const Vertex &v) {x = v.x; y = v.y;}
|
||||
Vertex(double x, double y) {this->x = x; this->y = y;}
|
||||
Vertex(float x, float y) {this->x = x; this->y = y;}
|
||||
|
||||
double getX() const {return x;}
|
||||
void setX(double x) {this->x = x;}
|
||||
float getX() const {return x;}
|
||||
void setX(float x) {this->x = x;}
|
||||
|
||||
double getY() const {return y;}
|
||||
void setY(double y) {this->y = y;}
|
||||
float getY() const {return y;}
|
||||
void setY(float y) {this->y = y;}
|
||||
|
||||
void setLocation(const Vertex &v) {x = v.x; y = v.y;}
|
||||
void setLocation(double x, double y) {this->x = x; this->y = y;}
|
||||
void setLocation(float x, float y) {this->x = x; this->y = y;}
|
||||
|
||||
double distanceSq(const Vertex &v) const;
|
||||
double distance(const Vertex &v) const;
|
||||
float distanceSq(const Vertex &v) const;
|
||||
float distance(const Vertex &v) const;
|
||||
|
||||
Vertex operator+(const Vertex &v) const;
|
||||
Vertex operator-(const Vertex &v) const;
|
||||
|
|
100
draw.cpp
100
draw.cpp
|
@ -7,31 +7,31 @@
|
|||
#include <GL/gl.h>
|
||||
|
||||
|
||||
static double scale = 100.0;
|
||||
static double xTranslate = 0.0, yTranslate = 0.0;
|
||||
static float scale = 100.0;
|
||||
static float xTranslate = 0.0, yTranslate = 0.0;
|
||||
|
||||
|
||||
static void drawGrid(const Rectangle &rect) {
|
||||
double depth = log10(scale)-0.75;
|
||||
double depth2 = floor(depth);
|
||||
double step = pow(0.1, depth2);
|
||||
double d;
|
||||
float depth = log10f(scale)-0.75f;
|
||||
float depth2 = floorf(depth);
|
||||
float step = powf(0.1f, depth2);
|
||||
float f;
|
||||
int i;
|
||||
//gchar *string;
|
||||
double x1 = rect.getVertex1().getX(), y1 = rect.getVertex1().getY();
|
||||
double x2 = rect.getVertex2().getX(), y2 = rect.getVertex2().getY();
|
||||
float x1 = rect.getVertex1().getX(), y1 = rect.getVertex1().getY();
|
||||
float x2 = rect.getVertex2().getX(), y2 = rect.getVertex2().getY();
|
||||
|
||||
|
||||
glBegin(GL_LINES);
|
||||
//cairo_set_font_size(cr, 10.0/scale);
|
||||
|
||||
for(i = 0; 0.4*(depth-depth2+i-1) < 0.5; i++) {
|
||||
d = MIN(0.4*(depth-depth2+i), 0.5);
|
||||
glColor3d(d, d, d);
|
||||
for(i = 0; 0.4f*(depth-depth2+i-1) < 0.5f; i++) {
|
||||
f = fminf(0.4f*(depth-depth2+i), 0.5f);
|
||||
glColor3f(f, f, f);
|
||||
|
||||
for(d = x1 - fmod(x1, step) - step; d <= x2; d+=step) {
|
||||
glVertex2d(d, y1);
|
||||
glVertex2d(d, y2);
|
||||
for(f = x1 - fmodf(x1, step) - step; f <= x2; f+=step) {
|
||||
glVertex2f(f, y1);
|
||||
glVertex2f(f, y2);
|
||||
|
||||
/*if(step > 0.005) {
|
||||
if(step > 0.5)
|
||||
|
@ -46,9 +46,9 @@ static void drawGrid(const Rectangle &rect) {
|
|||
}*/
|
||||
}
|
||||
|
||||
for(d = y1 - fmod(y1, step) - step; d <= y2; d+=step) {
|
||||
glVertex2d(x1, d);
|
||||
glVertex2d(x2, d);
|
||||
for(f = y1 - fmodf(y1, step) - step; f <= y2; f+=step) {
|
||||
glVertex2f(x1, f);
|
||||
glVertex2f(x2, f);
|
||||
|
||||
/*if(step > 0.005) {
|
||||
if(step > 0.5)
|
||||
|
@ -77,9 +77,9 @@ static void fillPolygon(const Polygon &polygon) {
|
|||
glBegin(GL_TRIANGLES);
|
||||
|
||||
for(std::vector<Triangle>::iterator t = triangles.begin(); t != triangles.end(); t++) {
|
||||
glVertex2d(t->getVertexA().getX(), t->getVertexA().getY());
|
||||
glVertex2d(t->getVertexB().getX(), t->getVertexB().getY());
|
||||
glVertex2d(t->getVertexC().getX(), t->getVertexC().getY());
|
||||
glVertex2f(t->getVertexA().getX(), t->getVertexA().getY());
|
||||
glVertex2f(t->getVertexB().getX(), t->getVertexB().getY());
|
||||
glVertex2f(t->getVertexC().getX(), t->getVertexC().getY());
|
||||
}
|
||||
|
||||
glEnd();
|
||||
|
@ -120,10 +120,10 @@ gboolean drawTopView(GtkWidget *widget, GdkEventExpose *event, gpointer data) {
|
|||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
|
||||
glLineWidth(1.0);
|
||||
glLineWidth(1.0f);
|
||||
|
||||
glTranslated(getImageWidth()/2-xTranslate, getImageHeight()/2-yTranslate, 0);
|
||||
glScaled(scale, scale, 1);
|
||||
glTranslatef(getImageWidth()/2-xTranslate, getImageHeight()/2-yTranslate, 0);
|
||||
glScalef(scale, scale, 1);
|
||||
|
||||
drawGrid(rect);
|
||||
|
||||
|
@ -131,23 +131,23 @@ gboolean drawTopView(GtkWidget *widget, GdkEventExpose *event, gpointer data) {
|
|||
if(&*room == getActiveRoom() && getEditMode() == EDIT_MODE_ADD) continue;
|
||||
|
||||
if(&*room == getActiveRoom())
|
||||
glColor4d(0.0, 0.7, 1.0, 0.2);
|
||||
glColor4f(0.0f, 0.7f, 1.0f, 0.2f);
|
||||
else
|
||||
glColor4d(0.0, 0.7, 1.0, 0.3);
|
||||
glColor4f(0.0f, 0.7f, 1.0f, 0.3f);
|
||||
|
||||
fillPolygon(*room);
|
||||
|
||||
if(&*room == getActiveRoom()) {
|
||||
glColor4d(1.0, 1.0, 1.0, 0.9);
|
||||
glLineWidth(2.0);
|
||||
glColor4f(1.0f, 1.0f, 1.0f, 0.9f);
|
||||
glLineWidth(2.0f);
|
||||
}
|
||||
else if(&*room == getHoveredRoom() && getEditMode() != EDIT_MODE_ADD) {
|
||||
glColor4d(0.0, 0.7, 1.0, 0.7);
|
||||
glLineWidth(2.0);
|
||||
glColor4f(0.0f, 0.7f, 1.0f, 0.7f);
|
||||
glLineWidth(2.0f);
|
||||
}
|
||||
else {
|
||||
glColor4d(0.0, 0.7, 1.0, 0.7);
|
||||
glLineWidth(1.0);
|
||||
glColor4f(0.0f, 0.7f, 1.0f, 0.7f);
|
||||
glLineWidth(1.0f);
|
||||
}
|
||||
|
||||
drawPolygon(*room, true);
|
||||
|
@ -155,19 +155,19 @@ gboolean drawTopView(GtkWidget *widget, GdkEventExpose *event, gpointer data) {
|
|||
|
||||
if(getEditMode() == EDIT_MODE_ADD) {
|
||||
if(isPolygonOk(getActiveRoom()))
|
||||
glColor4d(0.0, 0.7, 1.0, 0.2);
|
||||
glColor4f(0.0f, 0.7f, 1.0f, 0.2f);
|
||||
else
|
||||
glColor4d(1.0, 0.3, 0.3, 0.2);
|
||||
glColor4f(1.0f, 0.3f, 0.3f, 0.2f);
|
||||
|
||||
fillPolygon(*getActiveRoom());
|
||||
|
||||
glLineWidth(2.0);
|
||||
glColor4d(0.0, 0.7, 1.0, 0.7);
|
||||
glLineWidth(2.0f);
|
||||
glColor4f(0.0f, 0.7f, 1.0f, 0.7f);
|
||||
drawPolygon(*getActiveRoom(), false);
|
||||
|
||||
if(!getActiveRoom()->empty() && getHoveredVertex()) {
|
||||
if(!isVertexOk(getHoveredVertex()))
|
||||
glColor4d(1.0, 0.3, 0.3, 0.7);
|
||||
glColor4f(1.0f, 0.3f, 0.3f, 0.7f);
|
||||
|
||||
glBegin(GL_LINES);
|
||||
|
||||
|
@ -188,11 +188,11 @@ gboolean drawTopView(GtkWidget *widget, GdkEventExpose *event, gpointer data) {
|
|||
}
|
||||
|
||||
|
||||
double getScale() {
|
||||
float getScale() {
|
||||
return scale;
|
||||
}
|
||||
|
||||
void setScale(double s) {
|
||||
void setScale(float s) {
|
||||
scale = MAX(0.005, MIN(s, 10000));
|
||||
}
|
||||
|
||||
|
@ -206,15 +206,15 @@ void viewToImage(Vertex *v) {
|
|||
v->setY((v->getY()-getImageHeight()/2+yTranslate)/scale);
|
||||
}
|
||||
|
||||
double getImageWidth() {
|
||||
double min = 0.0, max = 0.0;
|
||||
float getImageWidth() {
|
||||
float min = 0.0, max = 0.0;
|
||||
|
||||
|
||||
if(getLevel()) {
|
||||
for(Level::iterator room = getLevel()->begin(); room != getLevel()->end(); room++) {
|
||||
for(Room::iterator v = room->begin(); v != room->end(); v++) {
|
||||
min = MIN(min, v->getX());
|
||||
max = MAX(max, v->getX());
|
||||
min = fminf(min, v->getX());
|
||||
max = fmaxf(max, v->getX());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -222,15 +222,15 @@ double getImageWidth() {
|
|||
return (max-min+10)*scale;
|
||||
}
|
||||
|
||||
double getImageHeight() {
|
||||
double min = 0.0, max = 0.0;
|
||||
float getImageHeight() {
|
||||
float min = 0.0, max = 0.0;
|
||||
|
||||
|
||||
if(getLevel()) {
|
||||
for(Level::iterator room = getLevel()->begin(); room != getLevel()->end(); room++) {
|
||||
for(Room::iterator v = room->begin(); v != room->end(); v++) {
|
||||
min = MIN(min, v->getY());
|
||||
max = MAX(max, v->getY());
|
||||
min = fminf(min, v->getY());
|
||||
max = fmaxf(max, v->getY());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -238,18 +238,18 @@ double getImageHeight() {
|
|||
return (max-min+10)*scale;
|
||||
}
|
||||
|
||||
double getXTranslate() {
|
||||
float getXTranslate() {
|
||||
return xTranslate;
|
||||
}
|
||||
|
||||
void setXTranslate(double x) {
|
||||
void setXTranslate(float x) {
|
||||
xTranslate = x;
|
||||
}
|
||||
|
||||
double getYTranslate() {
|
||||
float getYTranslate() {
|
||||
return yTranslate;
|
||||
}
|
||||
|
||||
void setYTranslate(double y) {
|
||||
void setYTranslate(float y) {
|
||||
yTranslate = y;
|
||||
}
|
||||
|
|
16
draw.h
16
draw.h
|
@ -7,18 +7,18 @@
|
|||
|
||||
gboolean drawTopView(GtkWidget *widget, GdkEventExpose *event, gpointer data);
|
||||
|
||||
double getScale();
|
||||
void setScale(double s);
|
||||
float getScale();
|
||||
void setScale(float s);
|
||||
|
||||
void imageToView(Vertex *v);
|
||||
void viewToImage(Vertex *v);
|
||||
|
||||
double getImageWidth();
|
||||
double getImageHeight();
|
||||
float getImageWidth();
|
||||
float getImageHeight();
|
||||
|
||||
double getXTranslate();
|
||||
void setXTranslate(double x);
|
||||
double getYTranslate();
|
||||
void setYTranslate(double y);
|
||||
float getXTranslate();
|
||||
void setXTranslate(float x);
|
||||
float getYTranslate();
|
||||
void setYTranslate(float y);
|
||||
|
||||
#endif /*DRAW_H_*/
|
||||
|
|
4
ui.cpp
4
ui.cpp
|
@ -30,9 +30,9 @@ static void handleAction(GtkAction *action, gpointer user_data) {
|
|||
const gchar* name = gtk_action_get_name(action);
|
||||
|
||||
if(!strcmp(name, "zoomIn"))
|
||||
zoomInCentered(1.2);
|
||||
zoomInCentered(1.2f);
|
||||
else if(!strcmp(name, "zoomOut"))
|
||||
zoomOutCentered(1.2);
|
||||
zoomOutCentered(1.2f);
|
||||
}
|
||||
|
||||
static GtkActionGroup *createActions() {
|
||||
|
|
24
window.cpp
24
window.cpp
|
@ -27,7 +27,7 @@ static void refreshScrolling() {
|
|||
gtk_widget_queue_draw(drawingArea);
|
||||
}
|
||||
|
||||
static void updateScrollbars(double x, double y) {
|
||||
static void updateScrollbars(float x, float y) {
|
||||
const gdouble imageWidth = getImageWidth(), imageHeight = getImageHeight();
|
||||
const gdouble width = drawingArea->allocation.width, height = drawingArea->allocation.height;
|
||||
gdouble upper, pageSize, value;
|
||||
|
@ -83,8 +83,8 @@ static void realize(GtkWidget *widget, gpointer data) {
|
|||
glLoadIdentity();
|
||||
|
||||
if(widget->allocation.width != 0 && widget->allocation.height != 0) {
|
||||
glTranslated(-1, 1, 0);
|
||||
glScaled(2.0/widget->allocation.width, -2.0/widget->allocation.height, 1);
|
||||
glTranslatef(-1, 1, 0);
|
||||
glScalef(2.0f/widget->allocation.width, -2.0f/widget->allocation.height, 1);
|
||||
}
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
|
@ -106,8 +106,8 @@ static gboolean configureEvent(GtkWidget *widget, GdkEventConfigure *event, gpoi
|
|||
glLoadIdentity();
|
||||
|
||||
if(widget->allocation.width != 0 && widget->allocation.height != 0) {
|
||||
glTranslated(-1, 1, 0);
|
||||
glScaled(2.0/widget->allocation.width, -2.0/widget->allocation.height, 1);
|
||||
glTranslatef(-1, 1, 0);
|
||||
glScalef(2.0f/widget->allocation.width, -2.0f/widget->allocation.height, 1);
|
||||
}
|
||||
|
||||
gdk_gl_drawable_gl_end(drawable);
|
||||
|
@ -119,14 +119,14 @@ static gboolean configureEvent(GtkWidget *widget, GdkEventConfigure *event, gpoi
|
|||
|
||||
|
||||
static gboolean scrollEvent(GtkWidget *widget, GdkEventScroll *event, gpointer user_data) {
|
||||
const gdouble x = event->x/widget->allocation.width, y = event->y/widget->allocation.height;
|
||||
const float x = event->x/widget->allocation.width, y = event->y/widget->allocation.height;
|
||||
|
||||
switch(event->direction) {
|
||||
case GDK_SCROLL_UP:
|
||||
zoomIn(1.1, x, y);
|
||||
zoomIn(1.1f, x, y);
|
||||
break;
|
||||
case GDK_SCROLL_DOWN:
|
||||
zoomOut(1.1, x, y);
|
||||
zoomOut(1.1f, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -389,20 +389,20 @@ void updateSidebar() {
|
|||
}
|
||||
}
|
||||
|
||||
void zoomIn(double factor, double x, double y) {
|
||||
void zoomIn(float factor, float x, float y) {
|
||||
setScale(getScale()*factor);
|
||||
updateScrollbars(x, y);
|
||||
}
|
||||
|
||||
void zoomOut(double factor, double x, double y) {
|
||||
void zoomOut(float factor, float x, float y) {
|
||||
setScale(getScale()/factor);
|
||||
updateScrollbars(x, y);
|
||||
}
|
||||
|
||||
void zoomInCentered(double factor) {
|
||||
void zoomInCentered(float factor) {
|
||||
zoomIn(factor, 0.5, 0.5);
|
||||
}
|
||||
|
||||
void zoomOutCentered(double factor) {
|
||||
void zoomOutCentered(float factor) {
|
||||
zoomOut(factor, 0.5, 0.5);
|
||||
}
|
||||
|
|
8
window.h
8
window.h
|
@ -9,9 +9,9 @@ GtkWidget* createMainWindow(GdkGLConfig *glconfig);
|
|||
|
||||
void updateSidebar();
|
||||
|
||||
void zoomIn(double factor, double x, double y);
|
||||
void zoomOut(double factor, double x, double y);
|
||||
void zoomInCentered(double factor);
|
||||
void zoomOutCentered(double factor);
|
||||
void zoomIn(float factor, float x, float y);
|
||||
void zoomOut(float factor, float x, float y);
|
||||
void zoomInCentered(float factor);
|
||||
void zoomOutCentered(float factor);
|
||||
|
||||
#endif /*WINDOW_H_*/
|
||||
|
|
Reference in a new issue