Drawing distorted space
Hi,
I need a formula to draw a distorted space, like in Einstain's relativety theory.
I need to get something like this:
I suppose that it should be something like h = M / r^2 , basing on Newton's law of gravity. But it will not work. If r aprroaches to 0, function is breaking. But I need to have something, like on those pictures.
How do I do it in a right way?
yea i couldn't find code for something like that when i wanted it, so i came up with the below. i generate an array which represents a NxN (i can get 100x100 to generate fast) grid of points (particles) on my screen, they are rendered evenly spaced apart.
i get the distance of every particles position from my mouse, then displace the position of the particles by some amount relative to that distance.
i used this for an audio visualization app i was playing with, so for that it worked. i used arbitrary values for the effect, i'm sure you can modify it to be physically accurate.
i get the distance of every particles position from my mouse, then displace the position of the particles by some amount relative to that distance.
i used this for an audio visualization app i was playing with, so for that it worked. i used arbitrary values for the effect, i'm sure you can modify it to be physically accurate.
#include <windows.h>#include <iostream>#include <vector>#include <cmath>#include <GL/glut.h>const int AW = 640, AH = 480, HAW = int(AW/2.0), HAH = int(AH/2.0);typedef struct { double x, y; } _Position;typedef struct { double r, g, b; } _RGB;typedef struct { double h, s, l; } _HSL;std::vector< double > coordx, coordy, gridx, gridy;_Position mouse, object, *instance;_HSL hslPoint, hslMouse;_RGB rgbPoint, rgbMouse;double Hue_to_RGB( double v1, double v2, double vH );void HSL_RGB( _HSL *icolor, _RGB *ocolor );static void resize(int width, int height){ glMatrixMode(GL_PROJECTION); glLoadIdentity(); glViewport(0, 0, width, height); glMatrixMode(GL_MODELVIEW); glLoadIdentity() ;}static void display(void){ static double t, px, py, qx, qy, dx, dy, angle, lim, mlim, rad, dist, alph, ctmp, ttmp; lim = 0.1; mlim = 0.33; alph = 1.0; // t = glutGet(GLUT_ELAPSED_TIME) / 1000.0; instance = &mouse; if (instance == &mouse) { // do nothing for the mouse } else { object.x = 0.0; object.y = 0.0; } glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); glPushMatrix(); glPointSize(2.0); glBegin(GL_POINTS); for (int x=0; x<gridx.size(); ++x) { qx = gridx.at(x); dx = (*instance).x - qx; for (int y=0; y<gridy.size(); ++y) { qy = gridy.at(y); dy = (*instance).y - qy; dist = sqrt((dx*dx)+(dy*dy)); rad = (lim / dist); angle = atan2((*instance).y - qy, (*instance).x - qx); px = (rad >= mlim) ? (*instance).x : ((cos(angle) * rad) + qx); py = (rad >= mlim) ? (*instance).y : ((sin(angle) * rad) + qy); hslPoint.h = cos(angle); hslPoint.s = 1.0; hslPoint.l = 0.5; HSL_RGB(&hslPoint, &rgbPoint); if (px == (*instance).x && py == (*instance).y) { // don't draw } else { glColor4f(rgbPoint.r, rgbPoint.g, rgbPoint.b, alph); glVertex2f(px, py); } } } glEnd(); glPopMatrix(); glutSwapBuffers(); Sleep(1);}static void key(unsigned char key, int x, int y){ int j; switch (key) { // esc case 27 : exit(0); break; } glutPostRedisplay();}static void idle(void){ glutPostRedisplay();}static void processMouse(int button, int state, int x, int y){ int specialKey = glutGetModifiers(); // GLUT_RIGHT_BUTTON, GLUT_MIDDLE_BUTTON // && (specialKey == GLUT_ACTIVE_ALT) if (state == GLUT_DOWN) { if (button == GLUT_LEFT_BUTTON) { // ... } } if (state == GLUT_UP) { if (button == GLUT_LEFT_BUTTON) { // ... } }}static void passiveMotionFunc(int x, int y){ mouse.x = coordx[x]; mouse.y = coordy[y];}static void motionFunc(int x, int y){ mouse.x = coordx[x]; mouse.y = coordy[y];}int main(int argc, char *argv[]){ hslPoint.h = 0.0; hslPoint.s = 1.0; hslPoint.l = 1.0; HSL_RGB(&hslPoint, &rgbPoint); hslMouse.h = 0.1; hslMouse.s = 0.7; hslMouse.l = 0.5; HSL_RGB(&hslMouse, &rgbMouse); int j; double ghm, gwm; ghm = AH / 16.0; gwm = AW / 16.0; for (j=-HAW; j<HAW; ++j) { coordx.push_back( float(j) / float(HAW) ); } for (j=HAH; j>-HAH; --j) { coordy.push_back( float(j) / float(HAH) ); } for (int x=0; x<int(gwm); ++x) { gridx.push_back(coordx[int((x / gwm) * (AW - 1))]); } for (int y=0; y<int(ghm); ++y) { gridy.push_back(coordy[int((y / ghm) * (AH - 1))]); } glutInit(&argc, argv); glutInitWindowSize(AW, AH); glutInitWindowPosition(160, 100); glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE); glutCreateWindow("Grid"); glutReshapeFunc(resize); glutDisplayFunc(display); glutKeyboardFunc(key); glutIdleFunc(idle); glutMouseFunc(processMouse); glutPassiveMotionFunc(passiveMotionFunc); glutMotionFunc(motionFunc); glClearColor(0.0, 0.0, 0.0, 0.0); glDisable(GL_DEPTH_TEST); glutSetCursor(GLUT_CURSOR_NONE); //glEnable(GL_BLEND); //glBlendFunc(GL_SRC_ALPHA, GL_DST_ALPHA); //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_POINT_SMOOTH); glEnable(GL_LINE_SMOOTH); glutMainLoop(); return EXIT_SUCCESS;}void HSL_RGB(_HSL *icolor, _RGB *ocolor){ double var_1, var_2, tmp, H, S, L; double etm = 1.0 / 3.0; H = (*icolor).h; S = (*icolor).s; L = (*icolor).l; if ( S == 0.0 ) { tmp = L; (*ocolor).r = tmp; // R (*ocolor).g = tmp; // G (*ocolor).b = tmp; // B } else { if ( L < 0.5 ) { var_2 = L * ( 1 + S ); } else { var_2 = ( L + S ) - ( S * L ); } var_1 = 2.0 * L - var_2; (*ocolor).r = Hue_to_RGB( var_1, var_2, H + etm ); (*ocolor).g = Hue_to_RGB( var_1, var_2, H ); (*ocolor).b = Hue_to_RGB( var_1, var_2, H - etm ); }}double Hue_to_RGB( double v1, double v2, double vH ){ double ftm = 2.0 / 3.0; if ( vH < 0.0 ) { vH += 1.0; } if ( vH > 1.0 ) { vH -= 1.0; } if ( ( 6.0 * vH ) < 1.0 ) { return ( v1 + ( v2 - v1 ) * 6.0 * vH ); } if ( ( 2.0 * vH ) < 1.0 ) { return ( v2 ); } if ( ( 3.0 * vH ) < 2.0 ) { return ( v1 + ( v2 - v1 ) * ( ftm - vH ) * 6.0 ); } return v1;}
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement