悬挂系统经典算法.docx

上传人:b****6 文档编号:7960399 上传时间:2023-01-27 格式:DOCX 页数:12 大小:148.02KB
下载 相关 举报
悬挂系统经典算法.docx_第1页
第1页 / 共12页
悬挂系统经典算法.docx_第2页
第2页 / 共12页
悬挂系统经典算法.docx_第3页
第3页 / 共12页
悬挂系统经典算法.docx_第4页
第4页 / 共12页
悬挂系统经典算法.docx_第5页
第5页 / 共12页
点击查看更多>>
下载资源
资源描述

悬挂系统经典算法.docx

《悬挂系统经典算法.docx》由会员分享,可在线阅读,更多相关《悬挂系统经典算法.docx(12页珍藏版)》请在冰豆网上搜索。

悬挂系统经典算法.docx

悬挂系统经典算法

OpenGL只提供了几种画简单直线图元的函数,这是为了便于硬件的支持,和硬件效率的提高。

但实际工作中,会用到大量的曲线和曲面,通常画曲线和曲面的方法,是采用细分法,用直线或平面去逼近。

对于曲面的逼近,通常采用三角图元去逼近(因为三角形可以保证三个顶点在一个平面上),如果要渲染光照效果,在细分过程中,一定要计算每个点的法向量。

    对于曲面的逼近,例如,用球的内接正四面体的细分去逼近球,那么,在细分的过程中,首先求的每个边的中点,然后根据该点法向量,求出该点在球面上对应的点的坐标,然后再做细分操作。

对于球体,对内接体上的点做单位化处理,就能得到其再球面上应该对应的位置。

   本文以平面图形的逼近为例,举两个例子,圆的逼近和抛物线的逼近。

   一、圆的逼近

   首先,画出圆的内接正三角形。

    GLfloatp1[2]={0,1},p2[2]={-sqrt(3.0)/2,-1/2.0},p3[2]={sqrt(3.0)/2,-1/2.0};

    glBegin(GL_LINE_LOOP);

    glVertex2fv(p1);

    glVertex2fv(p2);

    glVertex2fv(p3);

    glEnd();

    然后,用递归函数,每一步,首先求的三角形边p1p2上的中点p,再对该中点坐标做单位化处理,得到其在圆上的坐标,然后分别连接p1p和pp2,获得一次细分。

一次类推,当满足递归层次的时候,画出结果。

voidpara(GLfloat*p1,GLfloat*p2,intdepth)

{

 GLfloatp[2]={0,0};

 for(inti=0;i<2;i++)

 {

  p[i]=(p1[i]+p2[i])/2;//近似形上两点的中点

 }

 GLfloatd=sqrt(p[0]*p[0]+p[1]*p[1]);

 p[0]/=d;

 p[1]/=d;//根据法向量计算中点在圆上的位置

 if(depth

 {

  para(p1,p,depth+1);

  para(p,p2,depth+1);

 }

 else

 {

  glBegin(GL_LINES);

  glVertex2fv(p1);

  glVertex2fv(p);

  glVertex2fv(p);

  glVertex2fv(p2);

  glEnd();

  glFlush();  

 }

在display()函数中调用递归函数

para(p1,p2,0);

para(p2,p3,0);

para(p3,p1,0);

对三条边分别进行细分。

递归1次,2次,3次得到的结果如下:

 

 

 

单片机控制下步进电机画圆方法<转>  

2007-05-1620:

21:

59|  分类:

单片机学习|  标签:

|字号大中小 订阅

一直线算法

1.直线插补法:

直线插补法是在绘图系统中常用的一种逐点比较算法。

它的原理是:

执行机构每走一步,都要和给定轨迹上的坐标值进行一次比较,看当前位置和轨迹位置的关系,从而确定下一步的进给方向。

如果当前位置在给定轨迹的下方,下一步向给定轨迹的上方走,反之则相反。

如果当前位置在给定轨迹的里面,下一步向给定轨迹的外面走,反之则相反。

这样走一步看一步,决定下一步走向,形成“逐点比较”,使走线逼近给定轨迹。

2.多边形逼近画圆

一个正多边形,当其边数n足够大,即每边所对的圆心角△θ足够小时,就非常接近一个圆。

这样,画圆的问题就变成画多边形、画直线的问题了,只要确定n和θ角的大小,多边形顶点的坐标位置,我们就可以绕开烦琐的象限问题,直接利用上面的画线的简易算法来实现画圆。

3.圆弧插补法

圆弧插补法也是在绘图系统中常用的一种方法,它和直线插补法原理相同,也是逐点比较算法。

若F=0,表明加工点在圆弧上;

F>0,表明加工点在圆弧外;

F<0,表明加工点在圆弧内。

若F≥0,为逼近圆弧,下一步向-X轴进给一步,并计算出新的偏差值;

F<0,为逼近圆弧,下一步向+Y轴进给一步,并计算出新的偏差值。

各象限插补公式如下

步进电机控制下画笔具体走法

最后附上3相步进电机与AT89C51单片机驱动电路:

 

#include

#include

sbitcp1=P1^0;

sbitcw1=P1^1;

sbitcp2=P1^2;

sbitcw2=P1^3;

floatstep(floatx1,floaty1,floatx2,floaty2)

{

   floatbuj;

 floatchd1;

 chd1=sqrt((x1)*(x1)+y1*y1)-sqrt((x2)*(x2)+y2*y2);

  

 buj=chd1/0.01;

   returnbuj;

}

voiddelay(inti)

{

 while(i--);

}

voidbuj(floatbuj1,floatbuj2)

{

   inti,j,y,b;

  

   if(buj1<0)

 {

  cw1=1; 

  buj1=-buj1;

 }

 else

  cw1=0;

  

 if(buj2<0)

 {

  cw2=1;

  buj2=-buj2; 

 }

 else

  cw2=0;

   

   if(buj1>buj2){

       b=buj1/buj2;

       y=buj1-b*buj2;

       for(i=1;i<=buj2;i++){

           for(j=1;j<=b;j++){

               cp1=0;

               delay(100);

               cp1=1;

               delay(100);

           }

           cp2=0;

           delay(100);

           cp2=1;

           delay(100);  

       

           if(y!

=0){

               

               cp1=0;

               delay(100);

               cp1=1;

               delay(100);

               y--;          

           }    

       }

   }

   else{

           b=buj2/buj1;

           y=buj2-buj1*b;

           for(i=1;i<=buj1;i++){

               for(j=1;j<=b;j++){

                   cp2=0;

                   delay(100);

                   cp2=1;

                   delay(100);

               }

               cp1=0;

               delay(100);

               cp1=1;

               delay(100);  

       

               if(y!

=0){

                   

                   cp2=0;

                   delay(100);

                   cp2=1;

                   delay(100);

                   y--;           

               }                   

        }  

   }

}

 

 

voiddelay10ms()

{

 unsigned inti,j;

 for(j=10;j!

=0;j--)

  for(i=125;i!

=0;i--);

}

voidsan()//玫瑰线

{

 r=20*sin(3*(-1.5707963));

 x=40+r*cos(-1.5707963);

 y=50+r*sin(-1.5707963);

 for(i=-1.5707963;i<=1.5707963;i=i+3.1415926/180){

  r=20*sin(3*(i));

    w=40+r*cos(i);

  v=50+r*sin(i);

  buj1=step(x+15,115-y,w+15,115-v);

  buj2=step(95-x,115-y,95-w,115-v);

  buj(buj1,buj2);

  x=w;

  y=v;

 }

}

voidyuan(){//画圆

 r=20;

 x=40;

 y=30;

 for(i=-1.5707963;i<=4.85;i=i+3.1415926/180){

    w=40+r*cos(i);

    v=50+r*sin(i);

  buj1=step(x+15,115-y,w+15,115-v);

  buj2=step(95-x,115-y,95-w,115-v);

  buj(buj1,buj2);

  x=w;

  y=v;

 }

}

voidstar()//星形线

{

 floata1,b1;

 r=20;

 a1=60;

 b1=30;

 x=a1+r*cos(1.7);

   y=b1+r*sin(1.7);

 for(i=1.7;i<=3.1415926;i=i+3.1415926/180)

 {

  w=a1+r*cos(i);

    v=b1+r*sin(i);

  buj1=step(x+15,115-y,w+15,115-v);

  buj2=step(95-x,115-y,95-w,115-v);

  buj(buj1,buj2);

  x=w;

  y=v;

 }

 a1=20;

 b1=30;

 for(i=0;i<=1.5707963;i=i+3.1415926/180)

 {

  w=a1+r*cos(i);

    v=b1+r*sin(i);

  buj1=step(x+15,115-y,w+15,115-v);

  buj2=step(95-x,115-y,95-w,115-v);

  buj(buj1,buj2);

  x=w;

  y=v;

 }

 a1=20;

 b1=70;

 for(i=-1.5707963;i<=0;i=i+3.1415926/180)

 {

  w=a1+r*cos(i);

    v=b1+r*sin(i);

  buj1=step(x+15,115-y,w+15,115-v);

  buj2=step(95-x,115-y,95-w,115-v);

  buj(buj1,buj2);

  x=w;

  y=v;

 }

 a1=60;

 b1=70;

 for(i=3.1415926;i<=4.65;i=i+3.1415926/180)

 {

  w=a1+r*cos(i);

    v=b1+r*sin(i);

  buj1=step(x+15,115-y,w+15,115-v);

  buj2=step(95-x,115-y,95-w,115-v);

  buj(buj1,buj2);

  x=w;

  y=v;

 }

}

voidmysin() //y=zhengfu*sin(pinlv*(x-xiangwei))+pianzhi //正弦线

{

 x=20;

 y=30;

 v=20+1/0.13*6.6;

 r=1/0.13*6.2831852/360;

 for(i=20;i<=v;i=i+r)

 {

  w=15*sin(0.13*(i-20))+30;

  buj1=step(x+15,115-y,i+15,115-w);

  buj2=step(95-x,115-y,95-i,115-w);

  buj(buj1,buj2);

  x=i;

  y=w;

 }

}

voidlist()//直线

{

   buj1=step(54+15,115-50,40+15,115-30);

 buj2=step(95-54,115-50,95-40,115-30);

 buj(buj1,buj2);

}

voidmain()

   bitflag;

   while

(1)

   {

       do{

            while(key);

           delay10ms();

           if(key==0)

           {  

               flag=0;

               mysin();

           }

           else

               flag=1;

       }while(flag);

       

       do{

            while(key);

           delay10ms();

           if(key==0)

           {  

               flag=0;

               star();

           }

           else

               flag=1;

       }while(flag);

       

       do{

            while(key);

           delay10ms();

           if(key==0)

           {  

               flag=0;

               list();

           }

           else

               flag=1;

       }while(flag);

      

       do{

            while(key);

           delay10ms();

           if(key==0)

           {  

               flag=0;

               yuan();

           }

           else

               flag=1;

       }while(flag);

      

       do{

            while(key);

           delay10ms();

           if(key==0)

           {  

               flag=0;

               san();

           }

           else

               flag=1;

       }while(flag);

   }

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 解决方案 > 学习计划

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1