对于绘图应用程序,我将鼠标移动坐标保存到数组,然后使用lineTo绘制它们.生成的线条不平滑.如何在所有聚集点之间生成单条曲线?
我用谷歌搜索但我只找到了3个绘制线的函数:对于2个样本点,只需使用lineTo.对于3个样本点,quadraticCurveTo,对于4个样本点,bezierCurveTo.
(我尝试在阵列中每4个点绘制一个bezierCurveTo,但这会导致每4个采样点扭结,而不是连续的平滑曲线.)
如何编写一个函数来绘制一个包含5个样本点的平滑曲线?
我正在玩绘图路径,我注意到至少在某些情况下,UIBezierPath优于我认为的Core Graphics等价物.-drawRect:下面的方法创建两个路径:一个UIBezierPath和一个CGPath.除了它们的位置之外,路径是相同的,但是抚摸CGPath所需的时间大约是抚摸UIBezierPath的两倍.
- (void)drawRect:(CGRect)rect
{
CGContextRef ctx = UIGraphicsGetCurrentContext();
// Create the two paths, cgpath and uipath.
CGMutablePathRef cgpath = CGPathCreateMutable();
CGPathMoveToPoint(cgpath, NULL, 0, 100);
UIBezierPath *uipath = [[UIBezierPath alloc] init];
[uipath moveToPoint:CGPointMake(0, 200)];
// Add 200 curve segments to each path.
int iterations = 200;
CGFloat cgBaseline = 100;
CGFloat uiBaseline = 200;
CGFloat xincrement = self.bounds.size.width / iterations;
for (CGFloat x1 = 0, x2 = xincrement;
x2 < self.bounds.size.width;
x1 = x2, x2 += xincrement)
{ …Run Code Online (Sandbox Code Playgroud) 我们有一个起点(x,y)和一个圆半径.还存在可以从贝塞尔曲线点创建路径的引擎.
如何使用Bézier曲线创建圆?
在移动的过程中,如何在iOS绘图应用程序中平滑一组点?我尝试过UIBezier路径,但是当我只移动1,2,3,4 - 2,3,4,5点时,我得到的是它们相交的锯齿状末端.我听说过样条曲线和所有其他类型.我对iPhone编程很新,不懂如何在我的石英绘图应用程序中编程.一个坚实的例子将非常感激,我花了几个星期的圈子运行,我似乎永远不会找到任何iOS代码来完成这项任务.大多数帖子只链接到维基百科上的java模拟或页面关于曲线拟合,这对我没有任何作用.另外我不想切换到openGL ES.我希望有人能够最终提供代码来回答这个流传的问题.
这是我在UIBezierPath的代码,它在交叉点处留下了边缘///
更新到下面的答案
#define VALUE(_INDEX_) [NSValue valueWithCGPoint:points[_INDEX_]]
#define POINT(_INDEX_) [(NSValue *)[points objectAtIndex:_INDEX_] CGPointValue]
- (UIBezierPath*)smoothedPathWithGranularity:(NSInteger)granularity
{
NSMutableArray *points = [(NSMutableArray*)[self pointsOrdered] mutableCopy];
if (points.count < 4) return [self bezierPath];
// Add control points to make the math make sense
[points insertObject:[points objectAtIndex:0] atIndex:0];
[points addObject:[points lastObject]];
UIBezierPath *smoothedPath = [self bezierPath];
[smoothedPath removeAllPoints];
[smoothedPath moveToPoint:POINT(0)];
for (NSUInteger index = 1; index < points.count - 2; index++)
{
CGPoint p0 = POINT(index - 1);
CGPoint p1 = POINT(index); …Run Code Online (Sandbox Code Playgroud) 我目前正在使用Bezier曲线和曲面来绘制着名的犹他州茶壶.使用16个控制点的Bezier贴片,我已经能够绘制茶壶并使用"世界到相机"功能显示它,这使得能够旋转生成的茶壶,并且目前正在使用正交投影.
结果是我有一个"扁平"茶壶,预计正投影的目的是保持平行线.
但是,我想使用透视投影来给出茶壶深度.我的问题是,如何从"世界到相机"函数返回3D xyz顶点,并将其转换为2D坐标.我想在z = 0时使用投影平面,并允许用户使用键盘上的箭头键确定焦距和图像大小.
我在java中编程并设置了所有输入事件处理程序,并且还编写了一个处理基本矩阵乘法的矩阵类.我已经阅读了维基百科和其他资源一段时间,但我无法完全了解如何执行此转换.
我一直致力于二维连续数据的可视化项目.这是您可以用来研究2D地图上的高程数据或温度模式的类型.从本质上讲,它实际上是一种将三维平面化为二维加彩色的方法.在我的特定研究领域,我实际上并没有处理地理高程数据,但这是一个很好的比喻,所以我会在这篇文章中坚持下去.
无论如何,在这一点上,我有一个"连续颜色"渲染器,我很满意:

渐变是标准色轮,其中红色像素表示具有高值的坐标,紫色像素表示低值.
底层数据结构使用了一些非常聪明的(如果我自己这么说的话)插值算法,可以任意深度缩放到地图的细节.
在这一点上,我想绘制一些地形轮廓线(使用二次贝塞尔曲线),但我还没有找到任何描述找到这些曲线的有效算法的好文献.
为了让您了解我正在考虑的内容,这里是一个穷人的实现(渲染器只要遇到与轮廓线相交的像素就使用黑色RGB值):

但是,这种方法存在一些问题:
具有更陡峭斜率的图形区域导致更薄(并且经常断裂)的拓扑线.理想情况下,所有拓扑线应该是连续的.
具有更平坦斜率的图形区域导致更宽的拓扑线(并且通常是整个黑度区域,尤其是在渲染区域的外周边处).
因此,我正在研究一种矢量绘制方法,以获得那些漂亮,完美的1像素厚曲线.算法的基本结构必须包括以下步骤:
在我想要绘制地形线的每个离散高程处,找到一组坐标,其中该坐标处的高程非常接近(给定任意epsilon值)到所需高程.
消除冗余点.例如,如果三个点处于完全直线,则中心点是多余的,因为可以在不改变曲线形状的情况下消除它.同样,对于贝塞尔曲线,通常可以通过调整相邻控制点的位置来消除cetain锚点.
将剩余的点组装成序列,使得两个点之间的每个段近似于高程中性轨迹,并且使得没有两个线段跨越路径.每个点序列必须创建一个闭合多边形,或者必须与渲染区域的边界框相交.
对于每个顶点,找到一对控制点,使得结果曲线相对于步骤#2中消除的冗余点呈现最小误差.
确保在当前渲染比例下可见的地形的所有要素都由适当的拓扑线表示.例如,如果数据包含高海拔的尖峰,但直径极小,则仍应绘制拓扑线.如果垂直特征的特征直径小于图像的整体渲染粒度,则只应忽略垂直特征.
但即使在这些限制条件下,我仍然可以想到几种不同的启发式方法来寻找线条:
在渲染边界框中找到高点.从那个高点开始,沿着几条不同的轨迹下坡.只要遍历线超过高程阈值,请将该点添加到特定于高程的存储桶.当遍历路径达到局部最小值时,改变航向并向上行驶.
沿着渲染区域的矩形边界框执行高分辨率遍历.在每个海拔阈值处(以及在拐点处,斜坡反转方向的任何位置),将这些点添加到特定于海拔的铲斗中.完成边界遍历后,从这些桶中的边界点开始向内追踪.
扫描整个渲染区域,以稀疏的规则间隔进行高程测量.对于每次测量,使用它与高程阈值的接近度作为决定是否对其邻居进行插值测量的机制.使用这种技术可以更好地保证整个渲染区域的覆盖范围,但是很难将结果点组合成一个合理的构造路径的顺序.
所以,这些是我的一些想法......
在深入研究实现之前,我想看看StackOverflow上是否有其他人遇到过这类问题的经验,并且可以为准确有效的实现提供指导.
编辑:
我对ellisbben提出的"Gradient"建议特别感兴趣.而我的核心数据结构(忽略一些优化插值快捷键)可以表示为一组2D高斯函数的总和,这是完全可微的.
我想我需要一个数据结构来表示一个三维斜率,以及一个用于计算任意点的斜率矢量的函数.在我的头顶,我不知道该怎么做(虽然它看起来应该很容易),但如果你有一个解释数学的链接,我会非常感激!
更新:
由于ellisbben和Azim的出色贡献,我现在可以计算场中任意点的轮廓角.绘制真正的地形线将很快跟随!
这里有更新的渲染图,有和没有我一直在使用的基于ghetto栅格的topo-renderer.每个图像包括一千个随机采样点,由红点表示.该点处的轮廓角由白线表示.在某些情况下,在给定点处不能测量斜率(基于插值的粒度),因此红点在没有相应的轮廓线的情况下发生.
请享用!
(注意:这些渲染使用与之前渲染不同的表面形貌 - 因为我在每次迭代时随机生成数据结构,而我是原型 - 但核心渲染方法是相同的,所以我相信你会得到这个想法.)


这是一个有趣的事实:在这些渲染的右侧,你会看到一堆完美的水平和垂直角度的奇怪轮廓线.这些是插值过程的伪像,它使用插值器网格来减少执行核心渲染操作所需的计算次数(约500%).所有这些奇怪的轮廓线出现在两个插值器网格单元之间的边界上.
幸运的是,这些文物实际上并不重要.尽管在斜率计算期间可检测到伪像,但最终渲染器将不会注意到它们,因为它在不同的位深度处操作.
再次更新:
Aaaaaaaand,作为我睡觉前的最后一次放纵,这里是另一对效果图,一个是老式的"连续色彩"风格,另一个是20,000个渐变样本.在这组渲染中,我已经消除了点样本的红点,因为它不必要地使图像混乱.
在这里,由于插补器集合的网格结构,您可以真正看到我之前提到的那些插值工件.我应该强调的是,这些伪像在最终轮廓渲染中将是完全不可见的(因为任何两个相邻内插器单元之间的幅度差异小于渲染图像的位深度).
好胃口!!


language-agnostic algorithm bezier visualization topographical-lines
如何沿着最接近平面中任意点P的三次贝塞尔曲线找到点B(t)?
对于个人项目,我需要找出两条立方Bézier曲线是否相交.我不需要知道在哪里:我只需要知道他们是否这样做.但是,我需要快速完成.
我一直在清理这个地方,我找到了几个资源.大多数情况下,这里的问题有一个很有希望的答案.
所以在我想出什么是西尔维斯特矩阵之后,什么是决定因素,什么是结果以及为什么它有用,我想我认为解决方案是如何工作的.然而,现实不同,它不能很好地工作.
我用我的图形计算器绘制了两个相交的Bézier样条(我们称之为B 0和B 1).它们的坐标如下(P 0,P 1,P 2,P 3):
(1, 1) (2, 4) (3, 4) (4, 3)
(3, 5) (3, 6) (0, 1) (3, 1)
Run Code Online (Sandbox Code Playgroud)
结果如下,B 0是"水平"曲线而B 1是另一个:

根据上述问题的最高投票答案的指示,我将B 0减去B 1.根据我的计算器,它给我留下了两个方程式(X轴和Y轴):
x = 9t^3 - 9t^2 - 3t + 2
y = 9t^3 - 9t^2 - 6t + 4
Run Code Online (Sandbox Code Playgroud)
从那以后我构建了以下的西尔维斯特矩阵:
9 -9 -3 2 0 0
0 …Run Code Online (Sandbox Code Playgroud) 如何为矢量路径设置动画,就像它正在逐渐被绘制一样?换句话说,逐个像素地慢慢显示路径.
我正在使用Raphaël.js,但是如果你的答案不是特定于库的 - 也许有一些通用的编程模式来做这种事情(我对矢量动画很新) - 欢迎!
使用直线路径很容易,就像该页面上的示例一样简单::
path("M114 253").animate({path: "M114 253 L 234 253"});
Run Code Online (Sandbox Code Playgroud)
但尝试改变该页面上的代码,比如说,这样::
path("M114 26").animate({path: "M114 26 C 24 23 234 253 234 253"});
Run Code Online (Sandbox Code Playgroud)
你会明白我的意思.从初始状态(点"M114 26")到结束状态(曲线"C 24 23 234 253 234 253",从点"M114 26"开始),路径肯定是动画的,但不是以有问题的方式指定,不是像它正在被吸引.
我不知道怎么animateAlong能这样做.它可以沿着路径为对象设置动画,但是如何在对象沿着它进行动画处理时使这条路径逐渐显示出来?
(通过peteorpeter的回答.)
似乎目前最好的方法是使用原始SVG通过'假'破折号.有关说明,请参阅本演示或本文档,第4页.
如何制作渐进式绘图?
我们必须使用
stroke-dasharray并stroke-dashoffset知道要绘制的曲线长度.此代码在屏幕上不显示圆形,椭圆形,折线,多边形或路径:Run Code Online (Sandbox Code Playgroud)<[element] style="stroke-dasharray:[curve_length],[curve_length]; stroke-dashoffset:[curve_length]"/>如果在animate元素stroke-dashoffset减少到0,我们将逐步绘制曲线.
Run Code Online (Sandbox Code Playgroud)<circle cx="200" cy="200" r="115" style="fill:none; stroke:blue; stroke-dasharray:723,723; stroke-dashoffset:723"> <animate begin="0" attributeName="stroke-dashoffset" from="723" to="0" dur="5s" fill="freeze"/> </circle> …
我最近一直在玩帆布,并使用与这些曲线相关的方法绘制了几种形状(泪滴,花瓣,云,岩石).话虽如此,我似乎无法弄清楚这些不同曲线的用例之间的区别.
我知道三次贝塞尔曲线有2个控制点,一个起始点和一个端点,其中二次贝塞尔曲线有一个控制点,一个起点和一个端点.但是,在绘制形状时,我似乎无法轻易决定使用哪一个或何时结合使用它们.
如何知道在不同的绘制形状点使用哪种曲线?