GPWiki.org
GPWiki.org
It is currently Sat May 25, 2013 8:24 pm

All times are UTC




Post new topic Reply to topic  [ 18 posts ] 
Author Message
PostPosted: Thu Aug 02, 2012 11:49 am 
Rookie

Joined: Thu Aug 02, 2012 11:42 am
Posts: 4
Hi Guys, my friend sent me a program to do with Ray Casting, There is a function in the program called void view::RayCast that needs implementing, the function has copious amounts of comments for guidenice and has separted the function into 5 key steps. The steps describe the mathematcis behind it i've had a go but cant seem to get it. I can attach a screen shot of what the outcome should look like.

If there is anyone out there who is capable of completing this function it would mean a lot to me!! :)
Just send me your email address and I'd be happy to send to you so you can have a crack at it!




Thanks guys


Top
 Profile  
 
PostPosted: Thu Aug 02, 2012 1:22 pm 
Harmlessness does no harm
User avatar

Joined: Tue Sep 14, 2004 8:37 pm
Posts: 3810
Location: Ferriday, LA, US
SD9000 wrote:
Just send me your email address and I'd be happy to send to you so you can have a crack at it!

Not trying to be rude here, but that's not going to work.

Best thing you could do is post the code for the function you are trying to complete, so that someone can help fill in the blanks. :)

_________________
What most people don't understand about "enlightenment" is that it is not an end-goal; but where you find yourself just before taking a new "first step."


Top
 Profile  
 
PostPosted: Fri Aug 03, 2012 11:32 pm 
Lord of Cheesecakes

Joined: Sun Jun 24, 2012 12:49 am
Posts: 342
Subtle spam... maybe.

_________________
What most people don't understand is what I like to explain as a thing that I understand.


Top
 Profile  
 
PostPosted: Sat Aug 04, 2012 2:08 am 
Harmlessness does no harm
User avatar

Joined: Tue Sep 14, 2004 8:37 pm
Posts: 3810
Location: Ferriday, LA, US
Possibly. We do have users who seem to post innocent topics/replies, but later on add signatures to their accounts with spam links. Sneaky stealth spammers.

In either case, I wouldn't suggest anyone send the user their email address. Certainly not for this.

_________________
What most people don't understand about "enlightenment" is that it is not an end-goal; but where you find yourself just before taking a new "first step."


Top
 Profile  
 
PostPosted: Sat Aug 04, 2012 8:10 pm 
lol sorrry guys im fairly new to this ermm yeah i can post the code so here it is -
Code:
oid view::RayCast( float fRayStartX, float fRayStartY, unsigned int uViewingAngle )
{
  float fDX, fDY; // General purpose change in X and Y variables.
  int nGridX = 0; // The map array position of the next square intersecting the ray
  int nGridY = 0; // The map array position of the next square intersecting the ray
  int nTextIndex = 0; // The index into the relevant column of the texture map
 

  // Set the column angle to the angle of first ray with respect to the view.
  unsigned int nColumnAngle = m_nViewColAngStart;

  // Loop through all columns of pixels in viewport:
  for (int nColumn = 0; nColumn < m_nViewWidth; nColumn++)
  {
      // ***************************************************************************************
      // STEP 1: Use the starting position of the ray (fRayStartX, fRayStartY), the viewing
      // angle (uViewingAngle) and the column angle for this pixel column (nColumnAngle) to
      // calculate the end position (fRayEndX, fRayEndY) of a ray 1024 units long.
      // ***************************************************************************************

      // Avoid the situation where the column angle is 0
      if (nColumnAngle == 0) { nColumnAngle++; }

      // Calculate the angle of ray in with respect to the world
      // Ensure the angle is in the range of 0-4096


      // Look up the sin and cos of the ray angle in the relevant arrays


      // Rotate endpoint of a ray 1024 units long by the viewing angle:


      // Create variables to hold the ray's current position (fRayX, fRayY) and initialise them
      // to the start position.
      float fRayX = fRayStartX;
      float fRayY = fRayStartY;

      // ***************************************************************************************
      // STEP 2: Using the endpoint of the ray (fRayEndX, fRayEndY) calculate the change in
      // x and y (fDRayX and fDRayY) along the length of the ray. Then use these values to calculate
      // the slope (fSlope) of the ray (which is also m in the line equation y = mx + c).
      // ***************************************************************************************

      // Find difference in x,y coordinates along ray:


      // Make sure fDRayX is never exactly 0 otherwise you could get divide by zero errors


      // Calculate fSlope and make sure that is never exactly 0 either


      // Cast ray from grid line to grid line until the loop breaks out
      while( true )
      {
         // ***********************************************************************************
         // STEP 3: Calculate the co-ordinates of the intersection points between the ray and
         // the next map grid line in both the x and y axis: (fXCrossX, fXCrossY) for the x axis
         // and (fYCrossX, fYCrossY) for the y axis.
         // ***********************************************************************************

         float fXCrossX, fXCrossY; // Intersection point between the ray and the next grid line in the x axis

         // The sign of fDRayX tells you the direction of the ray in the x axis which will help you
         // to calculate fXCrossX. Once you have fXCrossX you can calculate fXCrossY based on the
         // fact that the change in x position (fXCrossX - fRayX) and the slope (fSlope) allows
         // you to calculate the change in the y position (fXCrossY - fRayY) for the movement to
         // the next x gridline. i.e. dy = m * dx

         // Check sign of fDRayX and calculate fXCrossX


         // Calculate fXCrossY


         float fYCrossX, fYCrossY; // Intersection point between the ray and the next grid line in the y axis

         // The sign of fDRayY tells you the direction of the ray in the y axis which will help you
         // to calculate fYCrossX. Once you have fYCrossX you can calculate fYCrossY based on the
         // fact that the change in y position (fXCrossY - fRayY) and the slope (fSlope) allows
         // you to calculate the change in the x position (fYCrossY - fRayX) for the movement to
         // the next y gridline. i.e. dx = dy / m

         // Check sign of fDRayY and calculate fXCrossX


         // Calculate fXCrossX


         // ***********************************************************************************
         // STEP 4: Use Pythagoras to calculate the relative distance to each of the grid line
         // intersection points(dXDistSq and dYDistSq) No need to use square roots here!
         // Double precision is necessary though.
         // ***********************************************************************************

         // Calculate dXDistSq
         double dXDistSq = 0.0;

         // Calculate dYDistSq
         double dYDistSq = 0.0;

         // ***********************************************************************************
         // STEP 5: Depending on which grid line is closer, update the ray position and
         // calcuate the map grid position (nGridX, nGridY). Check this map position to for an
         // obstruction and break out of the while loop if there is.
         // ***********************************************************************************

         // If x grid line is closer...
         if (dXDistSq < dYDistSq) {

            // Calculate maze grid coordinates of square nGridX and nGridY


            // Move current ray position to ray intersection point


            // Is there a maze cube here? If so, stop looping:
            if ( m_pViewWorld->m_pWorldTextures[nGridX][nGridY] != NULL)
               break;


         } else { // If y grid line is closer:

            // Calculate maze grid coordinates of square nGridX and nGridY


            // Move current ray position to ray intersection point


            // Is there a maze cube here? If so, stop looping:
            if ( m_pViewWorld->m_pWorldTextures[nGridX][nGridY] != NULL)
               break;


         }// End of If Else

      }// End of infinate for


Last edited by Mugai on Sun Aug 05, 2012 2:03 am, edited 1 time in total.
Added code tags


Top
  
 
PostPosted: Sat Aug 04, 2012 8:13 pm 
Rookie

Joined: Thu Aug 02, 2012 11:42 am
Posts: 4
just realised that i didnt sign in when i copied the code into this forum, sorry guys but that was me who posted that function, if anyone out there can do this it would help me out alot :)


Top
 Profile  
 
PostPosted: Sun Aug 05, 2012 8:36 am 
Bytewise

Joined: Sun Oct 16, 2011 3:09 pm
Posts: 277
Location: Here (where else?)
I don't know about you, but I don't like to do other peoples home work (even if it is not for school, although this looks very school-ish).
Solving other peoples problems is called 'work', and I already have a job, thank you very much.

I am fine with giving you advice or giving help on a specific point in the process, but you have to explain at what point you are stuck (and what you are having trouble with). You also have to work out the details in your code.

Like most forums, we are helping each other by discussing problems and alternatives, not by bluntly giving solutions, as nobody learns from that.



Thus, if doing a few posts is the only effort you have done so far in solving this, my suggestion is to look into how to actually crack this problem.
If you have looked at solving it, and are stuck at the beginning, please describe what you have considered as next step, and why do you think it is not working.

_________________
My project: Messing about in FreeRCT, dev blog, and IRC #freerct at oftc.net


Top
 Profile  
 
PostPosted: Mon Aug 06, 2012 10:55 am 
Rookie

Joined: Thu Aug 02, 2012 11:42 am
Posts: 4
Hi Alberth I understand what you're however i actually put the extra comments in to make it clear for other people to understand, this is a large a program and i've coded most of it and im stuck on this last 10%. I've looked on online resources but there isnt much that similar to my problem, I think i've hit the wall on this one and dont wanna stop after being sooo close to completion this is why i have posted it on here aswell as trying my self

hope you understand :)


Top
 Profile  
 
PostPosted: Mon Aug 06, 2012 11:53 am 
Funky Monkey

Joined: Thu Sep 09, 2004 1:17 pm
Posts: 1553
Location: burrowed
This might help you:

http://tom.cs.byu.edu/~455/3DDDA.pdf

I haven't fully grasped the math behind raycasting so i cannot help much further than that.

_________________
Long pork is people!

wzl's burrow


Top
 Profile  
 
PostPosted: Mon Aug 06, 2012 5:45 pm 
Bytewise

Joined: Sun Oct 16, 2011 3:09 pm
Posts: 277
Location: Here (where else?)
So you can write comments with details like "make this 1024 units long", or "must be between 0 and 4096", or "column angle 0 is bad", or "fdrayx must not be 0", yet you have no idea what to do at each point?

That's very weird.
The comments look asif they are written by someone that has a clear idea of what to put where, and what problems you are going to run into when you code it.


But anyway, do you know what math calculation to perform at each point?
That is really the first step, imho.

_________________
My project: Messing about in FreeRCT, dev blog, and IRC #freerct at oftc.net


Top
 Profile  
 
PostPosted: Tue Aug 07, 2012 11:50 am 
Rookie

Joined: Thu Aug 02, 2012 11:42 am
Posts: 4
Hi, Yeah thats causing me the problems is the maths! i've read some stuff on the web but its getting that maths into code, is whats troubling me


Top
 Profile  
 
PostPosted: Tue Aug 07, 2012 5:17 pm 
Bytewise

Joined: Sun Oct 16, 2011 3:09 pm
Posts: 277
Location: Here (where else?)
Forget about coding completely until you know exactly what to code. You seem very much focused on the code, but that just distracts you from solving the problem of what to code (only when you know what to code, you can start solving the puzzle of how to code it).

I'd say first write down the formulas that you need to compute at each step.

If you cannot do that, try to find where you get stuck exactly and why you see no other ways to try. Currently you are not giving any information at all, and without it, I see no way to give you much further help. We need MUCH more details on what exactly is the problem you are struggling with. Not the entire problem (you've told that already), but what it is that stops you from making the next step.
(You sort of gave us a complete book "this is what I need to solve". We need you to pinpoint a letter of a word at a specific page, and explain why that letter is a problem, and why you cannot get around that letter.)

_________________
My project: Messing about in FreeRCT, dev blog, and IRC #freerct at oftc.net


Top
 Profile  
 
PostPosted: Fri Aug 10, 2012 3:05 pm 
Hi Alberth

ok the first step is to Calculate the position of an arbitrary "end point" 1024 units along the length of the ray.

To calculate (fRayEndX, fRayEndY) you need:
Ray Angle (θ)
Ray Length (1024)
Ray Start (fRayStartX, fRayStartY)

so ray angle = column angle + viewing angle.
I need to calculate the endpoint which is done in these steps-:
A ray of length 1024 rotated by θ
sin θ = O / H (oposite divided by hypotenuse)
cos θ = A / H (Adjacent divided by hypotenuse)
Then add fRayStart
Note:
Current ray position is (fRayX, fRayY)
This is the one that changes, not fRayStart


Top
  
 
PostPosted: Fri Aug 10, 2012 6:29 pm 
Bytewise

Joined: Sun Oct 16, 2011 3:09 pm
Posts: 277
Location: Here (where else?)
That sounds good to me; A and O are your changes in x and y, so you may need to rewrite your formulas to
O = sin theta * H
A = cos theta * H

_________________
My project: Messing about in FreeRCT, dev blog, and IRC #freerct at oftc.net


Top
 Profile  
 
PostPosted: Sun Aug 12, 2012 11:26 am 
Cool man :)

im on step 2 this is what i got

// ***************************************************************************************
// STEP 2: Using the endpoint of the ray (fRayEndX, fRayEndY) calculate the change in
// x and y (fDRayX and fDRayY) along the length of the ray. Then use these values to calculate
// the slope (fSlope) of the ray (which is also m in the line equation y = mx + c).
// ***************************************************************************************

// Find difference in x,y coordinates along ray:
float fDRayX = fRayEndX - fRayX;
float fDRayY = fRayEndY - fRayY;

// Make sure fDRayX is never exactly 0 otherwise you could get divide by zero errors
// Calculate fSlope and make sure that is never exactly 0 either
while ( fDRayX != 0)
{
float fSlope = fDRayY / fDRayX;
/*float c = fRayX - m*fRayY;*/

/*float fSlope = m * fRayX + c;*/

}

How do i make sure that fSlope is never excatly 0?


Top
  
 
PostPosted: Sun Aug 12, 2012 12:28 pm 
Bytewise

Joined: Sun Oct 16, 2011 3:09 pm
Posts: 277
Location: Here (where else?)
Quote:
How do i make sure that fSlope is never excatly 0?
Is that even feasible? y = c seems a perfectly feasible solution to me, namely all lines parallel to the X-axis.

I somewhat fail to understand what step 2 is about. Step 1 computes a point 1024 units from your start point in some direction. In step 2, you compute an intersection betwoon both points?
Why not use the direction from step 1, and compute the distance to your intersection from the start point instead? That seems much easier to me.

The concept that you may be missing here is that the point (fRayStartX + t*cos theta, fRayStartY + t*sin theta) is actually a point on your line at distance t. t == 0 gives you the starting point, At t == 1024, you'll end up at your (fRayEndX, fRayEndY).

Intersection is the point where the X and Y coordinates are on both the grid line and on your line, that is, for a gridline X = C, you need to solve t from "fRayStartX + t*cos theta = C" (with some simple rewriting of the formula to end up with the form t = ...). Then use 't' in fRayStartY + t*sin theta to get the corresponding Y coordinate.
A similar approach works for grid lines Y = C. You'll need special cases for lines parallel to X and to Y axes, but you'll need them no matter how you solve it.

_________________
My project: Messing about in FreeRCT, dev blog, and IRC #freerct at oftc.net


Top
 Profile  
 
PostPosted: Mon Aug 13, 2012 7:11 am 
Hi Alberth

here is the completed function but for some reason when i run the program nothing is being outputted on the screen

void view::RayCast( float fRayStartX, float fRayStartY, unsigned int uViewingAngle )
{
float fDX, fDY; // General purpose change in X and Y variables.
int nGridX = 0; // The map array position of the next square intersecting the ray
int nGridY = 0; // The map array position of the next square intersecting the ray
int nTextIndex = 0; // The index into the relevant column of the texture map

// Set the column angle to the angle of first ray with respect to the view.
unsigned int nColumnAngle = m_nViewColAngStart;

// Loop through all columns of pixels in viewport:
for (int nColumn = 0; nColumn < m_nViewWidth; nColumn++)
{
// ***************************************************************************************
// STEP 1: Use the starting position of the ray (fRayStartX, fRayStartY), the viewing
// angle (uViewingAngle) and the column angle for this pixel column (nColumnAngle) to
// calculate the end position (fRayEndX, fRayEndY) of a ray 1024 units long.
// ***************************************************************************************

float fRayEndX;
float fRayEndY;
int RayLength = 1024;

// Avoid the situation where the column angle is 0
if (nColumnAngle == 0) { nColumnAngle++; }



// Calculate the angle of ray in with respect to the world
// Ensure the angle is in the range of 0-4096
int rayAngle = nColumnAngle + uViewingAngle;

if(rayAngle < 0)
{
rayAngle = 0;
}
else

if (rayAngle > 4096)
{
rayAngle = 4096;
}

// Look up the sin and cos of the ray angle in the relevant arrays


fSinArray[rayAngle] = sin(rayAngle*DEG_TO_RAD);
fCosArray[rayAngle] = cos(rayAngle*DEG_TO_RAD);



// Rotate endpoint of a ray 1024 units long by the viewing angle:
fRayEndX = (fSinArray[uViewingAngle] * RayLength) + fRayStartX;
fRayEndY = (fCosArray[uViewingAngle] * RayLength) + fRayStartY;




// Create variables to hold the ray's current position (fRayX, fRayY) and initialise them
// to the start position.
float fRayX = fRayStartX;
float fRayY = fRayStartY;



// ***************************************************************************************
// STEP 2: Using the endpoint of the ray (fRayEndX, fRayEndY) calculate the change in
// x and y (fDRayX and fDRayY) along the length of the ray. Then use these values to calculate
// the slope (fSlope) of the ray (which is also m in the line equation y = mx + c).
// ***************************************************************************************

// Find difference in x,y coordinates along ray:
float fDRayX = fRayEndX - fRayX;
float fDRayY = fRayEndY - fRayY;
/*float fSlope;*/

// Make sure fDRayX is never exactly 0 otherwise you could get divide by zero errors
// Calculate fSlope and make sure that is never exactly 0 either

if(fDRayX == 0)
{
fDRayX++;
}


float fSlope = (fDRayY / fDRayX) - RayLength;

if (fSlope == 0)
{
fSlope++;
}











// Cast ray from grid line to grid line until the loop breaks out
while( true )
{
// ***********************************************************************************
// STEP 3: Calculate the co-ordinates of the intersection points between the ray and
// the next map grid line in both the x and y axis: (fXCrossX, fXCrossY) for the x axis
// and (fYCrossX, fYCrossY) for the y axis.
// ***********************************************************************************

float fXCrossX, fXCrossY; // Intersection point between the ray and the next grid line in the x axis

// The sign of fDRayX tells you the direction of the ray in the x axis which will help you
// to calculate fXCrossX. Once you have fXCrossX you can calculate fXCrossY based on the
// fact that the change in x position (fXCrossX - fRayX) and the slope (fSlope) allows
// you to calculate the change in the y position (fXCrossY - fRayY) for the movement to
// the next x gridline. i.e. dy = m * dx

// Check sign of fDRayX and calculate fXCrossX

if ( fDRayX < 0)
{
fXCrossX = ((fDRayX / 128) *128 -1) /** fCosArray[rayAngle]*/;
}
else
fXCrossX = ((fDRayX / 128) *128 + 128) /** fCosArray[rayAngle]*/;

// Calculate fXCrossY

fXCrossY = fRayY + fSlope * ( fXCrossX - fRayX);


float fYCrossX, fYCrossY; // Intersection point between the ray and the next grid line in the y axis

// The sign of fDRayY tells you the direction of the ray in the y axis which will help you
// to calculate fYCrossX. Once you have fYCrossX you can calculate fYCrossY based on the
// fact that the change in y position (fXCrossY - fRayY) and the slope (fSlope) allows
// you to calculate the change in the x position (fYCrossY - fRayX) for the movement to
// the next y gridline. i.e. dx = dy / m

// Check sign of fDRayY and calculate fYCrossY

if ( fDRayY < 0)
{
fYCrossY = ((fDRayY / 128) * 128 -1)/** fCosArray[rayAngle]*/;
}
else
fYCrossY =((fDRayY / 128) * 128 + 128)/** fCosArray[rayAngle]*/;


// Calculate fYCrossX

fYCrossX = fRayX + ( fYCrossY - fRayY) / fSlope;


// ***********************************************************************************
// STEP 4: Use Pythagoras to calculate the relative distance to each of the grid line
// intersection points(dXDistSq and dYDistSq) No need to use square roots here!
// Double precision is necessary though.
// ***********************************************************************************

// Calculate dXDistSq
float hypX = fXCrossX - fRayX;
float hypY = fYCrossY - fRayY;
float dx = fSinArray[rayAngle] * hypX;
float dy = fCosArray[rayAngle] * hypY;



double dXDistSq = dx * dx;

// Calculate dYDistSq
double dYDistSq = dy * dy;

// ***********************************************************************************
// STEP 5: Depending on which grid line is closer, update the ray position and
// calcuate the map grid position (nGridX, nGridY). Check this map position to for an
// obstruction and break out of the while loop if there is.
// ***********************************************************************************

// If x grid line is closer...
if (dXDistSq < dYDistSq)
{

// Calculate maze grid coordinates of square nGridX and nGridY
nGridX = fXCrossX / 128;
nGridY = fXCrossY / 128;

// Move current ray position to ray intersection point
fRayX = fXCrossX;
fRayY = fXCrossY;

nTextIndex = (int)fXCrossY % 128;

// Is there a maze cube here? If so, stop looping:
if ( m_pViewWorld->m_pWorldTextures[nGridX][nGridY] != NULL)
break;


} else { // If y grid line is closer:

// Calculate maze grid coordinates of square nGridX and nGridY

nGridX = fXCrossX / 128;
nGridY = fXCrossY / 128;

// Move current ray position to ray intersection point
fRayX = fXCrossX;
fRayY = fYCrossY;

nTextIndex = (int) fXCrossX % 128;

// Is there a maze cube here? If so, stop looping:
if ( m_pViewWorld->m_pWorldTextures[nGridX][nGridY] != NULL)
break;


}// End of If Else

}// End of infinate for


Top
  
 
PostPosted: Tue Aug 14, 2012 5:21 pm 
Bytewise

Joined: Sun Oct 16, 2011 3:09 pm
Posts: 277
Location: Here (where else?)
Nice!

_________________
My project: Messing about in FreeRCT, dev blog, and IRC #freerct at oftc.net


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 18 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 4 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group