Sign in to follow this  
Enjoy

Drawing distorted space

Recommended Posts

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?

Share this post


Link to post
Share on other sites
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;
}






Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this