void Trace_Cercle( SDL_Surface* ecran, SDL_Rect C, int R, Couleur couleur )
{
    float Theta;
    SDL_Rect M;

    for(Theta=0 ; Theta <= 2*M_PI; Theta = Theta + M_PI/180)
    {
        M.x = C.x + R*cos(Theta);
        M.y = C.y + R*sin(Theta);
        Trace_Point( ecran, M, couleur );
    }
}
void Trace_Segment( SDL_Surface* ecran, SDL_Rect A, SDL_Rect B, Couleur couleur )
{
    SDL_Rect M;
    float a, b;

    if( A.x == B.x)
    {
        M.x = A.x;
        for(M.y=A.y; M.y<=B.y; M.y++)
            Trace_Point(ecran, M, couleur);
        for(M.y=A.y; M.y>=B.y; M.y--)
            Trace_Point(ecran, M, couleur);
    }
    else
    {
        if( A.y == B.y)
        {
            M.y = A.y;
            for(M.x=A.x; M.x<=B.x; M.x++)
                Trace_Point(ecran, M, couleur);
            for(M.x=A.x; M.x>=B.x; M.x--)
                Trace_Point(ecran, M, couleur);
        }
        else
        {
            a = (float)(B.y-A.y)/(B.x-A.x);
            b = A.y - a*A.x;
            for(M.x=A.x; M.x<=B.x; M.x++)
            {
                M.y = a*M.x + b;
                Trace_Point(ecran, M, couleur);
            }
            for(M.x=A.x; M.x>=B.x; M.x--)
            {
                M.y = a*M.x + b;
                Trace_Point(ecran, M, couleur);
            }
            for(M.y=A.y; M.y<=B.y; M.y++)
            {
                M.x = (M.y-b)/a;
                Trace_Point(ecran, M, couleur);
            }
            for(M.y=A.y; M.y>=B.y; M.y--)
            {
                M.x = (M.y-b)/a;
                Trace_Point(ecran, M, couleur);
            }
        }
    }
}
//---------------------------------------------------------
void CVisibility_BASE::Set_Visibility(CSG_Grid *pDTM, CSG_Grid *pVisibility, int x_Pos, int y_Pos, double z_Pos, double dHeight, int iMethod)
{
    double		Exaggeration	= 1.0;

    double		aziDTM, decDTM,
                aziSrc, decSrc,
                d, dx, dy, dz;


    for(int y=0; y<pDTM->Get_NY() && SG_UI_Process_Set_Progress(y, pDTM->Get_NY()); y++)
    {
        for(int x=0; x<pDTM->Get_NX(); x++)
        {
            if( pDTM->is_NoData(x, y) )
            {
                pVisibility->Set_NoData(x, y);
            }
            else
            {
                dx		= x_Pos - x;
                dy		= y_Pos - y;
                dz		= z_Pos - pDTM->asDouble(x, y);

                //-----------------------------------------
                if( Trace_Point(pDTM, x, y, dx, dy, dz) )
                {
                    switch( iMethod )
                    {
                    case 0:		// Visibility
                        pVisibility->Set_Value(x, y, 1);
                        break;

                    case 1:		// Shade
                        pDTM->Get_Gradient(x, y, decDTM, aziDTM);
                        decDTM	= M_PI_090 - atan(Exaggeration * tan(decDTM));

                        decSrc	= atan2(dz, sqrt(dx*dx + dy*dy));
                        aziSrc	= atan2(dx, dy);

                        d		= acos(sin(decDTM) * sin(decSrc) + cos(decDTM) * cos(decSrc) * cos(aziDTM - aziSrc));

                        if( d > M_PI_090 )
                            d = M_PI_090;

                        if( pVisibility->asDouble(x, y) > d )
                            pVisibility->Set_Value(x, y, d);
                        break;

                    case 2:		// Distance
                        d		= pDTM->Get_Cellsize() * sqrt(dx*dx + dy*dy);

                        if( pVisibility->is_NoData(x, y) || pVisibility->asDouble(x, y) > d )
                            pVisibility->Set_Value(x, y, d);
                        break;

                    case 3:		// Size
                        if( (d = pDTM->Get_Cellsize() * sqrt(dx*dx + dy*dy)) > 0.0 )
                        {
                            d	= atan2(dHeight, d);
                            if( pVisibility->is_NoData(x, y) || pVisibility->asDouble(x, y) < d )
                                pVisibility->Set_Value(x, y, d);
                        }
                        break;
                    }
                }
            }
        }
    }

    return;
}