bezier曲线拟合椭圆弧线

椭圆弧线用bezier曲线拟合 。
先计算出 椭圆中心 起始角度 旋转角度

S t e p 1 : C o m p u t e ( x 1 ′ , y 1 ′ ) Step 1: Compute(x'_1, y'_1) Step1:Compute(x1,y1)
( x 1 ′ y 1 ′ ) = ( cos ⁡ φ sin ⁡ φ − sin ⁡ φ cos ⁡ φ ) ⋅ ( x 1 − x 2 2 y 1 − y 2 2 ) \begin{pmatrix} x'_1 \\ \\ y'_1 \end{pmatrix} = \begin{pmatrix} \cos\varphi & \sin\varphi \\ \\ -\sin\varphi & \cos\varphi \end{pmatrix} \cdot \begin{pmatrix} \dfrac{ x_1-x_2}{2} \\ \\ \dfrac{ y_1-y_2}{2} \end{pmatrix} x1y1 = cosφsinφsinφcosφ 2x1x22y1y2

S t e p 2 : C o m p u t e ( c x ′ , c y ′ ) Step 2: Compute(c'_x, c'_y) Step2:Compute(cx,cy)
( c x ′ c y ′ ) = ± r x 2 y y 2 − r x 2 ( y 1 ′ ) 2 − r y 2 ( x 1 ′ ) 2 r x 2 ( y 1 ′ ) 2 + r y 2 ( x 1 ′ ) 2 ( r x y 1 ′ r y − r y x 1 ′ r x ) \begin{pmatrix} c'_x \\ \\ c'_y \end{pmatrix} = \pm \sqrt { \dfrac{ r^2_x y^2_y - r^2_x(y'_1)^2 - r^2_y (x'_1)^2} {r^2_x (y'_1)^2 + r^2_y(x'_1)^2 } } \begin{pmatrix} \dfrac{ r_xy'_1}{r_y} \\ \\ -\dfrac{ r_y x'_1}{r_x} \end{pmatrix} cxcy =±rx2(y1)2+ry2(x1)2rx2yy2rx2(y1)2ry2(x1)2 ryrxy1rxryx1

在这里插入图片描述

然后拟合
在这里插入图片描述

在这里插入图片描述

附代码

#include <math.h>
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>#define MAX(a, b) (((a) > (b)) ? (a) : (b))
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
#define PI 3.1415926static float angle(float ux, float uy, float vx, float vy) {   float res = (ux*vx + uy*vy)/sqrtf((ux*ux+uy*uy)*(vx*vx+vy*vy));res = MIN(MAX(res,-1),1);  //-1 <= res <= 1;float a ; if ((ux*vy - uy*vx) < 0)a = -acosf(res);elsea = acosf(res);return a;
}static int calcEllipse(float rx, float ry, float ph, int fa, int fs, float x1, float y1, float x2, float y2, float* pcx, float* pcy, float* pth, float* pdth) 
{if (!rx || !ry) return -1; rx = (rx > 0) ? rx : -rx;ry = (ry > 0) ? ry : -ry;float xp, yp; {   float tx = (x1 - x2) / 2;float ty = (y1 - y2) / 2;xp = cosf(ph)*tx + sinf(ph)*ty;yp = -sinf(ph)*tx + cosf(ph)*ty;float lambda = xp*xp/(rx*rx) + yp*yp/(ry*ry);if (lambda > 1) {lambda = sqrtf(lambda);rx = lambda*rx;ry = lambda*ry;}}float cx,cy;float th, dth;{float pr;{float tp = rx*rx*yp*yp + ry*ry*xp*xp;pr = sqrtf((rx*rx*ry*ry - tp)/tp);}float cxp,cyp;if (fa != fs) {cxp =  pr * rx * yp / ry;cyp = -pr * ry * xp / rx;} else {cxp = -pr * rx * yp / ry;cyp =  pr * ry * xp / rx;}cx = cosf(ph)*cxp - sinf(ph)*cyp + (x1+x2)/2;cy = sinf(ph)*cxp + cosf(ph)*cyp + (y1+y2)/2;th = angle(1, 0, (xp - cxp) / rx, (yp - cyp) / ry);dth = angle((xp-cxp)/rx,(yp-cyp)/ry,(-xp-cxp)/rx,(-yp-cyp)/ry);dth = fmod(dth,2*PI);}if ( fs==0 && dth > 0)dth -= 2*PI;if ( fs==1 && dth < 0)dth += 2*PI;*pcx = cx;*pcy = cy;*pth = th;*pdth = dth;return 0;
}
//  EFAULT pathname points outside your accessible address space
static int adrNotValid(void* p)
{int fd = open(p, 0, 0);int e = errno;if (fd == -1 && e == EFAULT)return 1;else if (fd != -1)close(fd);return 0;
}static int _bezierEllipse(float cx, float cy, float rx, float ry,float th, float sth, float eth,float* res)
{if(!res || adrNotValid(res) || adrNotValid(&res[5]))return -1;float x1 = cx + rx * cosf(th)*cosf(sth) - ry * sinf(th)*sinf(sth);float y1 = cy + rx * sinf(th)*cosf(sth) + ry * cosf(th)*sinf(sth);float x2 = cx + rx * cosf(th)*cosf(eth) - ry * sinf(th)*sinf(eth);float y2 = cy + rx * sinf(th)*cosf(eth) + ry * cosf(th)*sinf(eth);float dx1 = -1 * rx * cosf(th) * sinf(sth) - ry * sinf(th) * cosf(sth);float dy1 = -1 * rx * sinf(th) * sinf(sth) + ry * cosf(th) * cosf(sth);float dx2 = -1 * rx * cosf(th) * sinf(eth) - ry * sinf(th) * cosf(eth);float dy2 = -1 * rx * sinf(th) * sinf(eth) + ry * cosf(th) * cosf(eth);float tmp = tan((eth-sth)/2);float alpha = sinf(eth - sth)*(sqrtf(4+3*tmp*tmp)-1)/3;//   *res++ = x1;//   *res++ = y1;*res++ = x1 + alpha*dx1; // p1x*res++ = y1 + alpha*dy1; // p1y*res++ = x2 - alpha*dx2; // p2x*res++ = y2 - alpha*dy2; // p2y*res++ = x2;*res++ = y2;return 0;
}int bezierEllipse(float cx, float cy, float rx, float ry,float th, float sth, float eth, int n,float* res)
{if (n <= 0 || sth == eth) return -1;float step = (eth - sth)/n;float tmp = sth;for (int i = 0; i < n; i++) {int e = _bezierEllipse(cx, cy, rx, ry,th, tmp, tmp+step,res);if (e) return -1;tmp += step;res += 6;}return 0;
}int main()
{float rx = 50;float ry = 40;float phi = -120.0/180 * PI ;float x1 = 100;float y1 = 80;float x2 = 120;float y2 = 60;float cx,cy,th,dth;calcEllipse( rx, ry, phi, 1, 0, x1, y1, x2, y2,&cx,&cy,&th,&dth);printf("%f %f %f %f\n",cx,cy,th,dth);int dn = ceilf(((dth > 0)? dth : -dth)  * 4 / PI) ;if (dn < 1)return 0;int size = 2+6*dn;float* data = (float*)malloc(size*sizeof(float));data[0] = x1;data[1] = y1;bezierEllipse(cx, cy, rx, ry,phi, th, th+dth, dn,data+2);data[size-2] = x2;data[size-1] = y2;printf("M %f %f ",x1,y1);for(int i = 0; i < dn; i++) {printf(" C ");for(int j = 0; j < 6; j++)printf(" %f ",data[2+6*i+j]);}printf("\n");
}

拟合圆 椭圆 测试结果
在这里插入图片描述

参考 https://www.w3.org/TR/SVG/implnote.html
https://paperzz.com/doc/7611457/drawing-an-elliptical-arc-using-polylines–quadratic-or

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

some/ip CAN CANFD

关于SOME/IP的理解 在CAN总线的车载网络中&#xff0c;通信过程是面向信号的 当ECU的信号的值发生了改变&#xff0c;或者发送周期到了&#xff0c;就会发送消息&#xff0c;而不考虑接收者是否需要&#xff0c;这样就会造成总线上出现不必要的信息&#xff0c;占用了带宽 …

RabbitMQ详细讲解

目录 4.0 AMQP协议的回顾 4.1 RabbitMQ支持的消息模型 4.2 引入依赖 4.3 第一种模型(直连) 1. 开发生产者 2. 开发消费者 3. 参数的说明 4.4 第二种模型(work quene) 1. 开发生产者 2.开发消费者-1 3.开发消费者-2 4.测试结果 5.消息自动确认机制 4.5 第三种模型(…

开源表单设计器vue-form-design自动化校验实现原理

表单校验可以改善用户体验和减轻服务器的压力, 而动态配置表单校验能极大的提高动态表单的扩展性、灵活性, 满足多样性、差异化需求 目标 &#x1f44c;&#xff0c;首先我们简要说下要实现的目标功能&#xff1a; 具有基础的表单验证功能提供一些内置验证规则提供对外开放的…

用OceanBase binlog service 轻松进行数据回滚

背景 在日常的数据库运维过程中&#xff0c;难免会遭遇数据误操作的情形&#xff0c;比如因疏忽而执行了非预期的delete或update操作&#xff0c;这时就需要进行数据回滚。如果在OceanBase中启用了回收站功能&#xff0c;并设置了合适的undo_retention&#xff0c;那么我们可以…

jmx_prometheus_javaagent-0.19.0.jar+Prometheus+Grafana 监控Tongweb嵌入式(by lqw)

文章目录 1.思路2.部署准备3.应用jar包修改配置和导入tw嵌入式的依赖&#xff08;参考&#xff09;4.Prometheus部署5.Prometheus配置6.安装和配置Grafana 1.思路 Tongweb嵌入式最终是把依赖打入到java应用&#xff08;也就是jar包里&#xff09;&#xff0c;然后启动jar包进行…

单片机LED灯闪烁

延时函数计算&#xff08;相关代码生成&#xff09;&#xff1a; #include "reg52.h" #include <INTRINS.H> void Delay500ms() //11.0592MHz {unsigned char i, j, k;_nop_();_nop_();i 22;j 3;k 227;do{do{while (--k);} while (--j);} while (--i); }vo…

让扣你代码的人电脑关机-js反爬

文案 让扣你代码的人电脑关机&#xff0c;赶紧学起来。众所周知。浏览器中无法导入模块&#xff0c;会报错。nodejs中可以导入模块。那么我们可以在导入语句后加入整蛊代码。在捕获异常后执行正常的代码。那么代码在浏览器中就会正常执行&#xff0c;而当你在本地环境中执行的…

Docker常用命令!!!

一、docker基础命令 1、启动docker systemctl start docker 2、关闭docker systemctl stop docker 3、重启docker systemctl restart docker 4、docker设置随服务启动而自启动 systemctl enable docker 5、查看docker 运行状态 systemctl status docker 6、查看docker 版本号信…

Microsoft Edge浏览器Internal Server Error问题解决

网页无法在Microsoft Edge浏览器&#xff0c;尝试Google浏览器可以&#xff0c;排除服务器问题&#xff0c;应该是浏览器本身的问题。 一般这种都是和cookie有关&#xff0c;尝试删除记录 解决&#xff01;

【MQTT】Vue中使用mqtt

MQTT&#xff08;Message Queuing Telemetry Transport&#xff09;作为一种轻量级、开放、灵活、简单、易于实现的通信协议。它基于发布/订阅&#xff08;Publish/Subscribe&#xff09;模式的消息传输协议&#xff0c;在上位机和硬件设备间通信时经常用到。虽然在嵌入式软件一…

【图解物联网】第4章 先进的感测技术

4.1 逐步扩张的传感器世界 在前面的章节中&#xff0c;传感器的概念是“用来获取温度和湿度等纯数据的电子零件”。温度传感器和加速度传感器等确实是用来获取简单数据的小零件&#xff0c;我们可以将其理解为构成智能手机等电子设备的一个要素。 然而&#xff0c;随…

分布式文件存储与数据缓存(二)| Redis

目录 Redis概述_什么是NoSQLNoSQL的四大分类KV型NoSql&#xff08;代表----Redis&#xff09;列式NoSql&#xff08;代表----HBase&#xff09;文档型NoSql&#xff08;代表----MongoDB&#xff09;搜索型NoSql&#xff08;代表----ElasticSearch&#xff09; 关系型数据库和非…

Aspose.PDF功能演示:在 JavaScript 中优化 PDF 文件

PDF 文件是一种普遍存在的文档共享格式&#xff0c;但它们有时可能会很大&#xff0c;导致加载时间变慢并增加存储要求。优化 PDF 文件对于确保无缝的用户体验至关重要&#xff0c;尤其是在 Web 应用程序中。因此&#xff0c;在这篇博文中&#xff0c;我们将探讨如何使用 JavaS…

NCV4266ST50T3G线性稳压器芯片中文资料规格书PDF数据手册引脚图参数图片价格

产品概述&#xff1a; NCV4266 是一款集成了 150 mA 输出电流的低漏稳压器系列&#xff0c;可用于严酷汽车环境。它包括了较宽的运行温度范围和输出电压范围。该器件提供 3.3 V、5.0 V 固定电压版本&#xff0c;以及可调电压版本&#xff0c;输出电压准确度为 2%。它具有较高的…

IDEA 下载依赖包源码报错 Cannot download sources Sources not found for:XXX

最近在做一个功能的时候想看一个库的源码&#xff0c;结果源码下不下来&#xff0c;报Cannot download sources Sources not found for:XXX,网上搜了半天&#xff0c;也找不到靠谱的结论 后来想了下&#xff0c;应该是镜像那边出了问题&#xff0c;把镜像一删&#xff0c;源码…

HTML静态网页成品作业(HTML+CSS)——非遗徽州木雕网页(6个页面)

&#x1f389;不定期分享源码&#xff0c;关注不丢失哦 文章目录 一、作品介绍二、作品演示三、代码目录四、网站代码HTML部分代码 五、源码获取 一、作品介绍 &#x1f3f7;️本套采用HTMLCSS&#xff0c;未使用Javacsript代码&#xff0c;共有6个页面。 二、作品演示 三、代…

Linux nginx 域名申请证书后无法使用(无法访问此网站)阿里云域名

首先我们一步排除 1、域名备案是否成功&#xff1f; 网站备案_ICP备案_备案迁移_备案-阿里云 2、域名是否解析&#xff08;我就是错在这里&#xff09; 阿里云登录 - 欢迎登录阿里云&#xff0c;安全稳定的云计算服务平台 3、是否申请证书成功&#xff1f; 4、nginx是否支持…

【云原生 • Kubernetes】认识 k8s、k8s 架构、核心实战

文章目录 Kubernetes基础概念1. 是什么2. 架构2.1 工作方式2.2 组件架构 3. k8s组件创建集群步骤一 基础环境步骤二 安装kubelet、kubeadm、kubectl步骤三 主节点使用kubeadm引导集群步骤四 副节点加入主节点步骤五 部署dashboard Kubernetes核心实战1. 资源创建方式2. Namespa…

Beamer模板——基于LaTeX制作学术PPT

Beamer模板——基于LaTeX制作学术PPT 介绍Beamer的基本使用安装和编译用于学术汇报的模板项目代码模板效果图 Beamer的高级特性动态效果分栏布局定理环境 介绍 在学术领域&#xff0c;演示文稿是展示和讨论研究成果的重要方式。传统的PowerPoint虽然方便&#xff0c;但在处理复…

python爬虫之爬虫入门

import requests rrequests.get("http://www.baidu.com") print(r.status_code)#用status_code来确定页面状态是否正常 type(r) r.headers requests库入门 status_code可以用来检验网页状态是否正常type(r)返回r的类型r.headers返回该页面头部信 运行结果如下&#x…