Skip to main content
GameDev.net gamedev.net
🔒 Locked

Coordinate system conversion

Started by AliasNotFound Nov 27, 2002 at 4:19 PM 3 replies 200+ views
Original Post
AliasNotFound
AliasNotFound
I''ve been trying to implement an algorithm that will convert screen coordinates (in pixels) into a 2D cartesian system where the origin is at the center of the screen and the x and y can be set to a specific size. As an example, I''m trying to map a system that has x from -4 to 4 and y from 3 to -3 in order to plot a Mandelbrot fractal. The section of code that plots the fractal looks like this:
  

for (y=0; y<SCREEN_HEIGHT; y++)
{
   for (x=0; x<SCREEN_WIDTH; x++)
   {
      // convert pixel coordiates into graph coords	   

      comp_x = (4*(x-SCREEN_WIDTH/2))/SCREEN_WIDTH;   
      comp_y = -((3*(y-SCREEN_HEIGHT/2))/SCREEN_HEIGHT); 
      
      Complex z;
      Complex c(comp_x, comp_y);
   
      for (iter=0; iter<maxIter; iter++)
      {
         z = z*z + c;
         dist = z.distance();
	 
         if (dist>2)
	 {
	    if(iter!=0)
	       color = ColorIndex[iter];
	    break;
	 }
      }
      if (dist<2)		   
         color=RGB(0, 0, 0);
		   
      SetPixel(hdc, x, y, color);  
   }
} 
  
The code works but the lines that convert the coordinates seem very ugly to me. I did this more or less through experimentation to find out what works but what I need to do is come up with a generic method for performing this kind of operation so that I can use it in other programs without having to ''hardwire'' it. If anyone could give me a push in the right direction I would appreciate it. I know this is an elementary concept in graphics programming, but I''m still a beginner. BTW: This is not a school project, programming is simply a hobby Phillip
Kylotan
Kylotan
Well, what you have there already looks like the most efficient way of doing things. (Except for precalculating SCREEN_WIDTH/2, moving the calculation of comp_y into the y loop instead of the x, etc.) But if you really wanted something cleaner, you could look at it as a pair of simple linear interpolations. There should be plenty of code for that around if you wanted to make it generic. To be honest though, I would leave it as it is, since per-pixel operations are one of the few things that really need optimising in most code. You could perhaps write an inline function for the interpolation though.

[ MSVC Fixes | STL | SDL | Game AI | Sockets | C++ Faq Lite | Boost | Asking Questions | Organising code files | My stuff ]
AliasNotFound
AliasNotFound
quote:
Original post by Kylotan
Well, what you have there already looks like the most efficient way of doing things. (Except for precalculating SCREEN_WIDTH/2, moving the calculation of comp_y into the y loop instead of the x, etc.) But if you really wanted something cleaner, you could look at it as a pair of simple linear interpolations. There should be plenty of code for that around if you wanted to make it generic. To be honest though, I would leave it as it is, since per-pixel operations are one of the few things that really need optimising in most code. You could perhaps write an inline function for the interpolation though.



Kylotan,
Thanks for the info. I don''t know why I didn''t think of precalculating the SCREEN_WIDTH/2 and moving the comp_y calculation into the y loop. I guess I havn''t quite learned how to look for those kinds of inefficiencies yet. This should help speed things up a bit.
Thanks,
Phillip

trzy
trzy
quote:
To be honest though, I would leave it as it is, since per-pixel operations are one of the few things that really need optimising in most code. You could perhaps write an inline function for the interpolation though.



What?

Doing those calculations for every pixel in the image is going to be a pretty big bottleneck. What else are you going to optimize?

A better method would be to calculate a step_x and step_y outside of all of the loops (thus it''s only done once for the entire image) and add the results during each iteration. I use a method similar to this one:

step_x = (UPPER_X - LOWER_X) / xres;
step_y = (UPPER_Y - LOWER_Y) / yres;

You might want to adjust step_y to match the aspect ratio (by eliminating UPPER_Y and calculating a new one based on the X resolution of the screen), but that''s not necessary.

Each time you step a pixel in the X direction, add step_x to the plane coordinate (same goes for step_y in the Y direction.)

This way, there aren''t going to be _any_ screen->coordinate plane calculations performed during the rendering at all.

Function calls are out of the question on a per-pixel basis and even an inline function is an indicator that you''re missing something really obvious.

---
Bart
----Bart
Trienco
Trienco
comp_x = (4*(x-SCREEN_WIDTH/2))/SCREEN_WIDTH;
comp_y = -((3*(y-SCREEN_HEIGHT/2))/SCREEN_HEIGHT);

if i didnt make a mistake you could also do:
-4 + 8*(x/WIDTH) or -4 + x*(8/WIDTH)

or
xfactor=2*xsize/WIDTH;
yfactor=2*ysize/WIDTH;

and use comp_x=-xsize + x*xfactor;
or you use your equation and use (x-HalfWidth)*(4divWIDTH)
but any way would include at least one mutliplication and one addition.

oh, and if you ever use floats prefer a mult over a div (there seem to be cases when the fstp instruction takes an eternity to write back the result of a division.. close to 1000 clockticks- which is about 10 times what it took to calculate it *g*)
f@dzhttp://festini.device-zero.de

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.