椭圆中点算法

原理

椭圆的扫描转换与圆的扫描转换有相似之处,但也有不同,主要区别是椭圆弧上存在改变主位移方向的临界点。瞬时针绘制四分椭圆弧的中点算法,根据对称性可以绘制完整的椭圆。

四分椭圆弧

中心在原点,长半轴为 a a a、短半轴为 b b b 的椭圆隐函数方程为

F ( x , y ) = b 2 x 2 + a 2 y 2 − a 2 b 2 = 0 F(x, y) = b^2 x^2 + a^2 y^2 -a^2 b^2 = 0 F(x,y)=b2x2+a2y2a2b2=0

四分法画椭圆算法:已知第一象限内的一点 ( x , y ) (x, y) (x,y), 可以顺时针确定另外 3 个对称点 ( x , − y ) (x, -y) (x,y) ( − x , − y ) (-x, -y) (x,y) ( − x , y ) (-x, y) (x,y)

在这里插入图片描述

临界分析

在临界点处,曲线的斜率为 − 1 -1 1

在这里插入图片描述
N ( x , y ) = N x i + N y j = ∂ F ∂ x i + ∂ F ∂ y j = 2 b 2 x i + 2 a 2 y j N(x, y) = N_{x_i} +N_{y_j} = \frac{\partial F}{\partial x}i + \frac{\partial F}{\partial y}j = 2b^2 x_i + 2 a^2y_j N(x,y)=Nxi+Nyj=xFi+yFj=2b2xi+2a2yj

法矢量的 x x x 方向的分量为 N x = 2 b 2 x N_x = 2b^2x Nx=2b2x, 法矢量的 y y y 方向为 N y Ny Ny = 2a^2y.从曲线上一点的法矢量角度看,在区域 I \bm{I} I 内, N x < N y N_x < N_y Nx<Ny 在临界点处, N x = N y N_x = N_y Nx=Ny 在区域 Ⅱ \bm{Ⅱ} 内, N x > N y N_x > N_y Nx>Ny。显然,在临界点处,法矢量分量的大小发生了变化。

在这里插入图片描述
从曲线上的斜率角度来看,在临界点处,斜率为 − 1 -1 1, 区域内 Ⅰ \bm{Ⅰ} 内, d x > d y dx > dy dx>dy, 所以 x x x 方向为主位移方向,在临界点处,有 d x = d y dx= dy dx=dy, 在区域内 Ⅱ Ⅱ 内, d y > d x dy > dx dy>dx, 所以 y y y 方向为主位移方向。在临界点处,主位移方向发生了改变。

在区域 Ⅰ Ⅰ x x x 方向上每次递增一个单位, y y y 方向上减 1 或 减 0, 取决于中点误差项的值,在区域 Ⅱ Ⅱ y y y 方向上每次递增一个单位, x x x 方向上加 1 或 加 0 取决于中点误差项的值。

在这里插入图片描述

构造区域 I I I 的中点误差项

从当前点 P i P_i Pi 出发选取一个像素点时,需将 P u P_u Pu P d P_d Pd 两个候选像素连线的网格中点 M M M ( x i + 1 , y i − 0.5 ) (x_i + 1, y_i -0.5) (xi+1,yi0.5) 代入隐函数的方程,构造中点误差项 d 1 i d_{1i} d1i

d 1 i = F ( x i + 1 , y i − 0.5 ) = b 2 ( x i + 1 ) 2 + a 2 ( y i − 0.5 ) 2 − a 2 b 2 d_{1i} = F(x_i + 1, y_i-0.5) = b^2 (x_i + 1)^2 + a^2 (y_i -0.5)^2 - a^2b^2 d1i=F(xi+1,yi0.5)=b2(xi+1)2+a2(yi0.5)2a2b2
在这里插入图片描述

y i + 1 = { y i d 1 i < 0 y i − 1 d 1 i ≥ 0 y_{i+1} = \begin{cases} y_i & d_{1i} < 0\\ yi - 1 & d_1i \geq 0 \end{cases} yi+1={yiyi1d1i<0d1i0

中点误差项 d 1 i d_{1i} d1i 的递推公式

在这里插入图片描述
d 1 i < 0 d_1i < 0 d1i<0 区域内 Ⅰ Ⅰ 内中点的递推

d 1 i + 1 = d 1 i + b 2 ( x i + 3 ) d_{1i+1} = d_{1i} + b^2(x_i + 3) d1i+1=d1i+b2(xi+3)
在这里插入图片描述
d 1 i ≥ 0 d_1i \geq 0 d1i0 区域内 Ⅰ Ⅰ 内中点的递推

d 1 i + 1 = d 1 i + b 2 ( x i + 3 ) + a 2 ( − 2 y i + 2 ) d_{1i+1} = d_{1i} + b^2(x_i + 3) + a^2(-2y_i+ 2) d1i+1=d1i+b2(xi+3)+a2(2yi+2)

中点误差项 d 1 i d_1i d1i 的初值

在区域 Ⅰ Ⅰ 内,椭圆弧的起点扫描转换后的像素点为 P 0 ( a , b ) P_0(a, b) P0(a,b) 沿着主位移 x x x 的方向递增一个单位,第一个参与判断的中点是 M ( 1 , b − 0.5 ) M(1,b-0.5) M(1b0.5), 响应的中点误差项 d 1 i d_{1i} d1i

d 10 = b 2 + a 2 ( − b + 0.25 ) d_{10} = b^2 + a^2(-b + 0.25) d10=b2+a2(b+0.25)

构造区域 Ⅱ Ⅱ 的中点误差项

在区域 Ⅱ Ⅱ 内,主位移方向发生变化,由 x x x 方向转变为 y y y 方向,从区域 Ⅰ Ⅰ 椭圆弧的终点, P i ( x i , y i ) P_i(x_i, y_i) Pi(xi,yi) 出发选取下一像素时,需将 P 1 ( x i , y i − 1 ) P_1(x_i, y_i-1) P1(xiyi1) P r ( x I + 1 , y i + 1 ) P_r(x_I +1, y_i +1) Pr(xI+1,yi+1)
的中点, M ( x i + 0.5 , y i − 1 ) M(x_i + 0.5, y_i-1) M(xi+0.5,yi1) 代入隐函数方程,构造中点误差项 d 2 i d_{2i} d2i

d 2 i = F ( x i + 0.5 , y i − 1 ) = b 2 ( x i + 0.5 ) 2 + a 2 ( y i − 1 ) 2 − a 2 b 2 d_{2i} = F(x_i + 0.5, y_i-1) = b^2(x_i + 0.5)^2 + a ^2(y_i -1)^2 -a^2b^2 d2i=F(xi+0.5,yi1)=b2(xi+0.5)2+a2(yi1)2a2b2

在这里插入图片描述

x i + 1 = { x i + 1 d 2 i < 0 x i d 2 i ≥ 0 x_{i+1} = \begin{cases} x_i + 1& d_{2i} < 0\\ xi & d_{2i} \geq 0 \end{cases} xi+1={xi+1xid2i<0d2i0

中点误差项 d 2 i d_{2i} d2i 的递推公式

在这里插入图片描述

d 2 i < 0 d_{2i} < 0 d2i<0 区域 Ⅰ Ⅰ 内中的递推
d 2 ( i + 1 ) = d 2 i + b 2 ( 2 x i + 2 ) + a 2 ( − 2 y i + 3 ) d_{2(i+1)} = d_{2i} + b^2 (2x_i+2) + a^2(-2y_i +3) d2(i+1)=d2i+b2(2xi+2)+a2(2yi+3)

在这里插入图片描述
d 2 i ≥ 0 d_{2i} \geq 0 d2i0 区域 Ⅰ Ⅰ 内中的递推

d 2 ( i + 1 ) = d 2 i + a 2 ( − 2 y i + 3 ) d_{2(i+1)} = d_{2i} + a^2(-2y_i + 3) d2(i+1)=d2i+a2(2yi+3)

中点误差项 d 2 i d_{2i} d2i 的初始值

假定 P i ( x i , y i ) P_i(x_i, y_i) Pi(xi,yi) 点为区域 Ⅰ Ⅰ 内椭圆弧上的最后一个像素, M I ( x i + 1 , y i − 0.5 ) M_I(xi+1, y_{i-0.5}) MI(xi+1,yi0.5) p u p_u pu p d p_d pd 像素的中点,满足 x x x 方向分量小于 y y y 方向分量

b 2 ( x i + 1 ) < a 2 ( y i − 0.5 ) b^2(x_i +1) < a^2(y_i -0.5) b2(xi+1)<a2(yi0.5)

在这里插入图片描述

而在下一个中点处,不等号改变方向,则说明椭圆弧从区域 Ⅰ Ⅰ 转入了区域 Ⅱ Ⅱ 。 在区域 Ⅱ Ⅱ 内,中点转换为 M Ⅱ ( x i + 0.5 , y i − 1 ) M_Ⅱ (x_i + 0.5, y_i -1) M(xi+0.5,yi1), 用于判断选取 P 1 P1 P1 P r P_r Pr 像素,所以区域 Ⅱ Ⅱ 内椭圆弧中电误差项 d d d 的初始值为

d 2 , 0 = b 2 ( x + 0.5 ) 2 + a 2 ( y − 1 ) 2 − a 2 b 2 d_{2, 0} = b^2(x+0.5)^2 + a^2(y-1)^2 - a^2b^2 d2,0=b2(x+0.5)2+a2(y1)2a2b2

算法

  1. 读入椭圆的长半轴 a a a 和短半轴 b b b
  2. 定义椭圆当前坐标 x x x y y y 定义中点误差项 d 1 d_1 d1 d 2 d_2 d2 定义像素颜色 cColoer
  3. 计算 d 10 = b 2 + a 2 ( − b + 0.25 ) d_{10} = b^2 + a^2(-b+0.25) d10=b2+a2(b+0.25) x = 0 x=0 x=0, y = 0 y=0 y=0cColor=RGB(0, 0, 255)
  4. 绘制点 $(x, y) $及其在四分椭圆中的另外 3个对称点
  5. 判断 d 1 d_1 d1 的符号,若 d 1 < 0 d_1<0 d1<0 ( x , y ) 更新为 (x, y) 更新为 (x,y)更新为 ( x i + 1 , y ) (xi+1, y) (xi+1,y), d 1 d_1 d1 更新为 d 1 + b 2 ( 2 x + 3 ) d_1+b^2(2x+3) d1+b2(2x+3); 否则 ( x , y ) 更新为 (x, y) 更新为 (x,y)更新为 ( x i + 1 , y − 1 ) (xi+1, y-1) (xi+1,y1), d 1 d_1 d1 更新为 d 1 + b 2 ( 2 x + 3 ) + a 2 ( − 2 y + 2 ) d_1+b^2(2x+3) + a^2(-2y+2) d1+b2(2x+3)+a2(2y+2)
  6. b 2 ( x i + 1 ) < a 2 ( y i − 0.5 ) b^2(x_i+1)<a^2(y_i-0.5) b2(xi+1)<a2(yi0.5) 时,重复 (4) 与 (5) 否则转到步骤 (7)
  7. 计算下半部分 d 2 d_2 d2 的初值, d 20 = b 2 ( x + 0.5 ) 2 + a 2 ( y − 1 ) 2 − a 2 b 2 d_{20} = b^2(x+0.5)^2 + a^2(y-1)^2 - a^2 b^2 d20=b2(x+0.5)2+a2(y1)2a2b2
  8. 绘制点 ( x , y ) (x, y) (x,y) 及其在四分椭圆中的另外 3 个对称点
  9. 判断 d 2 d_2 d2 的符号,若 d 2 < 0 d_2 <0 d2<0 ( x , y ) 更新为 (x, y) 更新为 (x,y)更新为 ( x i + 1 , y − 1 ) (xi+1, y-1) (xi+1,y1) d 2 d_2 d2 更新为 d 2 + b 2 2 ( 2 x + 2 ) + a 2 ( − 2 y + 3 ) d_2+b_2^2(2x+2) + a^2(-2y+3) d2+b22(2x+2)+a2(2y+3) 否则 ( x , y ) 更新为 (x, y) 更新为 (x,y)更新为 ( x i + 1 , y ) (xi+1, y) (xi+1,y), d 2 d_2 d2 更新为 d 2 + a 2 ( 2 y + 3 ) d_2+a^2(2y+3) d2+a2(2y+3)
    10.如果 y ≥ 0 y \geq 0 y0 重复步骤 (8) 和 (9)
#include <QApplication>
#include <QPainter>
#include <QWidget>

void EllipsePoint(QPainter * painter, int x, int y) {
    QColor color(255, 0, 0);  // 设置为红色

    // 平移到正确的位置
    int centerX = 400;  // 窗口宽度的一半
    int centerY = 300;  // 窗口高度的一半

    painter->setPen(color);
    painter->drawPoint(centerX+x, centerY+y);
    painter->drawPoint(centerX+x, centerY-y);
    painter->drawPoint(centerX-x, centerY-y);
    painter->drawPoint(centerX-x, centerY+y);


}


void MidPointEllipse(QPainter* painter, int a, int b) {
    int x, y;
    x = 0, y = b;
    double d1 = b * b + a * a * (-b + 0.25);

    EllipsePoint(painter, x, y);

    while (b * b * (x+1) < a * a * (y-0.5)) {

        if (d1 < 0) {
            d1 += b * b * (2*x + 3);
        } else {
            d1 += b*b * (2*x + 3) + a* a*(-2*y +2);
            y--;
        }
        x++;
        EllipsePoint(painter, x, y);
    }
    double d2 = b * b * (x + 0.5) * (x + 0.5) + a * a * (y - 1) * (y -1) - a * a * b *b;
    while (y > 0) {
        if (d2 < 0) {
            d2 += b * b * (2*x + 2) + a * a * (-2*y + 3);
            x++;
        }else {
            d2 += a* a * (-2*y + 3);
        }
        y--;
        EllipsePoint(painter, x, y);
    }

}





class MyWidget : public QWidget {
public:
    MyWidget(QWidget* parent = nullptr) : QWidget(parent) {
        setFixedSize(800, 600);
    }

protected:
    void paintEvent(QPaintEvent* event) override {
        Q_UNUSED(event);

        QPainter painter(this);
        painter.setRenderHint(QPainter::Antialiasing, true);

//        int radius = 50;  // 圆的半径

        int a = 200;
        int b = 100;
//        MidPointCircle(&painter, radius);
        MidPointEllipse(&painter, a, b);

    }
};


int main(int argc, char* argv[]) {
    QApplication app(argc, argv);

    MyWidget widget;
    widget.show();

    return app.exec();
}

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/276878.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

diffusion model (十) anydoor技术小结

paperAnyDoor: Zero-shot Object-level Image Customizationcodehttps://github.com/damo-vilab/AnyDoorOrg香港大学&#xff0c;Alibaba Groupdate2023-07 1 Motivation 过去我们用dreambooth&#xff0c;LORA&#xff0c;textual inversion等方法做定制目标生成。但这个方法…

liunx系统突然不能启动jar

启动命令 nohup java -jar /date/gd_ly/jar/mssda-platform-backend-0.0.1-SNAPSHOT.jar -Dspring.config.location/date/gd_ly/jar/application-dev.yml 报错信息 Error: A JNI error has occurred, please check your installation and try again Exception in thread &q…

2022年全球软件质量效能大会(QECon北京站2022)-核心PPT资料下载

一、峰会简介 当前&#xff0c;新一轮科技革命和产业变革正在重塑全球经济格局&#xff0c;以云计算为代表的新一代信息技术创新活跃&#xff0c;与实体经济深度融合&#xff0c;推动泛在连接、数据驱动、智能引领的数字经济新形式孕育而生。 新兴技术的出现给测试乃至整个软…

CSS 纵向扩展动画

上干货 <template><!-- mouseenter"startAnimation" 表示在鼠标进入元素时触发 startAnimation 方法。mouseleave"stopAnimation" 表示在鼠标离开元素时触发 stopAnimation 方法。 --><!-- 容器元素 --><div class"container&q…

HCIA-Datacom题库(自己整理分类的)——OSPF协议判断

1.路由表中某条路由信息的Proto为OSPF则此路由的优先级一定为10。√ 2.如果网络管理员没有配置骨干区域,则路由器会自动创建骨干区域&#xff1f; 路由表中某条路由信息的Proto为OSPF&#xff0c;则此路由的优先级一定为10。 当两台OSPF路由器形成2-WAY邻居关系时&#xff0…

Arduino串口发送接收和串口中断事件

目录 一、硬件介绍 1、控制器 2、TTL转USB串口 二、软件程序 1、单片机发送字符串 &#xff08;1&#xff09;每个串口对应的类名称介绍 &#xff08;2&#xff09;发送功能 &#xff08;3&#xff09;代码 &#xff08;4&#xff09;测试 2、单片机接收字符串 &…

【 YOLOv5】目标检测 YOLOv5 开源代码项目调试与讲解实战(3)-训练yolov5模型(本地)

训练yolov5模型&#xff08;本地&#xff09; 训练文件 train.py训练如下图 一些参数的设置weights:对于weight参数&#xff0c;可以往Default参数中填入的参数有 cfg&#xff1a;&#xff08;缩写&#xff09;cfg参数可以选择的网络模型 data对于data hyp 超参数epochs 训练多…

全新ui自动化测试框架教学——Cypress

前言 在现阶段自动化测试领域大规模普及的是selenium及appium等常规自动化测试工具&#xff0c;但在其中会有遇到很多影响因素导致测试结果不理想和不准确的情况发生。在经过Darren洋对自动化测试工具调研后&#xff0c;发现了Cypress这一款针对端到端的自动化测试工具&#xf…

【Python基础】字符串

文章目录 [toc]什么是字符串索引示例索引越界 切片语法示例 字符串方法find()方法rfind()方法count()方法replace()方法 个人主页&#xff1a;丷从心 系列专栏&#xff1a;Python基础 什么是字符串 如下定义的变量url存储的是字符串类型的值 url www.baidu.com print(url)u…

【银行测试】金融银行-理财项目面试/分析总结(二)

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 银行理财相关的项…

在Adobe Acrobat上如何做PDF文档签名

Adobe Acrobat如何做PDF文档签名&#xff1f;PDF文档签名是指对PDF文档进行基于证书的数字签名&#xff0c;类似于传统的手写签名&#xff0c;可标识签名文档的人员。与手写签名不同&#xff0c;数字签名难以伪造&#xff0c;因为其包含签名者唯一的加密信息。为PDF文档进行基于…

Starling-LM-7B与GPT-4:开源AI的新纪录

引言 在人工智能的前沿领域&#xff0c;Starling-LM-7B的出现标志着开源大型语言模型&#xff08;LLM&#xff09;的一大突破。与GPT-4的近距离竞争不仅展示了Starling-LM-7B的技术实力&#xff0c;也突显了开源社区在推动AI发展方面的重要作用。 模型特点 Starling-LM-7B&a…

java 企业工程管理系统软件源码+Spring Cloud + Spring Boot +二次开发+ 可定制化

工程项目管理软件是现代项目管理中不可或缺的工具&#xff0c;它能够帮助项目团队更高效地组织和协调工作。本文将介绍一款功能强大的工程项目管理软件&#xff0c;该软件采用先进的Vue、Uniapp、Layui等技术框架&#xff0c;涵盖了项目策划决策、规划设计、施工建设到竣工交付…

通过Python将PDF转为文本,快速提取PDF中的文字

快速高效地从PDF文档中提取信息对于专业人士来说非常重要。处理大量PDF文件时&#xff0c;将PDF转换为可编辑的文本格式可以节省时间和精力。而强大的Python语言正是在这些方面发挥其作用。利用Python中丰富的API&#xff0c;我们可以轻松在Python程序中将PDF转换为文本&#x…

im6ull学习总结(三)文字显示

文字显示 字符编码方式 编码与字体 一个字符以不同编码形式会保存为不同的二进制数。 ASCII American Standard Code for Information Interchange”的缩写&#xff0c;美国信息交换标准代码。 一个字节的 7 位就可以表示 128 个数值&#xff0c;在 ASCII 码中最高位永远是…

天津医科大学临床医学院专升本药学专业有机化学考试大纲

天津医科大学临床医学院高职升本科专业课考试大纲药学专业《有机化学》科目考试大纲 一、考试基本要求 本考试大纲主要要求考生对《有机化学》基本概念有较深入的了解&#xff0c;能够系统地掌握各类化合物的命名、结构特点及立体异构、主要性质、反应、来源和合成制备方法等…

将正规文法转化为正规式

将正规文法转化为正规式有以下几个规则&#xff1a; 通过一道例题来讲解&#xff1a; ①A-->aC|bA ②C-->bD ③D-->aC|bD| (1)首先将②带入③&#xff08;不能将自身带入自身例如D-->aC|bD|,文法中带D&#xff0c;不能带入D&#xff09; DabD|bD|&#xff08;…

用电脑将图片转为excel表格有几种方法?怎么操作?

将图片转为Excel表格&#xff0c;一般需要借助OCR(光学字符识别)技术。OCR技术可以将图片中的文字提取出来&#xff0c;并转换成Excel表格中的数据。以下是几种常用的方法&#xff1a; 一、.使用在线OCR工具 1、打开金鸣表格文字识别&#xff08;简称金鸣识别&#xff09;网站…

第十一章 Stream消息驱动

Stream消息驱动 gitee:springcloud_study: springcloud&#xff1a;服务集群、注册中心、配置中心&#xff08;热更新&#xff09;、服务网关&#xff08;校验、路由、负载均衡&#xff09;、分布式缓存、分布式搜索、消息队列&#xff08;异步通信&#xff09;、数据库集群、…

32阵元 MVDR和DREC DOA估计波束方向图对比

32阵元 MVDR和DREC DOA估计波束方向图对比 一、原理 MVDR原理&#xff1a;https://zhuanlan.zhihu.com/p/457528114 DREC原理&#xff08;无失真响应特征干扰相消器&#xff09;&#xff1a;http://radarst.ijournal.cn/html/2019/3/201903018.html 主要参数&#xff1a; 阵…