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:
parent
58ff70113a
commit
b24809f39e
@ -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();
|
||||
}
|
||||
|
@ -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
196
Vector.h
Normal 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
|
Loading…
x
Reference in New Issue
Block a user