a clock
Each clock represents the hours, minutes and seconds (from left to right) which then change the vector field from where stream lines are being drawn, the CGAL lib was used to calculate the lines and we developed the app in openFrameworks + OpenGL

code is below, after the cut.
#include#include #include #include #include #include #include #include typedef double coord_type; typedef CGAL::Cartesian K1; typedef CGAL::Filtered_kernel K; typedef CGAL::Regular_grid_2 Field; typedef CGAL::Runge_kutta_integrator_2 Runge_kutta_integrator; typedef CGAL::Stream_lines_2 Strl; typedef Strl::Point_iterator_2 Point_iterator; typedef Strl::Stream_line_iterator_2 Strl_iterator; typedef Strl::Point_2 Point_2; typedef Strl::Vector_2 Vector_2; #include "ofMain.h" #include "ofCvMain.h" #include "myCvGrayscaleImage.h" #include "myCvColorImage.h" #include "vec.h" class testApp : public ofSimpleApp{ public: void setup(); void update(); void draw(); void keyPressed (int key); void mouseMoved(int x, int y ); void mouseDragged(int x, int y, int button); void mousePressed(int x, int y, int button); void mouseReleased(); ofVideoGrabber vidGrabber; myCvColorImage colorImg; bool showFreezeImg; long hours; long minutes; long seconds; vec3 hourVec; vec3 minVec; vec3 secVec; vec3 hourCenter; vec3 minCenter; vec3 secCenter; void updateClocks(); void renderClocks(); // VIDEO CAMERA //some capture frame dimensions int iwidth; int iheight; CvSize isize; //CGAL Strl* Stream_lines; std::vector vf; std::vector vfClock; double iXSize, iYSize; void calcStreamlines(); void drawStreamlines(); void initVectorfield(int width, int height); void drawVectorfield(std::vector & vf); void updateVectorfield(std::vector & vf); }; void testApp::setup() { ofSetFrameRate(60); ofSetVerticalSync(true); ofEnableAlphaBlending(); ofSetCircleResolution(44); hours = ofGetHours()*6; minutes = ofGetMinutes()*6 + 360*hours; seconds = ofGetSeconds()*6 + 360*minutes + 180; hourVec.set(sin(hours*(PI/180)), cos(hours*(PI/180)), 0); minVec.set(sin(minutes*(PI/180)), cos(minutes*(PI/180)), 0); secVec.set(sin(seconds*(PI/180)), cos(seconds*(PI/180)), 0); hourCenter = vec3(200, 350, 0); minCenter = vec3(ofGetWidth()/2, 350, 0); secCenter = vec3(ofGetWidth()-200, 350, 0); iwidth = 320; iheight = 240; isize = cvSize(iwidth, iheight); vidGrabber.setVerbose(true); //vidGrabber.initGrabber(iwidth, iheight); //colorImg.allocate(iwidth, iheight); iXSize = iYSize = 64; initVectorfield( 64, 64 ); calcStreamlines(); } void testApp::calcStreamlines() { Runge_kutta_integrator runge_kutta_integrator; //unsigned int x_samples, y_samples; /*data.vec.cin is an ASCII file containing the vector field values*/ //std::ifstream infile("vnoise.vec.cin", std::ios::in); //infile >> x_samples; //infile >> y_samples; /* Field regular_grid_2(3, 1, iXSize, iYSize); regular_grid_2.set_field(0, 0, Vector_2(hourVec.x, hourVec.y)); regular_grid_2.set_field(1, 0, Vector_2(minVec.x, minVec.y)); regular_grid_2.set_field(2, 0, Vector_2(secVec.x, secVec.y)); */ Field regular_grid_2(64, 64, iXSize, iYSize); /*fill the grid with the appropreate values*/ int i = 0; for( unsigned int y=0; y<64; y++ ) { for( unsigned int x=0; x<64; x++ ) { //vec3 loc = vf[i]; vec3 vel = vfClock[i+1]; regular_grid_2.set_field(x, y, Vector_2(vel.x, vel.y)); i += 2; } } /* the placement of streamlines */ //std::cout << "processing...\n"; double dSep = 3.5; double dRat = 1.6; Stream_lines = new Strl(regular_grid_2, runge_kutta_integrator,dSep,dRat); } void testApp::drawStreamlines() { glColor3f(1.0, 1.0, 1.0); glLineWidth(1.5f); float fX = ofGetWidth()/iXSize; float fY = ofGetHeight()/iXSize; for(Strl_iterator sit = Stream_lines->begin(); sit != Stream_lines->end(); sit++) { glBegin(GL_LINE_STRIP); for(Point_iterator pit = sit->first; pit != sit->second; pit++) { Point_2 p = *pit; glVertex2f(p.x()*fX, p.y()*fY); } glEnd(); } } void testApp::initVectorfield(int width, int height) { float x_spacing = ofGetWidth()/width; float y_spacing = ofGetHeight()/height; for(int y=0; y & vf) { vec3 steer; vec3 armLoc; float influence = 0; for(int i=0; i add(steer); armLoc.set(hourVec); armLoc.add(hourCenter); steer.set(hourVec); steer.normalize(); influence = (ofGetWidth()/4)/loc.distance(armLoc); steer.scale(influence*4); vel->add(steer); //minute clock steer.set(minVec); steer.normalize(); influence = (ofGetWidth()/4)/loc.distance(minCenter); steer.scale(influence); vel->add(steer); armLoc.set(minVec); armLoc.add(minCenter); steer.set(minVec); steer.normalize(); influence = (ofGetWidth()/4)/loc.distance(armLoc); steer.scale(influence*4); vel->add(steer); //seconds clock steer.set(secVec); steer.normalize(); influence = (ofGetWidth()/4)/loc.distance(secCenter); steer.scale(influence); vel->add(steer); armLoc.set(secVec); armLoc.add(secCenter); steer.set(secVec); steer.normalize(); influence = (ofGetWidth()/4)/loc.distance(armLoc); steer.scale(influence*4); vel->add(steer); vel->normalize(); vel->scale(10); } } void testApp::drawVectorfield(std::vector & vf) { glColor3f(0.0, 0.0, 0.0); glLineWidth(1.5f); glBegin(GL_LINES); for(int i=0; i