最近同事想让要做一个绘图的控件。VC里面的画弧函数Arc需要提供外接矩形的坐标。同事觉得不好用,他更习惯圆弧插补的那种方式。于是看了看圆弧插补的东西。其实这种画弧方式就是提供圆弧的起点、终点和半径来画弧。

首先来简单介绍下圆弧插补:

有两种圆弧插补:

G02     顺时针圆弧插补

G03    逆时针圆弧插补

圆弧插补编程(半径编程):

圆弧用编程功能G02 或G03 和其后圆弧终点坐标和半径值定义。

圆弧半径用字母“R”表示。如果圆弧小于180 度,半径用正数符号,如果大于180 度用负数符号。这样基于所选圆弧插补(G02 或G03),可定义所选圆弧。

结合圆弧插补,设计绘制圆弧的函数:函数可分为两种,顺时针绘制和逆时针绘制(分布对应G02 和G03)。函数的参数为圆弧起点,终点,半径。其中的半径若为正数,则绘制的圆弧为弧度小于180 的弧,这里称为小圆弧。若半径为负数,则绘制的弧为大雨180度的弧,这里成之为大圆弧。

圆弧的绘制最终还是要使用C++ 提供的画弧函数Arc 。 因此我们需要找出来圆所在的外接矩形(这里是正方形)。因为我们已知半径,所以找到圆心就可以推导出圆所在的矩形。

圆心的推导过程参考文章 已知圆上两点坐标和半径,求圆心   已知两点坐标和半径,求圆心 。圆心解出来有两个(x01,y01)(x02,y02)。如图所示,过相同的点并且半径相同的圆也确实有两个。那么到底哪一个是符合条件的圆呢。

首先来讨论逆时针画弧的函数。如上图,从起点A到终点B,小圆弧就指的红色部分的弧,大圆弧是指的蓝色部分的弧。小圆弧的圆心是O2,大圆弧的圆心是O1;

那么由什么条件能判断出所得的两个圆心(x01,y01)(x02,y02)哪一个是逆时针里的大圆弧的圆心O1,哪一个是逆时针里的小圆弧圆心O2呢? 这里我采用的是向量叉乘的方式判断的。

也就是起点到终点组成的向量,与起点与大弧圆心组成的向量叉乘结果是小于0 的。(这个从图上使用右手法则可以判断出来,由AB 向AO1 弯曲,拇指垂直屏幕向里)。

(有关向量知识参考 C语言-向量基本概念  向量叉乘判断点的位置)。

所以在上一步所得的两个圆心坐标,与起点坐标组成向量。

设A(x1,y1) B(x2,y2)

向量AB={x2-x1,y2-y1}

向量a={x01-x1,y01-y1}

向量b={x02-x1,y02-y1}

则(x01,y01)为大圆弧圆心 (x02,y02)为小圆弧圆心

否则 反之。

代码如下:

//已知圆弧上两点 和半径,求圆心
void CircleCenter(double x1,double y1,double x2,double y2,double R,double &x01,double &y01,double &x02,double &y02)
{  //x1 == x2if (abs(x1-x2)<0.0000001){//(x1,y1)(x2,y2)之间的距离 /2double dis = abs(y1-y2)/2;double dx = sqrt(R*R-dis*dis);double dy = (y1+y2)/2;x01 = x1-dx;y01 = dy;x02 = x1+dx;y02 = dy;return ;}double c1 = (x2*x2 - x1*x1 + y2*y2 - y1*y1) / (2 *(x2 - x1));  double c2 = (y2 - y1) / (x2 - x1);  //斜率double A = (c2*c2 + 1);  double B = (2 * x1*c2 - 2 * c1*c2 - 2 * y1);  double C = x1*x1 - 2 * x1*c1 + c1*c1 + y1*y1 - R*R;  y01 = (-B + sqrt(B*B - 4 * A*C)) / (2 * A);x01 = c1 - c2 * y01;   y02 =  (-B - sqrt(B*B - 4 * A*C)) / (2 * A);x02 = c1 - c2*y02;
}

  

//逆时针画弧
void CDrawShapeCtrl::Arc_AntiClock(DOUBLE StartX, DOUBLE StartY, DOUBLE EndX, DOUBLE EndY, DOUBLE R)
{AFX_MANAGE_STATE(AfxGetStaticModuleState());// TODO: Add your dispatch handler code here//圆心坐标double x01,y01,x02,y02;double x_big,y_big;//大弧圆心double x_small,y_small;//小弧圆心LONG nLeftRect, nTopRect,nRightRect,nBottomRect;CircleCenter(StartX,StartY,EndX,EndY,R,x01,y01,x02,y02);//向量 double ax = EndX- StartX;double ay = EndY - StartY;double bx = x01 - StartX;double by = y01 - StartY;//利用向量的叉乘判断圆心位置//叉乘<0  则为大弧圆心;否则为小弧圆心double mulRt = ax*by-bx*ay;if (mulRt<0){x_big = x01;y_big = y01;x_small = x02;y_small = y02;}else{x_big = x02;y_big = y02;x_small = x01;y_small = y01;}CClientDC dc(this);CRect rc;GetClientRect(rc);dc.SetMapMode(MM_ISOTROPIC);//MM_ISOTROPIC//逻辑坐标原点dc.SetViewportOrg(rc.right/2,rc.bottom/2);//设置映射比例为1,逻辑坐标Y轴方向与设备坐标相反dc.SetWindowExt(100,100);dc.SetViewportExt(100,-100);//R>0   弧<180度; R<0  弧>180度if (R<0) //大弧{nLeftRect = x_big-R;nTopRect = y_big + R;nRightRect = x_big+R;nBottomRect = y_big -R;dc.Arc(nLeftRect,nTopRect,nRightRect,nBottomRect,StartX,StartY,EndX,EndY);    }else //小弧{nLeftRect = x_small-R;nTopRect = y_small+R;nRightRect = x_small+R;nBottomRect = y_small - R;dc.Arc(nLeftRect,nTopRect,nRightRect,nBottomRect,StartX,StartY,EndX,EndY);}}

 顺时针函数,只要将起点终点坐标对换,直接调用逆时针函数即可。

arc 函数参考:

https://blog.csdn.net/u012513234/article/details/45460783

转载于:https://www.cnblogs.com/small-lazybee/p/10369394.html

模拟PLC 的圆弧插补方式在VC中绘制圆弧相关推荐

  1. c语言圆弧插补源代码,模拟PLC 的圆弧插补方式在VC中绘制圆弧

    最近同事想让要做一个绘图的控件.VC里面的画弧函数Arc需要提供外接矩形的坐标.同事觉得不好用,他更习惯圆弧插补的那种方式.于是看了看圆弧插补的东西.其实这种画弧方式就是提供圆弧的起点.终点和半径来画 ...

  2. HTML5 Canvas中 绘制圆弧

    绘制圆弧 圆弧被定义为假想的圆周上任意两点之间的部分.Canvas的API提供了两个绘制圆弧的方法:arc()和arcTo()方法. arc()方法 使用arc()方法绘制圆弧时,假想的圆由圆心和半径 ...

  3. android画布画弧形,在Android中绘制圆弧边缘圆弧,具有浮雕效果

    我正在尝试开发一个自定义组件,即圆弧滑块,我完成了弧和拇指,但不能弄清楚如何绘制圆弧边缘弧和其中的浮雕效果.在这一刻,滑块看起来像这样 绘制弧的代码是 private void drawSlider( ...

  4. 图像处理控件功能演示: 在 C# 中绘制直线、圆弧、椭圆、矩形等形状

    Aspose.Imaging for .NET是一个可以让开发人员可以创建.编辑.画图.转换图像的图像处库,提供了一些开发平台原有功能基础之上的一些新特性.它独立于其他应用程序, Aspose.Ima ...

  5. html 物理引擎,在物理引擎中画圆弧

    本文作者:IMWeb zzbozheng 未经同意,禁止转载 因为需求的需要,要使用在物理引擎中使用四分之一圆弧,我们来看看怎么实现在物理引擎中画出四分之一的圆弧, 在物理引擎中绘制圆弧 一般来说,物 ...

  6. cad怎么绘制大样图_浩辰CAD看图王电脑版中怎么绘制圆弧?

    有些小伙伴在使用浩辰CAD看图王电脑版编辑图纸的时候,找不到绘制圆弧的工具该怎么办呢?接下来就给大家介绍一下浩辰CAD看图王电脑版中绘制圆弧的操作教程吧! 在浩辰CAD看图王电脑版中,提供的绘图功能有 ...

  7. VC++中Depends工具的使用和DLL函数的动态调用方式示例

    VC++中Depends工具:Depends用来显示与一个可执行文件(exe或者dll)相关的依赖项(动态链接库dll),以及该exe或dll引用了这些dll中的哪些接口,同时也可以看到每个被依赖的d ...

  8. 转:vc中如何通过http的post方式上传文件

    文章引自:http://blog.myspace.cn/e/404248359.htm vc中如何通过http的post方式上传文件 HTTP响应     在接收和解释请求消息后,服务器会返回一个HT ...

  9. VC中ADO连接SQLSERVER的几种标准方式?

    VC用ADO访问数据库全攻略,介绍了VC用ADO来访问数据库的各个对象及各方法,很经典,也很实用,很值得一看. 正文 一.ADO概述 ADO是Microsoft为最新和最强大的数据访问范例 OLE D ...

最新文章

  1. React Native Windows 环境搭建(适合有Android 开发基础的同学)
  2. 成功解决 raise XGBoostError(_LIB.XGBGetLastError()) xgboost.core.DMatrix/Booster has not been intialized
  3. 【模型解读】从“局部连接”回到“全连接”的神经网络
  4. Windows7无损分区
  5. 使用Spring Task完成定时任务
  6. oracle数据库跟mysql的区别_关于Oracle数据库与MySQL数据库的几点区别
  7. sqlplus / as sysdba 提示权限不足(ORA-01031)问题处理
  8. 苹果员工号召罢工 呼吁顾客平安夜不购买苹果产品
  9. 电商无线页面设计手机移动端的设计模板
  10. Android异常总结---1.异常原因: java.lang.IllegalArgumentException: URI: content://com.android.contacts/con
  11. tornado总结4-html模板使用2
  12. Java并发编程:并发容器之ConcurrentHashMap(转载)
  13. ip地址伪装php,技术教程:如何使用浏览器插件伪装IP地址
  14. 管理感悟:人事问题不能拖,必须立即处理
  15. u盘固定盘符_Windows 下如何固定 U 盘的盘符?
  16. 基于Delphi7的木马程序的查杀设计与实现
  17. H264/AVC-NALU解析
  18. 关于人工智能不会使大脑变懒惰的议论文_模拟人类大脑 :人工智能的救赎之路 ?...
  19. Java IO流学习总结一:输入输出流
  20. onselect事件在表单元素中的使用

热门文章

  1. 离开互联网上岸1年后,我后悔了!重回大厂内卷
  2. 不吹不黑!让你搜遍GitHub都找不到这么吊炸天的网约车项目!
  3. 详解微服务技术中进程间通信
  4. 聊一聊 Spring 中的线程安全性
  5. SpringBoot实现过滤器、拦截器与切片
  6. Java分布式 RPC 框架性能大比拼,Dubbo最差?
  7. 报名即将截止,中国移动“梧桐杯”大数据应用创新大赛,寻找大数据敢想者!...
  8. kaggle、TDS、arXiv等,我最喜欢的数据科学资源
  9. 【廖雪峰python入门笔记】tuple_“元素可变”
  10. 1357篇ECCV 2020论文打包下载!奖项公布:李飞飞高徒获最佳论文奖