Jump to content
  • Advertisement
Sign in to follow this  
Enjoy

Drawing distorted space

This topic is 3888 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

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
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;
}






Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!