Chaikin Curve(球面插值)

 在两条折线间完成平滑的过渡是 用画布做UI 或者做类似地图编辑器一类的工作的 很常见的任务。

怎么样化方为圆是决定工作效率的很重要的因素。(当需要编辑的曲线多起来, 复杂起来的时候,这会是件相当繁重的工作)

最容易想到的莫非是 贝塞尔曲线,而且时下几乎所有主流的数学算法库或者画布api 都已经很好的支持了贝塞尔曲线的绘制。 并能提供很便利的接口,通常只需知道 开始位置, 结束位置 ,以及贝塞尔控制点 就可生成一条贝塞尔曲线。

例如:

context.bezierCurveTo(controlX1, controlY1, controlX2, controlY2, endX, endY); 

贝塞尔曲线的定义是由当前的上下文来看,两个控制点,和结束点。曲线的第一部分是切向的假想线,是由上下文点和第一个控制点定义。第二部分的曲线相切的假想线,是第二个控制点和结束点定义。

但是贝塞尔曲线仍旧属于“高输入”api, 尤其是贝塞尔控制点的定义,其实并不是一个简单就能得到的东西。
而且在实际应用中,通常的需求多为 已知折线,然后把折线转化为曲线的情况。

一般来说,折线我们是最好获得的,得到转折点连接起来就可以了。
但是当折线多起来的时候,会发现按照贝塞尔曲线绘制的思路来绘制平滑的曲线会是一件相当困难的事,光是控制点的确定就是一个大工程。

为了更好的,直接的把折线转化为平滑的曲线。我们还是得回到曲线绘制的根源--- 折线模拟

这就是今天想记录的Chaikin Curve, 插值曲线。

原理:
我们称一条折线的起始和结束的点 为断点, 中间的转折点都叫折点。
于是, 在每个非端点的折点附近取连接这个折点的两条线段各自的1/3位置处新建一个点。并将这两个新建的点连接。
如此重复下去,直到模拟出想要的平滑度。

根据想要的不同的曲线弧度,也可将1/3 替换成 1/4 或1/2 ...

这种方法如此简单,已知一条折线,根据需要定义迭代次数即可得到一条曲线(模拟)。

同时,用这种方式创建的折线还有一个优势,就是很方便的能得到曲线的长度,因为是折线模拟的,所以折线长度之和即为曲线的长度。

也不用担心这种类似二分的迭代方式计算量会有多大。我自己的测试,在800*800的区域通过插值来模拟曲线,基本也就迭代4次就已经足够平滑了。

曲线模拟的过程大致如下的动画:

以上都为随机6个点,迭代模拟4次的过程。

主函数即为下面的 subDivide

    var Point2 = La.geometry.Point2, // Point Class
Vector2 = La.geometry.Vector2, // Vector Class
self = this;

this.subDivide = function (handles, subdivs) {
if (handles.length) {
do {
var numHandles = handles.length;
// 第一个点
handles.push(new Point2(handles[0].x, handles[0].y));

for (var i = 0; i < numHandles - 1; ++i) {
// 每次拿出两个点
var p0 = handles[i];
var p1 = handles[i + 1];

// 根据两个原始点创建两个新点,做插值
var Q = new Point2(0.75 * p0.x + 0.25 * p1.x, 0.75 * p0.y + 0.25 * p1.y);
var R = new Point2(0.25 * p0.x + 0.75 * p1.x, 0.25 * p0.y + 0.75 * p1.y);

handles.push(Q);
handles.push(R);
}
// 最后一个店
handles.push(new Point2(handles[numHandles - 1].x, handles[numHandles - 1].y));

// 更新数组
for (var i = 0; i < numHandles; ++i)
handles.shift();
//handles.shift(numHandles);
} while (--subdivs > 0);
}
};



转载于:https://www.cnblogs.com/hongru/archive/2011/10/27/2226946.html

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

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

相关文章

六、ROI和泛洪填充

一、ROI ROI&#xff1a;region of interest&#xff0c;即感兴趣区域。 一般主要通过numpy来获取ROI 将某区域转变为灰色图片再覆盖原图像 import cv2 import numpy as npsrc cv2.imread(r"G:\Juptyer_workspace\study\opencv\opencv3\a1.jpg") cv2.imshow(&quo…

django 静态数据_如何在Django中使用静态数据?

django 静态数据Static Data means those data items that we cannot want to change, we want to use them as it is like audio, video, images, files etc. 静态数据是指我们不想更改的数据项&#xff0c;我们想像音频&#xff0c;视频&#xff0c;图像&#xff0c;文件等那…

Leetcode226. 翻转二叉树(递归、迭代、层序三种解法)

目录题目1、层序法&#xff1a;2、递归法&#xff1a;1、先序遍历&#xff08;中左右&#xff09;2、后序遍历&#xff08;左右中&#xff09;3、递归中序遍历为什么不行&#xff08;左中右&#xff09;3、迭代法&#xff1a;1、先序遍历2、中序遍历3、后序遍历为什么迭代法的中…

一款jQuery立体感动态下拉导航菜单特效

一款jQuery立体感动态下拉导航菜单特效,鼠标经过&#xff0c;在菜单栏上方下拉出一个背景图片&#xff0c;效果十分不错的一款jquery特效。 对IE6都是兼容的&#xff0c;希望大家好好研究研究。 适用浏览器&#xff1a;IE6、IE7、IE8、360、FireFox、Chrome、Safari、Opera、傲…

七、模糊操作

一、模糊操作基本原理 1&#xff0c;基于离散卷积 2&#xff0c;定义好每一个卷积核 3&#xff0c;不同卷积核得到不同的卷积效果 4&#xff0c;模糊是卷积的一种表象 二、1*3卷积核举例 每次右移一格&#xff0c;进行对应相乘再求和。1*3的卷积核左右两边的元素并没有处理而…

LeetCode 100. 相同的树 思考分析

给定两个二叉树&#xff0c;编写一个函数来检验它们是否相同。 如果两个树在结构上相同&#xff0c;并且节点具有相同的值&#xff0c;则认为它们是相同的。 示例 1: 输入: 1 1 / \ / 2 3 2 3 [1,2,3], [1,2,3]输出: true 示例 2: 输入: 1 1 / 2 2 [1,2], [1,null,2]输…

八、边缘保留滤波(EPF)

一、概念 边缘保留滤波(EPF,edge preserving filtering) 二、高斯双边 cv2.bilateralFilter(image,0,100,15)100为差异&#xff0c;15为周围的区域 import cv2 import numpy as npdef bilateralFilter(image):dst cv2.bilateralFilter(image,0,100,15)cv2.imshow(bilater…

九、图像直方图

一、图像直方图的属性 说白了就是将图像上的各个颜色通道上的像素点的像素值进行统计&#xff0c;例如&#xff1a;像素值为14的像素点个数有几个&#xff0c;进行显示。 图像的像素值取值范围为[0,255]&#xff0c;这个范围也成为直方图的range也就是直方图的横坐标轴 每一个…

BIFR的完整形式是什么?

BIFR&#xff1a;工业和金融重组委员会 (BIFR: Board of Industrial and Financial Reconstruction) BIFR is an abbreviation of the Board of Industrial and Financial Reconstruction. It was an organization of the Government of India and a branch of the Department …

LeetCode 101. 对称二叉树 思考分析

题目 给定一个二叉树&#xff0c;检查它是否是镜像对称的。 例如&#xff0c;二叉树 [1,2,2,3,4,4,3] 是对称的。 1/ 2 2 / \ / 3 4 4 3 但是下面这个 [1,2,2,null,3,null,3] 则不是镜像对称的: 1/ 2 2 \ 3 3 进阶&#xff1a; 你可以运用递归和迭代两种方法解决这个…

直方图反向投影

通过直方图反向投影&#xff0c;根据目标衣服颜色的特征来进行定位 cv2.calcHist([roi_hsv],[0,1],None,[32,48],[0,180,0,256])其中[32,48]表示bin的个数&#xff0c;可以修改&#xff0c;当然范围越小越精确 import cv2 import numpy as np from matplotlib import pyplot …

LeetCode 二叉树、N叉树的最大深度与最小深度(递归解)

目录104. 二叉树的最大深度559. N叉树的最大深度111. 二叉树的最小深度之前的笔记中&#xff0c;已经用层序遍历解决过这个问题了现在试着用深度的解法去求解104. 二叉树的最大深度 给定一个二叉树&#xff0c;找出其最大深度。 二叉树的深度为根节点到最远叶子节点的最长路径…

十、模板匹配

一、概念 模板匹配就是在整个图像区域发现与给定子图像匹配的小块区域。 需要首先给定一个模板图像A&#xff0c;和一个待检测图像B。 在待检测图像B上&#xff0c;从左往右&#xff0c;从上往下计算待检测图像B和模板图像A所重叠的匹配度&#xff0c;匹配度越高则两者相同的可…

基于WF的意见征集4(浅析)

接口项目&#xff1a;IClass&#xff08;项目名称&#xff09; HTHuiFuusing System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Workflow.Runtime;using System.Workflow.Activities;namespace IClass{ /// <summary> /…

那些VisualStudio隐藏的调试功能

VisualStudio是一个强大的调试工具&#xff0c;里面很多隐藏功能少有人问津&#xff0c;但是在特定场景可以节省你很多时间&#xff0c;本文主要介绍一些VisualStudio调试相关的隐藏功能&#xff0c;欢迎大家补充。 运行到指针(Run to cursor) 大多数人用Visual Studio在调试程…

十一、图像二值化

一、二值图像 其实就是把图像转换为只有黑白的两种颜色图像&#xff0c;即像素值非零即一 三角阈值二值化 对一个图像进行操作&#xff0c;获取图像的直方图&#xff0c;找到波峰和波谷进行连线设为线段A&#xff0c;每个点做有关线段A的垂线垂足在线段A上&#xff0c;最后将…

地毯店 如何辨别地毯的好坏?

在实地选购地毯品牌时&#xff0c;许多地方需要引起注意&#xff0c;而且要显得专业&#xff0c;这样才能科学深入地辨别地毯的好坏。比如&#xff0c;辨明拉绞地毯和抽绞地毯两种工艺的打结方法几乎相同&#xff0c;只是变绞形式上有所区别。抽绞的方式较古老&#xff0c;一般…

十二、图像金字塔

一、原理 reduce高斯模糊降采样 expand扩大卷积 PyrDown&#xff1a;降采样 PyrUp&#xff1a;还原 二、高斯金字塔 import cv2 import numpy as np from matplotlib import pyplot as pltdef pyramid(image):level 3temp image.copy()pyramid_image []for i in range(le…

LeetCode 110. 平衡二叉树思考分析

题目 给定一个二叉树&#xff0c;判断它是否是高度平衡的二叉树。 本题中&#xff0c;一棵高度平衡二叉树定义为&#xff1a; 一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过1。 示例 1: 给定二叉树 [3,9,20,null,null,15,7] 3 / 9 20 / 15 7 返回 true 。 示例 2…

十三、图像梯度

一、两种算子 一阶导数—Sobel算子 水平梯度&#xff1a; 垂直梯度&#xff1a; 最终图像梯度&#xff1a; 二阶导数—Laplacian算子 在二阶导数的时候&#xff0c;最大变化处的值为零&#xff0c;即边缘是零值。 常见的拉普拉斯算子&#xff1a;、其所有元素之和为零。…