递进网格算法绘制等高线

/* generates contours using marching squares */

/* region size */

#define X_MAX 1.0 
#define Y_MAX 1.0 
#define X_MIN -1.0 
#define Y_MIN -1.0

/* number of cells */

#define N_X 50 
#define N_Y 50

/* contour value */

#define THRESHOLD 0.0

#include 
<GL/glut.h>

void display()
{
   
double f(double,double);
   
int cell(doubledoubledoubledouble);
   
void lines(intintintdoubledoubledoubledouble);

   
double data[N_X][N_Y];
   
int i,j;
   
int c;

   glClear(GL_COLOR_BUFFER_BIT);
/* form data array from function */

    
for(i=0;i<N_X;i++for (j=0;j<N_Y;j++)
       data[i][j]
=f(X_MIN+i*(X_MAX-(X_MIN))/(N_X-1.0), Y_MIN+j*(Y_MAX-(Y_MIN))/(N_Y-1.0));

    
/* process each cell */

    
for(i=0;i<N_X;i++for (j=0;j<N_Y;j++)
    {
       c
=cell(data[i][j], data[i+1][j], data[i+1][j+1], data[i][j+1]);
       lines(c,i,j,data[i][j], data[i
+1][j], data[i+1][j+1], data[i][j+1]);
    }
    glFlush();
}

/* define function f(x,y)      */

double f(double x, double y)
{

   
double a=0.49, b=0.5;

   
/* Ovals of Cassini  */

   
return (x*x+y*y+a*a)*(x*x+y*y+a*a)-4*a*a*x*x-b*b*b*b;
}


/* define cell vertices */

int cell(double a, double b, double c , double d)
{
    
int n=0;
    
if(a>THRESHOLD) n+=1;
    
if(b>THRESHOLD) n+=8;
    
if(c>THRESHOLD) n+=4;
    
if(d>THRESHOLD) n+=2;
    
return n;
}


/* draw line segments for each case */

void lines(int num, int i, int j, double a, double b, double c, double d)
{
     
void draw_one(intintintdoubledoubledoubledouble);
     
void draw_adjacent(intintintdoubledoubledoubledouble);
     
void draw_opposite(intintintdoubledoubledoubledouble);
     
switch(num)
     {
     
case 1case 2case 4case 7case 8case 11case 13case 14:
        draw_one(num, i,j,a,b,c,d);
        
break;
     
case 3case 6case 9case 12:
        draw_adjacent(num,i,j,a,b,c,d);
        
break;
     
case 5case 10:
        draw_opposite(num, i,j,a,b,c,d);
        
break;
     
case 0case 15break;
     }
}

void draw_one(int num, int i, int j, double a, double b, double c, double d)
{
  
double x1, y1, x2, y2;
  
double ox, oy;
  
double dx, dy;
  dx
=(X_MAX-(X_MIN))/(N_X-1.0);
  dy
=(Y_MAX-(Y_MIN))/(N_Y-1.0);
  ox
=X_MIN+i*(X_MAX-(X_MIN))/(N_X-1.0);
  oy
=Y_MIN+j*(Y_MAX-(Y_MIN))/(N_Y-1.0);
    
switch(num)
    {
    
case 1case 14:
      x1
=ox;
      y1
=oy+dy*(THRESHOLD-a)/(d-a);
      x2
=ox+dx*(THRESHOLD-a)/(b-a);
      y2
=oy;
      
break;
    
case 2case 13:
      x1
=ox;
      y1
=oy+dy*(THRESHOLD-a)/(d-a);
      x2
=ox+dx*(THRESHOLD-d)/(c-d);
      y2
=oy+dy;
      
break;
    
case 4case 11:
      x1
=ox+dx*(THRESHOLD-d)/(c-d);
      y1
=oy+dy;
      x2
=ox+dx;
      y2
=oy+dy*(THRESHOLD-b)/(c-b);
      
break;
    
case 7case 8:
      x1
=ox+dx*(THRESHOLD-a)/(b-a);
      y1
=oy;
      x2
=ox+dx;
      y2
=oy+dy*(THRESHOLD-b)/(c-b);
      
break;
    }
  glBegin(GL_LINES);
    glVertex2d(x1, y1);
    glVertex2d(x2, y2);
  glEnd();
}

void draw_adjacent(int num, int i, int j, double a, double b,
double c, double d)
{
  
double x1, y1, x2, y2;
  
double ox, oy;
  
double dx, dy;
  dx
=(X_MAX-(X_MIN))/(N_X-1.0);
  dy
=(Y_MAX-(Y_MIN))/(N_Y-1.0);
  ox
=X_MIN+i*(X_MAX-(X_MIN))/(N_X-1.0);
  oy
=Y_MIN+j*(Y_MAX-(Y_MIN))/(N_Y-1.0);
  
switch(num)
  {
    
case 3case 12:
      x1
=ox+dx*(THRESHOLD-a)/(b-a);
      y1
=oy;
      x2
=ox+dx*(THRESHOLD-d)/(c-d);
      y2
=oy+dy;
      
break;
    
case 6case 9:
      x1
=ox;
      y1
=oy+dy*(THRESHOLD-a)/(d-a);
      x2
=ox+dx;
      y2
=oy+dy*(THRESHOLD-b)/(c-b);
      
break;
  }
  glBegin(GL_LINES);
    glVertex2d(x1, y1);
    glVertex2d(x2, y2);
  glEnd();

}

void draw_opposite(int num, int i, int j, double a, double b,
double c, double d)
{
  
double x1,y1,x2,y2,x3,y3,x4,y4;
  
double ox, oy;
  
double dx, dy;
  dx
=(X_MAX-(X_MIN))/(N_X-1.0);
  dy
=(Y_MAX-(Y_MIN))/(N_Y-1.0);
  ox
=X_MIN+i*(X_MAX-(X_MIN))/(N_X-1.0);
  oy
=Y_MIN+j*(Y_MAX-(Y_MIN))/(N_Y-1.0);
  
switch(num)
  {
    case5:
      x1
=ox;
      y1
=oy+dy*(THRESHOLD-a)/(d-a);
      x2
=ox+dx*(THRESHOLD-a)/(b-a);
      y2
=oy;
      x3
=ox+dx*(THRESHOLD-d)/(c-d);
      y3
=oy+dy;
      x4
=ox+dx;
      y4
=oy+dy*(THRESHOLD-b)/(c-b);
      
break;
    
case 10:
      x1
=ox;
      y1
=oy+dy*(THRESHOLD-a)/(d-a);
      x2
=ox+dx*(THRESHOLD-d)/(c-d);
      y2
=oy+dy;
      x3
=ox+dy*(THRESHOLD-a)/(b-a);
      y3
=oy;
      x4
=ox+dx;
      y4
=oy+dy*(THRESHOLD-b)/(c-b);
      
break;
  }
  glBegin(GL_LINES);
    glVertex2d(x1, y1);
    glVertex2d(x2, y2);
    glVertex2d(x3, y3);
    glVertex2d(x4, y4);
  glEnd();
}

void myReshape(int w, int h)
{
    glViewport(
00, w, h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    
if (w <= h) gluOrtho2D(X_MIN, X_MAX, Y_MIN * (GLfloat) h / (GLfloat) w, Y_MAX* (GLfloat) h / (GLfloat) w);
    
else gluOrtho2D(X_MIN * (GLfloat) w / (GLfloat) h, X_MAX * (GLfloat) w / (GLfloat) h, Y_MIN, Y_MAX);
    glMatrixMode(GL_MODELVIEW);
}

int main(int argc, char **argv)
{
   glutInit(
&argc, argv);
   glutInitWindowSize(
500500);
   glutCreateWindow(
"contour plot");
   glutReshapeFunc(myReshape);
   glutDisplayFunc(display);
   glClearColor(
0.0,0.0,0.0,1.0);
   glColor3f(
1.0,1.0,1.0);
   glutMainLoop();
}

200792701.jpg

posted on   Phinecos(洞庭散人)  阅读(1658)  评论(3编辑  收藏  举报

编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· [AI/GPT/综述] AI Agent的设计模式综述

导航

统计

点击右上角即可分享
微信分享提示