求画三角形和椭圆的算法

littlevoice 2005-03-13 02:10:31
如题,比较急
...全文
1078 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
iori_yagami 2005-03-16
  • 打赏
  • 举报
回复
随便找本《计算机图形学》就有啊,网上搜搜也多的是
dongpy 2005-03-16
  • 打赏
  • 举报
回复
画椭圆算法:

////////////////////////////////////////////////////////////////////////////////////
//BreEllipse
//(xc,yc)----------椭圆中心
//fla,flb----------横轴和纵轴的半径
//double-----------旋转的角度
////////////////////////////////////////////////////////////////////////////////////
void BreEllipse(CDC *pDC,float xc ,float yc,float fla,float flb,double angle)
{
int i;
float a,b,x,y;
double dx,dy,di,aa,bb,sinA,cosA;
cosA=cos(angle);
sinA=sin(angle);
a=fla;
b=flb;
aa=a*a;
bb=b*b;
float flX[4],flY[4];
x=0;
y=b;
dx=0;
dy=2*aa*y;
di=bb-aa*b+aa/4;
flX[0]=xc+x*cosA-y*sinA;
flX[1]=xc+x*cosA+y*sinA;
flX[2]=xc-x*cosA-y*sinA;
flX[3]=xc-x*cosA+y*sinA;
flY[0]=yc+y*cosA+x*sinA;
flY[1]=yc-y*cosA+x*sinA;
flY[2]=yc+y*cosA-x*sinA;
flY[3]=yc-y*cosA-x*sinA;
i=0;
while(dx<dy)
{
i++;
if(i==5)
{
pDC->MoveTo(flX[0],flY[0]);
pDC->LineTo(xc+x*cosA-y*sinA,yc+y*cosA+x*sinA);
pDC->MoveTo(flX[1],flY[1]);
pDC->LineTo(xc+x*cosA+y*sinA,yc-y*cosA+x*sinA);
pDC->MoveTo(flX[2],flY[2]);
pDC->LineTo(xc-x*cosA-y*sinA,yc+y*cosA-x*sinA);
pDC->MoveTo(flX[3],flY[3]);
pDC->LineTo(xc-x*cosA+y*sinA,yc-y*cosA-x*sinA);
flX[0]=xc+x*cosA-y*sinA;
flX[1]=xc+x*cosA+y*sinA;
flX[2]=xc-x*cosA-y*sinA;
flX[3]=xc-x*cosA+y*sinA;
flY[0]=yc+y*cosA+x*sinA;
flY[1]=yc-y*cosA+x*sinA;
flY[2]=yc+y*cosA-x*sinA;
flY[3]=yc-y*cosA-x*sinA;
i=0;
}
x++;
dx+=2*bb;
di+=dx+bb;
if(di>=0)
{
dy-=2*aa;
di-=dy;
y--;
}
}
pDC->MoveTo(flX[0],flY[0]);
pDC->LineTo(xc+x*cosA-y*sinA,yc+y*cosA+x*sinA);
pDC->MoveTo(flX[1],flY[1]);
pDC->LineTo(xc+x*cosA+y*sinA,yc-y*cosA+x*sinA);
pDC->MoveTo(flX[2],flY[2]);
pDC->LineTo(xc-x*cosA-y*sinA,yc+y*cosA-x*sinA);
pDC->MoveTo(flX[3],flY[3]);
pDC->LineTo(xc-x*cosA+y*sinA,yc-y*cosA-x*sinA);

di+=int((3*(aa-bb)-2*(dx-dy))/4+0.5);
flX[0]=xc+x*cosA-y*sinA;
flX[1]=xc+x*cosA+y*sinA;
flX[2]=xc-x*cosA-y*sinA;
flX[3]=xc-x*cosA+y*sinA;
flY[0]=yc+y*cosA+x*sinA;
flY[1]=yc-y*cosA+x*sinA;
flY[2]=yc+y*cosA-x*sinA;
flY[3]=yc-y*cosA-x*sinA;
i=0;
while(y>0)
{
i++;
if(i==5)
{
pDC->MoveTo(flX[0],flY[0]);
pDC->LineTo(xc+x*cosA-y*sinA,yc+y*cosA+x*sinA);
pDC->MoveTo(flX[1],flY[1]);
pDC->LineTo(xc+x*cosA+y*sinA,yc-y*cosA+x*sinA);
pDC->MoveTo(flX[2],flY[2]);
pDC->LineTo(xc-x*cosA-y*sinA,yc+y*cosA-x*sinA);
pDC->MoveTo(flX[3],flY[3]);
pDC->LineTo(xc-x*cosA+y*sinA,yc-y*cosA-x*sinA);
flX[0]=xc+x*cosA-y*sinA;
flX[1]=xc+x*cosA+y*sinA;
flX[2]=xc-x*cosA-y*sinA;
flX[3]=xc-x*cosA+y*sinA;
flY[0]=yc+y*cosA+x*sinA;
flY[1]=yc-y*cosA+x*sinA;
flY[2]=yc+y*cosA-x*sinA;
flY[3]=yc-y*cosA-x*sinA;
i=0;
}
y--;
dy-=2*aa;
di+=aa-dy;
if(di<0)
{
dx+=2*bb;
di+=dx;
x++;
}
}
pDC->MoveTo(flX[0],flY[0]);
pDC->LineTo(xc+x*cosA-y*sinA,yc+y*cosA+x*sinA);
pDC->MoveTo(flX[1],flY[1]);
pDC->LineTo(xc+x*cosA+y*sinA,yc-y*cosA+x*sinA);
pDC->MoveTo(flX[2],flY[2]);
pDC->LineTo(xc-x*cosA-y*sinA,yc+y*cosA-x*sinA);
pDC->MoveTo(flX[3],flY[3]);
pDC->LineTo(xc-x*cosA+y*sinA,yc-y*cosA-x*sinA);
}
dgx2363467 2005-03-13
  • 打赏
  • 举报
回复
找本计算机图形学看看
littlevoice 2005-03-13
  • 打赏
  • 举报
回复
还没彻底解决啊,有谁能说的清楚明白点
pcboyxhy 2005-03-13
  • 打赏
  • 举报
回复
在数学上,理想的点和直线都是没有宽度的。但是,由于每个像素对应于图形设备上的一个矩形区域,当我们在光栅图形设备上显示一个点时,实际上它是有用一个发光的矩形区域来表示的;当在光栅图形设备上显示一条直线时,我们只能在显示器所给定的有限个像素组成的矩阵中,按扫描线顺序,依次确定最佳逼近于该直线的一组像素,并且对这些像素进行写操作。这个过程称为直线的扫描转换。
对于水平线、垂直线和45º斜线,选择哪些像素是显而易见的,但是对于其它的直线,确定用哪些像素来表示它就不那麽简单了。本节我们介绍用于直线扫描转换的常用算法:Bresenham画线算法。
在介绍画线算法之前,我们先讨论画直线的基本要求:直线必须有精确的起点和终点,外观要直,线宽应当均匀一致、且与直线的长度和方向无关,最后,算法速度要快。
Bresenham算法是计算机图形学领域使用最广泛的直线扫描转换算法。该方法最初是为数字绘图仪设计的,后来被广泛地应用于光栅图形显示和数控(NC)加工。该算法构思巧妙,使得每次只需检测误差项的符号就能决定直线上的下一个像素的位置。算法原理如下:过各个像素的中心构造一组虚拟网格线,首先按直线从起点到终点的顺序计算直线与各垂直网格线的交点,然后,采用增量计算,使得对于每一列,只要检查一个误差项的符号,就可以确定该列像素中与此交点最近的像素。
先考虑斜率k=dy/dx≤1的直线。如图2.1所示,设直线 方程为 ,其中,k = dy/dx。 假设当前像素的x坐标已经确定为xi,其y坐标为yi,由于坐标(xi,yi)(i=0,1,…)只能取整数,那么下一个像素的x坐标 ,而yi+1的坐标有两种可能:
1) 保持不变,即y i+1=yi;或者

2) y坐标递增1,即y i+1=yi+1。
令 ,y坐标是否增加1取决于如图所示误差项d i的值。因为直线的起始点在像素中心,所以初始误差d0=0。x每增加1,y的值相应递增直线的斜率值k,即 。一旦di+1≥1,就把它减去1,这样保证di+1在0~1之间。当d i+1≥0.5时,直线 与x=xi+1的垂线的交点最接近于当前像素(xi,yi)的右上方像素(xi+1,yi+1);而当d i+1<0.5时,其交点更接近于(xi,yi)右边的像素(xi+1,yi)。为方便计算,令e0=-0.5,e i+1=di+1-0.5,增量为k。当ei+1≥0时,取当前像素(xi,yi)的右上方像素(xi+1, yi+1);而当e i+1<0时,更接近于右方像素(xi+1,yi)。









中心在原点、轴对齐的椭圆的非参数化方程为:
。
上式可用隐式方程表示为:

由于椭圆的对称性,仅考虑在第一象限的椭圆弧即可。椭圆弧的法向量计算公式为:

椭圆弧上斜率为-1的点将椭圆弧分为上、下部分,见图2.3所示。在上部分(区域2),法向量的y向分量较大,选择像素时增量Δy比较重要;在下部分(区域1),法向量的x分量较大,选择像素时增量Δx比较重要。下面我们分开进行讨论。
在区域2,设当前位置为点,下一个可能的点是像素点H和D,这时可构造判别式:

若<0,表示像素点H和D的中点在椭圆内,这时可取H为下一个像素点;若 >=0,表示像素点H和D的中点在椭圆外,这时应当取D为下一个像素点。所以,对于在区域2的椭圆弧,我们可以按左边的规则选取下一个像素作为椭圆弧的最佳逼近点:



不能贴图,
只能省略某些公式了
dongpy 2005-03-13
  • 打赏
  • 举报
回复
关注画椭圆的算法...
dongpy 2005-03-13
  • 打赏
  • 举报
回复
三角形好画的,由三个点确定3条线段,就是画线。

64,639

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧