Thread: distance algorythm help

  1. #1
    Registered User MicroFiend's Avatar
    Join Date
    Nov 2002
    Posts
    80

    distance algorythm help

    ok ive been try8ing to work this out for a while now, say if we have an x,y 2d position, and a "3d" view is required how could i turn the x,y co-ordinates into a point of view co-ordinate like a side on view that gives a false definition of depth, i ve got sprite scaling to work fine for it but im having trouble getting the correct blit coordinates to make it look like its going towards the horizon (center of view) its not a good explanation of my prob, if u need more of my dogey explanations of the problem just say so, but if u can help out with the problem it would be great, thanx

  2. #2
    Registered User Draco's Avatar
    Join Date
    Apr 2002
    Posts
    463
    Another explanation of your problem would be helpful I think I understand what you're trying to say, and my thought is to try leaving the your sprite at the desired final coordinate and letting the sprite scaling to do the job of animation for you.

  3. #3
    Registered User MicroFiend's Avatar
    Join Date
    Nov 2002
    Posts
    80
    ok below is a dogey image to help explain, i think that ID software used a simular algorythm to make doom appear 3d, although it is actualy 2d but uses a blitting algorythm (which i want) to make it appear 3d

    http://members.lycos.co.uk/csoft/eg.JPG

  4. #4
    Registered User Draco's Avatar
    Join Date
    Apr 2002
    Posts
    463
    I think I understand better now. Something that should give more feel of depth is to have the objects move across the screen with the speed depending on the depth. If you have any good ol' Super Nintendo or Genesis games you can look at, study those for even more ideas.

  5. #5
    Registered User MicroFiend's Avatar
    Join Date
    Nov 2002
    Posts
    80
    ive thought of that idea also, thanx for ur hep.. i guess tho for now itl have to stay 2d..

  6. #6
    Registered User Draco's Avatar
    Join Date
    Apr 2002
    Posts
    463
    You're welcome. The technical name for the doom engine's effect if I remember right is called raycasting, there should be a lot of easily findable information about it.

  7. #7
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Yes DOOM used raycasting and what you are referring to has little or nothing to do with raycasting.


    To determine the x,y screen coords of any object from the 3D coords, here is a simplified version of the projection transformation:

    Let's assume your 3D coords for your object are in camera space.

    screen_x=camera.x*view_plane_dist/camera.z+halfscreen_x;
    screen_y=camera.y*view_plane_dist/camera.z+halfscreen_y;

    For info on DOOM-like raycasting consult Peroxide tutorials 7 and 8 or PXDTUT7 and PXDTUT8 (I think it's 8, maybe 9). Google it and you will find em.

  8. #8
    Banned
    Join Date
    May 2004
    Posts
    129
    Actually bubba, if I am not mistaken, what you are doing IS raycasting. Don't those equations simply find the 2D screen coordinates where the ray that was casted from the camera to a transformed vertex intersects the viewing plane?

    edit

    the way I am used to seeing it (for DirectX coordinate system) is:

    1) transform the vertex (using inverse translation and angles, effectively leaving camera position at origin, but transforming vertex around camera pos to simulate movement/rotation)
    2) screen coord pos = vertexpos * (planedist/vertex.z)
    Last edited by vNvNation; 06-12-2004 at 01:40 PM.

  9. #9
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    No a raycast is much different than that.

    Raycast will divide the ray into itx x and y components.

    Essentially in ortho ray casting if you know the size of each cell then you can find out the stepsize for each component via tangent instead of sin cos.

    cos(theta)=adj/hyp
    sin(theta)=opp/hyp
    tan(theta)=opp/adj

    if you know adj or opp which we do...its the cellsize, then you can find the other.


    This is essentially a projection transform...you are finding the height of the wall by dividing by the distance from the camera, but to equate raycasting with an actual projection transform is not a good habit. They are two fundamentally different approaches. One is fake 3D and one is true 3D.

    Actually in DX there is more going on than that. The clip matrix transforms from camera space to clip space to get the correct value in W.

    Direct3D clip matrix:
    0<=z<=w

    Mclip=
    [zoomx 0 0 0]
    [0 zoomy 0 0]
    [0 0 (f/(f-n) 0]
    [0 0 (nf/(n-f)) 0]

    then:

    screenx=(clipx*resx/2*clipw)+screencenterx;
    screeny=(clipy*resy/2*clipw)+screencentery;

    zclip and wclip can be used for zbuffering and perspective correction.

    But I think we are straying off topic.


    Here is a crappy slow raycast using sin cos:

    Code:
    void Slow2DRaycast(Player &thePlayer)
    {
     
    //Compute casting angle for 60 degree FOV
    float angle=thePlayer.angle-30f;
    if (angle<0.0f) angle+=360.0f;
     
    //Compute angle increment for screen res x
    float angleinc=60.0f/horiz_res_x;
     
    //Ray position
    float rayx=0.0f,rayy=0.0f;
     
    //Ray steps
    float ix=0.0f,iy=0.0f;
     
    //Height of hit wall
    float heightofslice=0.0f;
     
    //Map position intersected by ray
    int mapx=0,mapy=0;
     
    //Color of slice
    int wallcolor=0;
     
    //Floor and ceiling screen y locations
    int floor=0;
    int ceiling=0;
     
    //Cast from 0 to horizontal screen res
    for (int screenx=0;screenx<horiz_res_x;screenx++)
    {
    	 //Set ray origin at player location
    	 rayx=thePlayer.x;
    	 rayy=thePlayer.y;
     
    	 //Compute increments
    	 ix=cos(DEGTORAD(angle));
    	 iy=sin(DEGTORAD(angle));
     
    	 do
    	 {
    		 //Advance ray
    		 rayx+=ix;
    		 rayy+=iy;
     
    		 //Compute ray map coords from ray world coords
    		 int mapx= rayx/CELLSIZE;
    		 int mapy=rayy/CELLSIZE;
     
    		 //keep ray on map - only works on maps that are a power of 2
    		 mapx&=(mapwidth-1);
    		 mapy&=(mapheight-1);
     
    		 //Retrieve value from map at ray intersection
    		 wallcolor=map(mapy*mapwidth+mapx);
     
    		 //Check to see if we hit a wall
    		 if (wallcolor)
    		 {
    			float dx=rayx-thePlayer.x;
    			float dy=rayy-thePlayer.y;
     
    			//Compute actual distance from player
    			//extremely slow - could use cos for distance
    			heightofslice=sqrt((dx*dx)+(dy*dy));
     
    			//Compute ceiling and floor
    			ceiling=centerscreeny-(heightofslice/2.0f);
    			floor=ceiling+heightofslice;
     
    			//Draw the slice
    			VerticalLine(screenx,ceiling,floor,wallcolor);
    		 }
    	 } while (wallcolor==0);
     
    	 //Increment angle and check for angle>360.0f
    	 angle+=angleinc;
    	 if (angle>360.0f) angle-=360.0f;
    }
    }
    Last edited by VirtualAce; 06-12-2004 at 08:51 PM.

  10. #10
    Banned
    Join Date
    May 2004
    Posts
    129
    Okay, after reading that post, I can see a fundamental difference.

    I'm glad you cleared that up for me

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Segfaulting Distance Program
    By radiohead in forum C Programming
    Replies: 2
    Last Post: 01-09-2006, 08:48 PM
  2. Distance Formula in my program..... I need help fast!!!
    By Mackology101 in forum C Programming
    Replies: 3
    Last Post: 09-23-2004, 10:10 PM
  3. Distance Formula Implecations: Urgent!
    By KneeLess in forum C Programming
    Replies: 6
    Last Post: 03-20-2004, 10:52 PM
  4. Fuzzy Logic
    By ygfperson in forum A Brief History of Cprogramming.com
    Replies: 10
    Last Post: 10-13-2002, 04:58 PM
  5. Collision detection algorithm
    By Hannwaas in forum Game Programming
    Replies: 5
    Last Post: 11-30-2001, 01:27 PM