图形旋转和歪斜的椭圆.docx_第1页
图形旋转和歪斜的椭圆.docx_第2页
图形旋转和歪斜的椭圆.docx_第3页
图形旋转和歪斜的椭圆.docx_第4页
免费预览已结束,剩余1页可下载查看

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

图形旋转和歪斜的椭圆 介绍 窗口中的矩形,带圆角的矩形和椭圆只能由GDI在轴向上绘制。假如有人希望在Windows NT下绘制旋转或歪斜的图形,他可以使用世界坐标系变换。很不幸的是在Windows 95/98下,是没有世界坐标系变换的。作为一个跨平台的解决方案,就需要自己做更多的工作。矩形能由四边形模拟,这样它就能旋转和歪斜了。然而,椭圆又该怎么办呢?基本上有三个选择 两种选择 使用一个定制的函数来画椭圆。 椭圆的数学模型相对简单,而且还有用于在标准文本中旋转椭圆的修改过的Bresenham方程。然而,这种方法必须自己执行光栅操作,这样在绘制宽线时就变得复杂了。这种努力只有在向一个脱离屏幕的表面(比如DirectDraw)或位图上绘制视才是值得的 用连接的线段来绘制椭圆。 实际的线条可以通过LineTo(.)或Polyline(.)图形设备接口调用。你可以自己完成椭圆的近似,或者使用GDI的FlattenPath(.) 函数 使用贝塞尔曲线来近似绘制椭圆。 这里就举例说明这种方法。 用贝塞尔曲线绘制椭圆 使用四条贝塞尔曲线,每条代表原轴向椭圆的90度,这样就能获得一个相当近似的椭圆,最大误差只有0.027%。这个最大误差相当于长径3700的椭圆的误差小于一个像素,这已经超出我们所要求的准确度了。 优点 简单。 只需要有四个GDI调用。贝塞尔曲线控制点的计算代价是很小的。 快速 你可以利用现在新的显卡对曲线绘制的硬件支持。在我的系统上,这和调用GDI函数Ellipse(.)绘制椭圆的速度比,如果不是更快,至少也是一样快。 变化 因为贝塞尔曲线在旋转、缩放和平移时是不变的,在对椭圆做同样的变化时就只需要传送控制点。更巧的是,因为在一个三次贝塞尔曲线上的每个点都是控制点的重心组合,在仿射映射中曲线上控制点之间的关系是不变的。 设备无关性 假如想自己把椭圆转化为线段或光栅,那么每次表面的分辨率和设备描述表改变时(例如向一个打印机设备描述表绘制时),就必须重新光栅化。而使用贝塞尔曲线时就不需要这样做。还有一个好处就是椭圆能通过图元文件输出到绘画程序,例如CORELDRAW,在其中可以没有失真的缩放图形。 过程 首先以一个轴向椭圆的外接边界矩形开始(使用一个普通的GDI调用)。13个定义4条组成椭圆的贝塞尔曲线的控制点(以下标为0-12)可使用一个经验常量计算得出。下列代码为Y轴正方向向下的的映射模式产生控制点(例如MM_TEXT)。在Y轴正方向向上时,只要如注释中所示,把偏移量设为负值就行了。 / Create points to simulate ellipse using beziers/使用贝塞尔曲线创建点,模拟椭圆void EllipseToBezier(CRect& r, CPoint* cCtlPt) / MAGICAL CONSTANT to map ellipse to beziers / 2/3*(sqrt(2)-1) / 把椭圆映射为贝塞尔曲线的常量 2/3*(sqrt(2)-1) const double EToBConst =0.2761423749154; CSize offset(int)(r.Width() * EToBConst), (int)(r.Height() * EToBConst);/ Use the following line instead for mapping systems where +ve Y is upwards/ 在Y轴正方向向上时,使用下面一行/ CSize offset(int)(r.Width() * EToBConst), -(int)(r.Height() * EToBConst); CPoint centre(r.left + r.right) / 2, (r.top + r.bottom) / 2); cCtlPt0.x = /-/ cCtlPt1.x = / / cCtlPt11.x = / 2_3_4 / cCtlPt12.x = r.left; / 1 5 / cCtlPt5.x = / | | / cCtlPt6.x = / | | / cCtlPt7.x = r.right; / 0,12 6 / cCtlPt2.x = / | | / cCtlPt10.x = centre.x - offset.cx; / | | / cCtlPt4.x = / 11 7 / cCtlPt8.x = centre.x + offset.cx; / 10_9_8 / cCtlPt3.x = / / cCtlPt9.x = centre.x; /-* cCtlPt2.y = cCtlPt3.y = cCtlPt4.y = r.top; cCtlPt8.y = cCtlPt9.y = cCtlPt10.y = r.bottom; cCtlPt7.y = cCtlPt11.y = centre.y + offset.cy; cCtlPt1.y = cCtlPt5.y = centre.y - offset.cy; cCtlPt0.y = cCtlPt12.y = cCtlPt6.y = centre.y;Rotation of the Ellipse can be accomplished using code similar to: 使用与下面近似的代码可完成椭圆的旋转/ LDPoint is an equivalent type to CPoint but with floating point precision/ LDPoint是一个和CPoint相当的类型,不过它还具有浮点精度。void Rotate(double radians, const CPoint& c, CPoint* vCtlPt, unsigned Cnt) double sinAng = sin(radians); double cosAng = cos(radians); LDPoint constTerm( c.x - c.x * cosAng - c.y * sinAng, c.y + c.x * sinAng - c.y * cosAng); for (int i = Cnt-1; i=0; -i) vCtlPti = (LDPoint( vCtlPti.x * cosAng + vCtlPti.y * sinAng, -vCtlPti.x * sinAng + vCtlPti.y * cosAng) + constTerm).GetCPoint(); / Create Ellipse/ 创建椭圆CRect rect; GetClientRect(&rect);CPoint ellipsePts13;EllipseToBezier(ellipseR, ellipsePts);/ Rotate/ 旋转Rotate(m_Radians, midPoint, ellipsePts, 13);Filled EllipsesOf course, four bezier curves together only make up the outline of an ellipse, whether rotated or not. Thankfully, Win32 Path functions are there for filled ellipses. One only needs to enclose the PolyBezier(.) call in a Path Bracket. The resulting path can be stroked and filled to ones satisfaction. If one is feeling adventurous, further special fills like gradients, custom bitmaps or fractals etc. can be achieved by first setting the clipping region to the path via SelectClipPath(.).填充椭圆当然,无论是不是旋转,四条贝塞尔曲线只完成了椭圆的轮廓。幸运的是,Win32路径功能可用于填充椭圆。你只在需要调用PolyBezier(.)来封闭路径。完成的路径是一笔画出的,而且能被让人满意的填充。假如有人觉得还不够,比如更特殊的填充,比如斜线、用户位图或不规则碎片等。这些能由SelectClipPath(.)来把剪贴区域设置到路径上来而获得。dc.BeginPath();dc.PolyBezier(ellipsePts);dc.EndPath();dc.StrokePath;/ or F

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论