悬挂系统经典算法.docx
《悬挂系统经典算法.docx》由会员分享,可在线阅读,更多相关《悬挂系统经典算法.docx(12页珍藏版)》请在冰豆网上搜索。
![悬挂系统经典算法.docx](https://file1.bdocx.com/fileroot1/2023-1/27/34c31269-b270-4d4a-9b68-cc9d35bccbe2/34c31269-b270-4d4a-9b68-cc9d35bccbe21.gif)
悬挂系统经典算法
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);
}