2012-12-17 5 views
2

플랫 - 탑 삼각형과 플랫 - 톱 삼각형을 채우기 위해 두 가지 함수를 작성하려고합니다. 그러나 큰 부분에 대해서는 균열이 여전히 옆면을 공유하는 인접한 삼각형 사이에서 보입니다. 나는 각 단계마다 새로운 왼쪽 및 오른쪽 한계를 계산하여 라인별로 삼각형을 래스터 링하는 보간 기법을 사용합니다. 이것의 대부분은 코드에서 설명하지만, 여기에 (평평한 바닥에 대한) 일반적인 생각입니다 :트라이앵글 래스터 화 문제

1) DY (높이 찾기)

2) 마구/DX (경사 찾기)로부터 각 바닥 점

3) 위에서 포인트는 시작 행 (바닥 (상부 지점))로 이동 한 초기 X 스타트 및 X-단부 옆 라인

4) 이동 좌표를 찾은 새로운 시작을 계산할 끝 한계 ...

균열은 상단/하단 조인이 아닌 측면에서 결합하는 삼각형 사이에서만 볼 수 있습니다. 나는 너무 오랫동안 나는 이제는 무엇을 해야할지 모르겠다. 나는 논리가 단단하다고 생각한다. 아마도 어떤 균열은 부동 소수점 오류 때문일 것이다. 나는 약간의 피드백에 정말로 감사 할 것입니다.

typedef unsigned int uint32; 

void Line(uint32 y, uint32 x_left, uint32 x_right); //Draws a horizontal line 

struct vector2 
{ 
    float x,y; 
}; 

//-------------------------------------------------------------------------------- 
//  Draws a flat bottom triangle from top to bottom 
//-------------------------------------------------------------------------------- 
void Draw_Bottom_Tri_SOLID(Vector2 p0, Vector2 p1, Vector2 p2) 
{ 
    //Point order: 
    //Bottom left: p0 
    //Bottom right: p1 
    //Top point:  p2 

    //calculate dy 
    float dy = p2.y - p0.y; 

    //dx/dy for the left and right edges 
    float dxdy_left = (p0.x - p2.x)/dy; 
    float dxdy_right = (p1.x - p2.x)/dy; 

    //Since we start the raster process at floor(p2.y) 
    //we need to shift the initial x start and x end 
    //postions along by this factor: 
    float y_bump = p2.y - floor(p2.y); 

    //Initial start and end x values 
    float xs = p2.x + dxdy_left*y_bump; //x left (start) 
    float xe = p2.x + dxdy_right*y_bump; //x right (end) 

    uint32 yb = uint32(p0.y) + 1;   //y bottom, +1 for top left fill convention 
    uint32 yt = uint32(p2.y);    //y top, use casting instead of std::floor 

    //Draw lines 
    for (uint32 i = yt; i >= yb; i--) 
    { 
     //Set left and right limits, use casting instead of std::floor 
     uint32 left = uint32(xs) + 1;  //+1 for top left fill convention 
     uint32 right = uint32(xe); 

     //Draw line, can also be std::fill or simply a for loop. 
     Line(i, left, right); 

     //Increment limits 
     xs += dxdy_left; 
     xe += dxdy_right; 
    } 

} //End: Draw_Bottom_Tri_SOLID() 


//-------------------------------------------------------------------------------- 
//  Draws a flat top triangle from bottom to top 
//-------------------------------------------------------------------------------- 
void Draw_Top_Tri_SOLID(Vector2 p0, Vector2 p1, Vector2 p2) 
{ 
    //Point order: 
    //Top left:  p0 
    //Top right:  p1 
    //Bottom point: p2 

    //calculate dy (height) 
    float dy = p0.y - p2.y; 

    //dx/dy for the left and right edges 
    float dxdy_left = (p0.x - p2.x)/dy; 
    float dxdy_right = (p1.x - p2.x)/dy; 

    //Find shifting factor 
    float y_bump = ceil(p2.y) - p2.y; 

    //Initial start and end x values 
    float xs = p2.x + dxdy_left*y_bump; //x left (start) 
    float xe = p2.x + dxdy_right*y_bump; //x right (end) 

    uint32 yb = uint32(p2.y) + 1;   //y bottom, +1 for top left fill convention 
    uint32 yt = uint32(p0.y) ;    //y top 

    //Draw lines 
    for (uint32 i = yb; i <= yt; i++) 
    { 
     //Set left and right limits 
     uint32 left = uint32(xs) + 1;  //+1 for top left fill convention 
     uint32 right = uint32(xe); 

     //Draw line, can be std::fill or simply a for loop. 
     Line(i, left, right); 

     //Increment limits 
     xs += dxdy_left; 
     xe += dxdy_right; 
    } 


} //End: Draw_Top_Tri_SOLID() 

답변

1

플로트 오류가 발생할 것으로 보입니다. 인접한 두 모서리의 값이 같아야합니다. 이런 식으로 누적 할 때 float 값으로 수정하는 것은 약간 까다로울 수 있습니다. 필요에 따라 몇 가지 옵션이 있습니다.

  • 대신 고정 점을 사용하십시오. 이것은 또한 더 빠를 것입니다.
  • 오버 드로우가 문제가되지 않는다면 단순히 float 값에 충분히 큰 엡실론을 추가하면됩니다.
관련 문제