Drawing distorted space

Started by
0 comments, last by nplex 16 years, 2 months ago
Hi, I need a formula to draw a distorted space, like in Einstain's relativety theory. I need to get something like this: 1 2 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?
Advertisement
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.


#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