initial dragging attempt... failed so far

git-svn-id: svn://anubis/misc/sierpinski-gtk@256 bd8a9e45-a331-0410-811e-c64571078777
This commit is contained in:
josh 2010-10-28 16:49:32 +00:00
parent 58ff70113a
commit b24809f39e
3 changed files with 266 additions and 10 deletions

View File

@ -9,6 +9,7 @@
#include <gdkmm/cursor.h>
#include "SierpinskiDA.h"
#include "Vector.h"
using namespace std;
@ -22,6 +23,7 @@ SierpinskiDA::SierpinskiDA(const Glib::RefPtr<const Gdk::GL::Config> & config,
| Gdk::BUTTON_PRESS_MASK
| Gdk::BUTTON_RELEASE_MASK
| Gdk::SCROLL_MASK);
m_dragging = false;
}
void SierpinskiDA::regenerate_clicked()
@ -84,17 +86,14 @@ bool SierpinskiDA::draw()
glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60, get_width()/(double)get_height(), 0.01, 1000.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0, -3, 1.5,
0, 0, 1,
0, 0, 1);
glPushMatrix();
glMultMatrixf(m_drag_matrix);
glCallList(m_dl);
glPopMatrix();
if (get_gl_window()->is_double_buffered())
get_gl_window()->swap_buffers();
else
@ -106,17 +105,48 @@ bool SierpinskiDA::draw()
bool SierpinskiDA::on_motion_notify_event(GdkEventMotion * event)
{
get_pointer(m_x, m_y);
if (m_dragging)
{
Vector v = ptrToDragVector();
Vector cross = m_dragBegin * v;
if (cross.mag2() > 0.5)
{
gl_begin();
glPushMatrix();
glLoadIdentity();
glRotated(180.0 * acos(m_dragBegin % v) / M_PI,
cross[0], cross[1], cross[2]);
glGetFloatv(GL_MODELVIEW_MATRIX, &m_drag_matrix[0]);
glPopMatrix();
gl_end();
}
queue_draw();
}
return true;
}
bool SierpinskiDA::on_button_press_event(GdkEventButton * event)
{
if (event->button == 1)
{
m_dragging = true;
m_dragBegin = ptrToDragVector();
}
return false;
}
bool SierpinskiDA::on_button_release_event(GdkEventButton * event)
{
if (event->button == 1)
{
m_dragging = false;
gl_begin();
glPushMatrix();
glLoadIdentity();
glGetFloatv(GL_MODELVIEW_MATRIX, &m_drag_matrix[0]);
glPopMatrix();
gl_end();
}
return false;
}
@ -143,6 +173,16 @@ void SierpinskiDA::on_realize()
#endif
glColor3f(1, 1, 1);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60, get_width()/(double)get_height(), 0.01, 1000.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glGetFloatv(GL_MODELVIEW_MATRIX, &m_drag_matrix[0]);
gluLookAt(0, -3, 1.5,
0, 0, 1,
0, 0, 1);
gl_end();
regenerate(10000);
@ -167,3 +207,17 @@ bool SierpinskiDA::on_expose_event(GdkEventExpose * event)
{
return draw();
}
Vector SierpinskiDA::ptrToDragVector()
{
int x, y;
get_pointer(x, y);
int w = get_width();
int h = get_height();
double r = min(w, h) / 2.0;
double xd = (x - w/2.0) / r;
double yd = (h/2.0 - y) / r;
double d2 = xd*xd + yd*yd;
double z = d2 >= 1.0 ? 0.0 : sqrt(1 - d2);
return Vector(xd, yd, z).normalize();
}

View File

@ -4,6 +4,8 @@
#include <gtkmm/gl/drawingarea.h>
#include "Vector.h"
class SierpinskiDA : public Gtk::GL::DrawingArea
{
public:
@ -13,7 +15,9 @@ class SierpinskiDA : public Gtk::GL::DrawingArea
void regenerate_clicked();
protected:
int m_x, m_y;
bool m_dragging;
Vector m_dragBegin;
float m_drag_matrix[16];
int m_dl;
Gtk::Entry & m_n_points_entry;
@ -24,6 +28,8 @@ class SierpinskiDA : public Gtk::GL::DrawingArea
bool gl_begin();
void gl_end();
Vector ptrToDragVector();
/* signal handlers */
virtual bool on_motion_notify_event(GdkEventMotion * event);
virtual bool on_button_press_event(GdkEventButton * event);

196
Vector.h Normal file
View File

@ -0,0 +1,196 @@
#ifndef VECTOR_H
#define VECTOR_H VECTOR_H
#include <math.h> /* sqrt() */
#include <iostream>
class Vector
{
public:
Vector()
{
m_array[0] = 0.0;
m_array[1] = 0.0;
m_array[2] = 0.0;
}
Vector(double x, double y, double z)
{
m_array[0] = x;
m_array[1] = y;
m_array[2] = z;
}
Vector & normalize()
{
double length = mag();
m_array[0] /= length;
m_array[1] /= length;
m_array[2] /= length;
return *this;
}
double mag() const
{
return sqrt(m_array[0] * m_array[0]
+ m_array[1] * m_array[1]
+ m_array[2] * m_array[2]);
}
double mag2() const
{
return m_array[0] * m_array[0]
+ m_array[1] * m_array[1]
+ m_array[2] * m_array[2];
}
double dist_to(const Vector & other) const
{
return (other - *this).mag();
}
Vector proj(const Vector & target) const
{
Vector target_normalized = target;
target_normalized.normalize();
return target_normalized * ((*this) % target_normalized);
}
Vector reflect(const Vector & target) const
{
return (*this) - target * (2 * dot(target));
}
/*
* from http://www.flipcode.com/archives/
* Reflections_and_Refraction_in_Raytracing.shtml
* target: normal vector of surface
* n1: refraction index of object we're coming from
* n2: refraction index of object we're going into
*/
Vector refract(const Vector & target, double n1, double n2) const
{
const double n = n1 / n2;
const double cosI = -dot(target);
const double sinT2 = n * n * (1.0 - cosI * cosI);
if (sinT2 > 1.0)
return Vector(0.0, 0.0, 0.0);
return (*this) * n + target * (n * cosI - sqrt(1.0 - sinT2));
}
Vector getPerpendicular() const
{
Vector t = *this;
t.normalize();
Vector p = t * Vector(0, 0, 1);
if (p.mag() <= 0.1)
{
p = t * Vector(1, 0, 0);
}
return p;
}
Vector mult(const Vector & v2) const
{
return Vector(
m_array[0] * v2.m_array[0],
m_array[1] * v2.m_array[1],
m_array[2] * v2.m_array[2]);
}
Vector div(const Vector & v2) const
{
return Vector(
m_array[0] / v2.m_array[0],
m_array[1] / v2.m_array[1],
m_array[2] / v2.m_array[2]);
}
Vector operator-() const
{
return Vector(
-m_array[0],
-m_array[1],
-m_array[2]);
}
/* Compute the dot-product of two vectors */
double dot(const Vector & v2) const
{
return m_array[0] * v2.m_array[0]
+ m_array[1] * v2.m_array[1]
+ m_array[2] * v2.m_array[2];
}
double operator%(const Vector & v2) const { return dot(v2); }
/* Compute the cross-product of two vectors */
Vector cross(const Vector & v2) const
{
return Vector(
m_array[1] * v2.m_array[2] - m_array[2] * v2.m_array[1],
m_array[2] * v2.m_array[0] - m_array[0] * v2.m_array[2],
m_array[0] * v2.m_array[1] - m_array[1] * v2.m_array[0]);
}
Vector operator*(const Vector & v2) const { return cross(v2); }
Vector operator+(const Vector & v2) const
{
return Vector(
m_array[0] + v2.m_array[0],
m_array[1] + v2.m_array[1],
m_array[2] + v2.m_array[2]);
}
Vector operator-(const Vector & v2) const
{
return Vector(
m_array[0] - v2.m_array[0],
m_array[1] - v2.m_array[1],
m_array[2] - v2.m_array[2]);
}
Vector operator*(double scale) const
{
return Vector(
m_array[0] * scale,
m_array[1] * scale,
m_array[2] * scale);
}
Vector operator/(double scale) const
{
return Vector(
m_array[0] / scale,
m_array[0] / scale,
m_array[0] / scale);
}
Vector & operator+=(const Vector & v2)
{
m_array[0] += v2.m_array[0];
m_array[1] += v2.m_array[1];
m_array[2] += v2.m_array[2];
return *this;
}
Vector & operator-=(const Vector & v2)
{
m_array[0] -= v2.m_array[0];
m_array[1] -= v2.m_array[1];
m_array[2] -= v2.m_array[2];
return *this;
}
double & operator[](int idx) { return m_array[idx]; }
double operator[](int idx) const { return m_array[idx]; }
protected:
double m_array[3];
};
static inline Vector operator*(double d, const Vector & v) { return v * d; }
static inline Vector operator/(double d, const Vector & v) { return v / d; }
#endif