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 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_*/

View file

@ -51,14 +51,8 @@ class LevelEdge : public LevelObject {
provider->moveEdge(id, x, y);
}
virtual void rotate(float a) {
provider->rotateEdge(id, a);
}
virtual Vertex getCenter() const {
Line l = provider->getEdge(id)->toLine();
return (l.getVertex1()+l.getVertex2()) / 2;
virtual void rotate(Vertex m, float a) {
provider->rotateEdge(id, m, a);
}
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 void move(float x, float y) {}
virtual void rotate(float a) {}
virtual Vertex getCenter() const {return Vertex();}
virtual void rotate(Vertex m, float a) {}
};
#endif /*LEVELOBJECT_H_*/

View file

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

View file

@ -88,15 +88,19 @@ class Portal : public LevelObject, public VertexProvider {
updateVertices();
}
virtual void rotate(float a) {
virtual void rotate(Vertex m, float a) {
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();
}
virtual Vertex getCenter() const {
return pos;
}
virtual const Vertex* getVertex(size_t id) const {
return &vertices[id];
}
@ -109,12 +113,8 @@ class Portal : public LevelObject, public VertexProvider {
move(x, y);
}
virtual void rotateVertex(size_t id, float a) {
pos = vertices[id];
rotate(a);
pos = vertices[(id+2)%4];
updateVertices();
virtual void rotateVertex(size_t id, Vertex m, float a) {
rotate(m, a);
}
};

View file

@ -69,6 +69,20 @@ void Renderer::drawCircle(const Vertex &m, float r, int n) {
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) {
glBegin(GL_POLYGON);

View file

@ -22,6 +22,7 @@ class Renderer {
void drawPolygon(const Polygon &polygon, bool close = true);
void fillCircle(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 renderObject(const LevelObject &object, bool selected, bool highlighted, float scale);

View file

@ -2,17 +2,6 @@
#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) {
polygon.clear();
edges.clear();
@ -61,3 +50,14 @@ std::vector<SharedPtr<LevelObject> > Room::getChildren() {
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;
void rotateAround(Vertex z, float a);
public:
Room() {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;
}
virtual void rotate(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 void rotate(Vertex m, float a);
virtual const Vertex* getVertex(size_t id) const {
return &polygon[id];
@ -82,8 +69,8 @@ class Room : public LevelObject, private VertexProvider, private EdgeProvider {
polygon[id] += Vertex(x, y);
}
virtual void rotateVertex(size_t id, float a) {
rotateAround(polygon[id], a);
virtual void rotateVertex(size_t id, Vertex m, float a) {
rotate(m, a);
}
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);
}
virtual void rotateEdge(size_t id, float a) {
rotateAround((polygon[id]+polygon[(id+1)%polygon.size()])/2, a);
virtual void rotateEdge(size_t id, Vertex m, float a) {
rotate(m, a);
}
};

View file

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

View file

@ -1,6 +1,8 @@
#include "ToolRotate.h"
#include <GL/gl.h>
ToolRotate::ToolRotate(EditManager *editManager) : sidebar(editManager) {
ToolRotate::ToolRotate(EditManager *editManager) : Renderer(editManager), sidebar(editManager) {
this->editManager = editManager;
pressed = false;
@ -24,8 +26,8 @@ bool ToolRotate::buttonPress(unsigned int button) {
return false;
pressed = true;
Vertex v = *editManager->getHoveredVertex() - editManager->getHoveredObject()->getCenter();
angle = atan2(v.getY(), v.getX());
valid = false;
v0 = v = *editManager->getHoveredVertex();
editManager->setSelectedObject(editManager->getHoveredObject());
@ -58,13 +60,40 @@ bool ToolRotate::motion() {
if(!editManager->getHoveredVertex())
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;
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 "SidebarView.h"
#include "Renderer.h"
class ToolRotate : public Tool, EventHandler {
class ToolRotate : public Tool, private EventHandler, private Renderer {
private:
GtkWidget *image;
@ -12,12 +13,14 @@ class ToolRotate : public Tool, EventHandler {
SidebarView sidebar;
bool pressed;
bool pressed, valid;
float angle;
Vertex v0, v;
// prevent shallow copy
ToolRotate(const ToolRotate &t);
const ToolRotate& operator=(const ToolRotate &t);
public:
ToolRotate(EditManager *editManager);
virtual ~ToolRotate();
@ -48,6 +51,12 @@ class ToolRotate : public Tool, EventHandler {
virtual bool buttonRelease(unsigned int button);
virtual bool motion();
virtual Renderer *getRenderer() {
return this;
}
virtual void render(const Level &level, const Rectangle &rect, float scale);
virtual Sidebar* getSidebar() {
return &sidebar;
}

View file

@ -12,7 +12,7 @@ class VertexProvider {
virtual size_t getVertexCount() const = 0;
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_*/