GL绘制自定义线条2_手写曲线应用贝塞尔曲线

news2024/11/17 15:48:17

        上一篇文章的曲线是由触摸点直接生成的,但触摸点并非连续的,而是离散的,而且屏幕触摸点采样的间隔时间其实不短,因此如果单纯只用触摸点生成OpenGL触摸曲线,在高速书写时会导致曲线看起来就像多个线段合起来一样(事实也是如此)。

        为了解决这个问题,最好的办法就是像Path一样使用Bezier曲线,以三次触摸坐标记录为关键点补间出相对更细密的曲线坐标,从而使线段变得更光滑。

        二次贝塞尔曲线的原理:

        假定我现在有3个顶点(P0、P1、P2),想以曲线的方式进行绘制其路径,那么可以从P0到P1、P1到P2两个线段,按照同样的百分比步进量,沿着这两个线段对应百分比的位置连接为一个新的线段(图中绿色部分),然后取这个线段同样百分比位置的坐标,将这些坐标连城线即可得到一端曲线。

 

 

推导:

        但现在要面临的是不定数目的线条顶点,如何才能使用二次贝塞尔曲线连成一个光滑的曲线呢?

        首先像下图这样,画完一段曲线后,关键点全部顺移一个序号,肯定是无法收尾相接的,因为两个曲线段之间断开了:

        克服办法也不难想到,每段线段起始的位置,都把上一次使用的P0和P1向量相加之后除以2,即可让下一段曲线的起始段和之前曲线的结尾段结合起来了。

        关键代码如下:

        二次贝塞尔关键点的计算:

PointF keyPoint0 = new PointF((mBezierKeyPoint0[0] + mBezierKeyPoint1[0]) / 2f, (mBezierKeyPoint0[1] + mBezierKeyPoint1[1]) / 2f);
PointF keyPoint1 = new PointF(mBezierKeyPoint1[0], mBezierKeyPoint1[1]);
PointF keyPoint2 = new PointF((x + mBezierKeyPoint1[0]) / 2f, (y + mBezierKeyPoint1[1]) / 2f);
List<PointF> points = bezierCalc(new PointF[] {keyPoint0, keyPoint1, keyPoint2});

        二次贝塞尔曲线点计算方法:

private List<PointF> bezierCalc(PointF[] keyPointP) {
    List<PointF> points = new LinkedList<>();
    double t = 0.1f; //步进
    for (double k = 0; k <= 1f; k += t) {
        double r = 1 - k;
        double x = Math.pow(r, 2) * keyPointP[0].x + 2 * k * r * keyPointP[1].x
                + Math.pow(k, 2) * keyPointP[2].x;
        double y = Math.pow(r, 2) * keyPointP[0].y + 2 * k * r * keyPointP[1].y
                + Math.pow(k, 2) * keyPointP[2].y;
        points.add(new PointF((float) x, (float) y));
    }
    return points;
}

        再把上述算法插入到上次的GL线条绘制代码中,在生成线条顶点之前通过以上算法插值平滑一下,最后结果如下:

 

 

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

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

相关文章

为何ChatGPT一出现让巨头们都坐不住?

近几个月来&#xff0c;ChatGPT都是当仁不让的舆论话题。 上一次AI在全球范围内引起轰动&#xff0c;还是谷歌的AI机器人AlphaGO下棋战胜围棋世界冠军的时候。 ChatGPT的出现&#xff0c;让国内外几乎所有的科技巨头都坐立不安。 2月1日&#xff0c;谷歌母公司Alphabet首席执…

C++跨平台“点绘机” 代码解读

前言 球球大作战可以自定义皮肤&#xff0c;用画刷绘制。 想着用软件来绘制。 初次尝试&#xff0c;没有达成最终目的&#xff0c;不过也有很大收获。 仓库链接&#xff1a;https://github.com/sixsixQAQ/dolphin 问题 这个半成品&#xff0c;已经有了基本结构了&#xff…

高德地图api 地理编码(地址-->坐标)geocoder.getLocation在官方可以测试出结果,下载代码到本地却用不了 问题解决

问题 高德地图api 地理编码&#xff08;地址-->坐标&#xff09;功能&#xff0c;通过输入 地址信息 得到 经纬度信息。geocoder.getLocation在官方可以测试出结果&#xff0c;下载代码到本地却用不了。 官方示例测试&#xff0c;可以从地址得到坐标 下载官方代码本地运行却…

常见注意力机制解析

1.Squeeze-and-Excitation&#xff08;SE&#xff09; SE的主要思想是通过对输入特征进行压缩和激励&#xff0c;来提高模型的表现能力。具体来说&#xff0c;SE注意力机制包括两个步骤&#xff1a;Squeeze和Excitation。在Squeeze步骤中&#xff0c;通过全局平均池化操作将输…

【2023年Mathorcup杯数学建模竞赛C题】电商物流网络包裹应急调运与结构优化--完整作品分享

1.问题背景 2.论文摘要 为了应对电商物流网络中物流场地和线路电商物流网络中物流场地和线路上货量波动的情况&#xff0c; 设计合理的物流网络调整方案以保障物流网络的正常运行。本文运用 0-1 整数规划模型&#xff0c;多目标动 态规划模型&#xff0c;给出了问题的结果。 针…

深入讲解eMMC简介

1 eMMC是什么 eMMC是embedded MultiMediaCard的简称&#xff0c;即嵌入式多媒体卡,是一种闪存卡的标准&#xff0c;它定义了基于嵌入式多媒体卡的存储系统的物理架构和访问接口及协议&#xff0c;具体由电子设备工程联合委员会JEDEC订立和发布。它是对MMC的一个拓展&#xff0…

redi缓存使用

1、缓存的特征 第一个特征&#xff1a;在一个层次化的系统中&#xff0c;缓存一定是一个快速子系统&#xff0c;数据存在缓存中时&#xff0c;能避免每次从慢速子系统中存取数据。 第二个特征&#xff1a;缓存系统的容量大小总是小于后端慢速系统的&#xff0c;不可能把所有数…

GAMES101 计算机图形学 | 学习笔记 (上)

目录 环境安装什么是计算机图形学物体上点的坐标变换顺序齐次坐标光栅化如何判定一个点在三角形内光栅化填充三角形示例代码光栅化产生的问题 采样不足&#xff08;欠采样&#xff09;导致锯齿抗锯齿滤波算法 环境安装 1. C中安装opencv库 2. C中安装eigen库 3. C中安装open…

ChatGPT调教指北,技巧就是效率!

技巧就是效率 很多人都知道ChatGPT很火很强&#xff0c;几乎无所不能&#xff0c;但跨越了重重门槛之才有机会使用的时候却有些迷茫&#xff0c;一时间不知道如何使用它。如果你就是把他当作一个普通的智能助手来看待&#xff0c;那与小爱同学有什么区别&#xff1f;甚至还差劲…

热乎的面经——踏石留印

⭐️前言⭐️ 本篇文章记录博主面试北京某公司所记录的面经&#xff0c;希望能给各位带来帮助。 &#x1f349;欢迎点赞 &#x1f44d; 收藏 ⭐留言评论 &#x1f4dd;私信必回哟&#x1f601; &#x1f349;博主将持续更新学习记录收获&#xff0c;友友们有任何问题可以在评论…

Origin如何绘制三维图形?

文章目录 0.引言1.使用矩阵簿窗口2.三维数据转换3.三维绘图4.三维曲面图5.三维XYY图6.三维符号、条状、矢量图7.等高线图 0.引言 因科研等多场景需要&#xff0c;绘制专业的图表&#xff0c;笔者对Origin进行了学习&#xff0c;本文通过《Origin 2022科学绘图与数据》及其配套素…

63.空白和视觉层级的实战应用

例如看我们之前的小网页&#xff1b; 这些标题的上下距离一样&#xff0c;这样让我们很容易对这些标题进行混淆&#xff0c;我们可以适当的添加一点空白 header, section {margin-bottom: 96px; }这样看上去似乎就好很多&#xff01; 除此之外&#xff0c;如我们之间学的空…

【line features】线特征

使用BinaryDescriptor接口提取线条并将其存储在KeyLine对象中&#xff0c;使用相同的接口计算每个提取线条的描述符&#xff0c;使用BinaryDescriptorMatcher确定从不同图像获得的描述符之间的匹配。 opencv提供接口实现 线提取和描述符计算 下面的代码片段展示了如何从图像中…

K8S相关核心概念

个人笔记&#xff1a; 要弄明白k8s的细节&#xff0c;需要知道k8s是个什么东西。它的主要功能&#xff0c;就是容器的调度--也就是把部署实例&#xff0c;根据整体资源的使用状况&#xff0c;部署到任何地方 注意任何这两个字&#xff0c;预示着你并不能够通过常规的IP、端口…

如何全面学习Object-C语言的语法知识 (Xmind Copilot生成)

网址&#xff1a;https://xmind.ai/login/ 登录后直接输入&#xff1a;如何全面学习Object-C语言的语法知识&#xff0c;就可以生成大纲 点击右上角的 按钮&#xff0c;可以显示md格式的问题&#xff0c;再点击生成全文&#xff0c;就可以生成所有内容了&#xff0c; 还有这个…

CentOS7/8 安装 5+ 以上的Linux kernel

CentOS以稳定著称&#xff0c;稳定在另外一方面就是保守。所以CentOS7还在用3.10&#xff0c;CentOS8也才是4.18。而当前最新的Linux Kernel都更新到6.0 rc3了。其他较新的发行版都用上了5.10的版本。本文简单介绍如何在CentOS7、8上直接安装5.1以上版本的第三方内核。 使用ted…

5.8晚间黄金行情走势分析及短线交易策略

近期有哪些消息面影响黄金走势&#xff1f;本周黄金多空该如何研判&#xff1f; ​黄金消息面解析&#xff1a;周一亚洲时段&#xff0c;现货黄金小幅反弹&#xff0c;目前交投于2024.3美元/盎司附近&#xff0c;一方面是金价上周五守住了 2000 整数关口&#xff0c;逢低买盘涌…

java环境Springboot框架中配置使用GDAL,并演示使用GDAL读取shapefile文件

GDAL是应用广泛的空间数据处理库&#xff0c;可以处理几何、栅格数据&#xff0c;Springboot是常用的JAVA后端开发框架。本文讲解如何在Springboot中配置使用GDAL。本文示例中使用的GDAL版本为3.4.1&#xff08;64位&#xff09; 图1 GDAL读取shp效果 一、部署GDAL类库 将GDA…

什么是点对点传输?什么是点对多传输

点对点技术&#xff08;peer-to-peer&#xff0c; 简称P2P&#xff09;又称对等互联网络技术&#xff0c;是一种网络新技术&#xff0c;依赖网络中参与者的计算能力和带宽&#xff0c;而不是把依赖都聚集在较少的几台服务器上。P2P网络通常用于通过Ad Hoc连接来连接节点。这类网…

WiFi(Wireless Fidelity)基础(四)

目录 一、基本介绍&#xff08;Introduction&#xff09; 二、进化发展&#xff08;Evolution&#xff09; 三、PHY帧&#xff08;&#xff08;PHY Frame &#xff09; 四、MAC帧&#xff08;MAC Frame &#xff09; 五、协议&#xff08;Protocol&#xff09; 六、安全&#x…