zoomedit: Made rotation tool much nicer ;-)

This commit is contained in:
neoraider 2008-02-15 19:10:04 +00:00
parent 80b4f14530
commit 0ea1d38865
13 changed files with 96 additions and 68 deletions

View file

@ -12,7 +12,7 @@ class EdgeProvider {
virtual size_t getEdgeCount() const = 0; virtual size_t getEdgeCount() const = 0;
virtual void moveEdge(size_t id, float x, float y) {} virtual void moveEdge(size_t id, float x, float y) {}
virtual void rotateEdge(size_t id, float a) {} virtual void rotateEdge(size_t id, Vertex m, float a) {}
}; };
#endif /*EDGEPROVIDER_H_*/ #endif /*EDGEPROVIDER_H_*/

View file

@ -51,14 +51,8 @@ class LevelEdge : public LevelObject {
provider->moveEdge(id, x, y); provider->moveEdge(id, x, y);
} }
virtual void rotate(float a) { virtual void rotate(Vertex m, float a) {
provider->rotateEdge(id, a); provider->rotateEdge(id, m, a);
}
virtual Vertex getCenter() const {
Line l = provider->getEdge(id)->toLine();
return (l.getVertex1()+l.getVertex2()) / 2;
} }
const Edge* operator->() const {return provider->getEdge(id);} const Edge* operator->() const {return provider->getEdge(id);}

View file

@ -27,9 +27,7 @@ class LevelObject : public Object {
virtual int getPriority() const {return 0;} virtual int getPriority() const {return 0;}
virtual void move(float x, float y) {} virtual void move(float x, float y) {}
virtual void rotate(float a) {} virtual void rotate(Vertex m, float a) {}
virtual Vertex getCenter() const {return Vertex();}
}; };
#endif /*LEVELOBJECT_H_*/ #endif /*LEVELOBJECT_H_*/

View file

@ -30,12 +30,8 @@ class LevelVertex : public LevelObject {
provider->moveVertex(id, x, y); provider->moveVertex(id, x, y);
} }
virtual void rotate(float a) { virtual void rotate(Vertex m, float a) {
provider->rotateVertex(id, a); provider->rotateVertex(id, m, a);
}
virtual Vertex getCenter() const {
return *provider->getVertex(id);
} }
const Vertex* operator->() const {return provider->getVertex(id);} const Vertex* operator->() const {return provider->getVertex(id);}

View file

@ -88,15 +88,19 @@ class Portal : public LevelObject, public VertexProvider {
updateVertices(); updateVertices();
} }
virtual void rotate(float a) { virtual void rotate(Vertex m, float a) {
orient = fmodf(orient+a, 2*M_PI); orient = fmodf(orient+a, 2*M_PI);
s = sinf(a);
c = cosf(a);
pos -= m;
pos.setLocation(c*pos.getX() - s*pos.getY(), c*pos.getY() + s*pos.getX());
pos += m;
updateOrient(); updateOrient();
} }
virtual Vertex getCenter() const {
return pos;
}
virtual const Vertex* getVertex(size_t id) const { virtual const Vertex* getVertex(size_t id) const {
return &vertices[id]; return &vertices[id];
} }
@ -109,12 +113,8 @@ class Portal : public LevelObject, public VertexProvider {
move(x, y); move(x, y);
} }
virtual void rotateVertex(size_t id, float a) { virtual void rotateVertex(size_t id, Vertex m, float a) {
pos = vertices[id]; rotate(m, a);
rotate(a);
pos = vertices[(id+2)%4];
updateVertices();
} }
}; };

View file

@ -69,6 +69,20 @@ void Renderer::drawCircle(const Vertex &m, float r, int n) {
glEnd(); glEnd();
} }
void Renderer::drawCircleDotted(const Vertex &m, float r, int n, int d, float rot) {
glBegin(GL_LINES);
for(int i = 0; i < n; i++) {
if(2*d*(i%(n/d)) >= n)
continue;
glVertex2f(m.getX()+r*cosf(rot+2*M_PI*i/n), m.getY()+r*sinf(rot+2*M_PI*i/n));
glVertex2f(m.getX()+r*cosf(rot+2*M_PI*(i+1)/n), m.getY()+r*sinf(rot+2*M_PI*(i+1)/n));
}
glEnd();
}
void Renderer::fillCircle(const Vertex &m, float r, int n) { void Renderer::fillCircle(const Vertex &m, float r, int n) {
glBegin(GL_POLYGON); glBegin(GL_POLYGON);

View file

@ -22,6 +22,7 @@ class Renderer {
void drawPolygon(const Polygon &polygon, bool close = true); void drawPolygon(const Polygon &polygon, bool close = true);
void fillCircle(const Vertex &m, float r, int n = 64); void fillCircle(const Vertex &m, float r, int n = 64);
void drawCircle(const Vertex &m, float r, int n = 64); void drawCircle(const Vertex &m, float r, int n = 64);
void drawCircleDotted(const Vertex &m, float r, int n = 64, int d = 8, float rot = 0);
void drawCross(const Vertex &m, float r); void drawCross(const Vertex &m, float r);
void renderObject(const LevelObject &object, bool selected, bool highlighted, float scale); void renderObject(const LevelObject &object, bool selected, bool highlighted, float scale);

View file

@ -2,17 +2,6 @@
#include "LevelEdge.h" #include "LevelEdge.h"
void Room::rotateAround(Vertex z, float a) {
float s = sinf(a);
float c = cosf(a);
for(Polygon::iterator v = polygon.begin(); v != polygon.end(); v++) {
*v -= z;
v->setLocation(c*v->getX() - s*v->getY(), c*v->getY() + s*v->getX());
*v += z;
}
}
const Room& Room::operator=(const Room &room) { const Room& Room::operator=(const Room &room) {
polygon.clear(); polygon.clear();
edges.clear(); edges.clear();
@ -61,3 +50,14 @@ std::vector<SharedPtr<LevelObject> > Room::getChildren() {
return children; return children;
} }
void Room::rotate(Vertex m, float a) {
float s = sinf(a);
float c = cosf(a);
for(Polygon::iterator v = polygon.begin(); v != polygon.end(); v++) {
*v -= m;
v->setLocation(c*v->getX() - s*v->getY(), c*v->getY() + s*v->getX());
*v += m;
}
}

23
Room.h
View file

@ -17,8 +17,6 @@ class Room : public LevelObject, private VertexProvider, private EdgeProvider {
std::vector<Edge> edges; std::vector<Edge> edges;
void rotateAround(Vertex z, float a);
public: public:
Room() {height = 10;} Room() {height = 10;}
Room(std::string name) {this->name = name; height = 10;} Room(std::string name) {this->name = name; height = 10;}
@ -57,18 +55,7 @@ class Room : public LevelObject, private VertexProvider, private EdgeProvider {
*v += m; *v += m;
} }
virtual void rotate(float a) { virtual void rotate(Vertex m, float a);
rotateAround(getCenter(), a);
}
virtual Vertex getCenter() const {
Vertex ret;
for(Polygon::const_iterator v = polygon.begin(); v != polygon.end(); v++)
ret += *v;
return ret / polygon.size();
}
virtual const Vertex* getVertex(size_t id) const { virtual const Vertex* getVertex(size_t id) const {
return &polygon[id]; return &polygon[id];
@ -82,8 +69,8 @@ class Room : public LevelObject, private VertexProvider, private EdgeProvider {
polygon[id] += Vertex(x, y); polygon[id] += Vertex(x, y);
} }
virtual void rotateVertex(size_t id, float a) { virtual void rotateVertex(size_t id, Vertex m, float a) {
rotateAround(polygon[id], a); rotate(m, a);
} }
virtual const Edge* getEdge(size_t id) const { virtual const Edge* getEdge(size_t id) const {
@ -99,8 +86,8 @@ class Room : public LevelObject, private VertexProvider, private EdgeProvider {
moveVertex((id+1)%polygon.size(), x, y); moveVertex((id+1)%polygon.size(), x, y);
} }
virtual void rotateEdge(size_t id, float a) { virtual void rotateEdge(size_t id, Vertex m, float a) {
rotateAround((polygon[id]+polygon[(id+1)%polygon.size()])/2, a); rotate(m, a);
} }
}; };

View file

@ -6,7 +6,7 @@
#include "SidebarAdd.h" #include "SidebarAdd.h"
class ToolAddPolygon : public Tool, public EventHandler, public Renderer { class ToolAddPolygon : public Tool, private EventHandler, private Renderer {
private: private:
GtkWidget *image; GtkWidget *image;

View file

@ -1,6 +1,8 @@
#include "ToolRotate.h" #include "ToolRotate.h"
#include <GL/gl.h>
ToolRotate::ToolRotate(EditManager *editManager) : sidebar(editManager) {
ToolRotate::ToolRotate(EditManager *editManager) : Renderer(editManager), sidebar(editManager) {
this->editManager = editManager; this->editManager = editManager;
pressed = false; pressed = false;
@ -24,8 +26,8 @@ bool ToolRotate::buttonPress(unsigned int button) {
return false; return false;
pressed = true; pressed = true;
Vertex v = *editManager->getHoveredVertex() - editManager->getHoveredObject()->getCenter(); valid = false;
angle = atan2(v.getY(), v.getX()); v0 = v = *editManager->getHoveredVertex();
editManager->setSelectedObject(editManager->getHoveredObject()); editManager->setSelectedObject(editManager->getHoveredObject());
@ -58,13 +60,40 @@ bool ToolRotate::motion() {
if(!editManager->getHoveredVertex()) if(!editManager->getHoveredVertex())
return false; return false;
Vertex v = *editManager->getHoveredVertex() - editManager->getSelectedObject()->getCenter(); v = *editManager->getHoveredVertex();
float a = atan2(v.getY(), v.getX()); float a = atan2((v-v0).getY(), (v-v0).getX());
editManager->getSelectedObject()->rotate(a-angle); if(v0.distanceSq(v) > 0.04f) {
if(valid)
editManager->getSelectedObject()->rotate(v0, a-angle);
else
valid = true;
}
else
valid = false;
angle = a; angle = a;
return false; return false;
} }
void ToolRotate::render(const Level &level, const Rectangle &rect, float scale) {
Renderer::render(level, rect, scale);
if(pressed && valid) {
glLineWidth(1.0f);
glColor4f(1.0f, 1.0f, 1.0f, 0.7f);
drawCircleDotted(v0, v0.distance(v), 64, 16, angle);
glLineWidth(2.0f);
glBegin(GL_LINES);
glVertex2f(v0.getX(), v0.getY());
glVertex2f(v.getX(), v.getY());
glEnd();
}
}

View file

@ -3,8 +3,9 @@
#include "Tool.h" #include "Tool.h"
#include "SidebarView.h" #include "SidebarView.h"
#include "Renderer.h"
class ToolRotate : public Tool, EventHandler { class ToolRotate : public Tool, private EventHandler, private Renderer {
private: private:
GtkWidget *image; GtkWidget *image;
@ -12,12 +13,14 @@ class ToolRotate : public Tool, EventHandler {
SidebarView sidebar; SidebarView sidebar;
bool pressed; bool pressed, valid;
float angle; float angle;
Vertex v0, v;
// prevent shallow copy // prevent shallow copy
ToolRotate(const ToolRotate &t); ToolRotate(const ToolRotate &t);
const ToolRotate& operator=(const ToolRotate &t); const ToolRotate& operator=(const ToolRotate &t);
public: public:
ToolRotate(EditManager *editManager); ToolRotate(EditManager *editManager);
virtual ~ToolRotate(); virtual ~ToolRotate();
@ -48,6 +51,12 @@ class ToolRotate : public Tool, EventHandler {
virtual bool buttonRelease(unsigned int button); virtual bool buttonRelease(unsigned int button);
virtual bool motion(); virtual bool motion();
virtual Renderer *getRenderer() {
return this;
}
virtual void render(const Level &level, const Rectangle &rect, float scale);
virtual Sidebar* getSidebar() { virtual Sidebar* getSidebar() {
return &sidebar; return &sidebar;
} }

View file

@ -12,7 +12,7 @@ class VertexProvider {
virtual size_t getVertexCount() const = 0; virtual size_t getVertexCount() const = 0;
virtual void moveVertex(size_t id, float x, float y) {} virtual void moveVertex(size_t id, float x, float y) {}
virtual void rotateVertex(size_t id, float a) {} virtual void rotateVertex(size_t id, Vertex m, float a) {}
}; };
#endif /*VERTEXPROVIDER_H_*/ #endif /*VERTEXPROVIDER_H_*/