Original Post
Alright, so I am implementing this algorithm. I have a book, Tips and Tricks of the Windows Game Programming Guru's that has some source code. I don't like to just copy/paste. I like working through the math. Anyways, on with the question. The following code is basically copy/paste from the books source CD with name changes. I am working through the math before I recode it my way. Neways, in some of the calculations where we multiply by the slope (startY-endY)/(startX-endX) or the inverse slope, (StartX-EndX)/(StartY-endY) he is adding 0.5. In the code above, all 0.5's are replaced by tempVar. I am assuming 0.5 is added when we are rounding from a double to an int and the 0.5 makes the rounding more accurate. In C++ double to int just loses the decimal information. The + 0.5 essentially rounds for us. Neways, why is it not there for ALL of the places where there is going to be a decimal value? It would make sense to always add 0.5 before casting to integer would it not? I've set tempVar to both 0.5 and 0.0 and run the code, drawing 16 clipped lines every time. I haven't saved the results and done a pixel to pixel comparasin but the images look identical. Any thoughts on the issue would be appreciated. Do you figure his source code is just missing a couple 0.5's?
switch(p1code)
{
case CLIP_REGION_C:
{
break;
}
case CLIP_REGION_N:
{
clipStartY = clipRect->top;
clipStartX = startX + tempVar+(clipRect->top-startY)*(endX-startX)/(endY-startY);
break;
}
case CLIP_REGION_S:
{
clipStartY = clipRect->bottom;
clipStartX = startX + tempVar+(clipRect->bottom-startY)*(endX-startX)/(endY-startY);
break;
}
case CLIP_REGION_W:
{
clipStartX = clipRect->left;
clipStartY = startY + tempVar+(clipRect->left-startX)*(endY-startY)/(endX-startX);
break;
}
case CLIP_REGION_E:
{
clipStartX = clipRect->right;
clipStartY = startY + tempVar+(clipRect->right-startX)*(endY-startY)/(endX-startX);
break;
}
// these cases are more complex, must compute 2 intersections
case CLIP_REGION_NE:
{
// north hline intersection
clipStartY = clipRect->top;
clipStartX = startX + tempVar+(clipRect->top-startY)*(endX-startX)/(endY-startY);
// test if intersection is valid, of so then done, else compute next
if (clipStartX < clipRect->left || clipStartX > clipRect->right)
{
// east vline intersection
clipStartX = clipRect->right;
clipStartY = startY + tempVar+(clipRect->right-startX)*(endY-startY)/(endX-startX);
} // end if
break;
}
case CLIP_REGION_SE:
{
// south hline intersection
clipStartY = clipRect->bottom;
clipStartX = startX + tempVar+(clipRect->bottom-startY)*(endX-startX)/(endY-startY);
// test if intersection is valid, of so then done, else compute next
if (clipStartX < clipRect->left || clipStartX > clipRect->right)
{
// east vline intersection
clipStartX = clipRect->right;
clipStartY = startY + tempVar+(clipRect->right-startX)*(endY-startY)/(endX-startX);
} // end if
break;
}
case CLIP_REGION_NW:
{
// north hline intersection
clipStartY = clipRect->top;
clipStartX = startX + tempVar+(clipRect->top-startY)*(endX-startX)/(endY-startY);
// test if intersection is valid, of so then done, else compute next
if (clipStartX < clipRect->left || clipStartX > clipRect->right)
{
clipStartX = clipRect->left;
clipStartY = startY + tempVar+(clipRect->left-startX)*(endY-startY)/(endX-startX);
} // end if
break;
}
case CLIP_REGION_SW:
{
// south hline intersection
clipStartY = clipRect->bottom;
clipStartX = startX + tempVar+(clipRect->bottom-startY)*(endX-startX)/(endY-startY);
// test if intersection is valid, of so then done, else compute next
if (clipStartX < clipRect->left || clipStartX > clipRect->right)
{
clipStartX = clipRect->left;
clipStartY = startY + tempVar+(clipRect->left-startX)*(endY-startY)/(endX-startX);
} // end if
break;
}
default:
{
break;
}
} // end switch
// determine clip point for p2
switch(p2code)
{
case CLIP_REGION_C:
{
break;
}
case CLIP_REGION_N:
{
clipEndY = clipRect->top;
clipEndX = endX + (clipRect->top-endY)*(startX-endX)/(startY-endY);
break;
}
case CLIP_REGION_S:
{
clipEndY = clipRect->bottom;
clipEndX = endX + (clipRect->bottom-endY)*(startX-endX)/(startY-endY);
break;
}
case CLIP_REGION_W:
{
clipEndX = clipRect->left;
clipEndY = endY + (clipRect->left-endX)*(startY-endY)/(startX-endX);
break;
}
case CLIP_REGION_E:
{
clipEndX = clipRect->right;
clipEndY = endY + (clipRect->right-endX)*(startY-endY)/(startX-endX);
break;
}
// these cases are more complex, must compute 2 intersections
case CLIP_REGION_NE:
{
// north hline intersection
clipEndY = clipRect->top;
clipEndX = endX + tempVar+(clipRect->top-endY)*(startX-endX)/(startY-endY);
// test if intersection is valid, of so then done, else compute next
if (clipEndX < clipRect->left || clipEndX > clipRect->right)
{
// east vline intersection
clipEndX = clipRect->right;
clipEndY = endY + tempVar+(clipRect->right-endX)*(startY-endY)/(startX-endX);
} // end if
break;
}
case CLIP_REGION_SE:
{
// south hline intersection
clipEndY = clipRect->bottom;
clipEndX = endX + tempVar+(clipRect->bottom-endY)*(startX-endX)/(startY-endY);
// test if intersection is valid, of so then done, else compute next
if (clipEndX < clipRect->left || clipEndX > clipRect->right)
{
// east vline intersection
clipEndX = clipRect->right;
clipEndY = endY + tempVar+(clipRect->right-endX)*(startY-endY)/(startX-endX);
} // end if
break;
}
case CLIP_REGION_NW:
{
// north hline intersection
clipEndY = clipRect->top;
clipEndX = endX + tempVar+(clipRect->top-endY)*(startX-endX)/(startY-endY);
// test if intersection is valid, of so then done, else compute next
if (clipEndX < clipRect->left || clipEndX > clipRect->right)
{
clipEndX = clipRect->left;
clipEndY = endY + tempVar+(clipRect->left-endX)*(startY-endY)/(startX-endX);
} // end if
break;
}
case CLIP_REGION_SW:
{
// south hline intersection
clipEndY = clipRect->bottom;
clipEndX = endX + tempVar+(clipRect->bottom-endY)*(startX-endX)/(startY-endY);
// test if intersection is valid, of so then done, else compute next
if (clipEndX < clipRect->left || clipEndX > clipRect->right)
{
clipEndX = clipRect->left;
clipEndY = endY + tempVar+(clipRect->left-endX)*(startY-endY)/(startX-endX);
} // end if
break;
}
default:
{
break;
}
}