如何知道当前像素的顶点坐标_如何利用Processing制作互动Virtual Ribbons (虚拟彩带)...

本文介绍如何使用Processing进行颜色追踪,通过分析颜色相似度获取顶点坐标,进而实现动态彩带的生成。讲解了颜色追踪的原理,包括获取坐标、计算相似度和试点筛选,并通过队列存储历史位置,利用贝塞尔曲线实现从直线轨迹到曲线的转变,增强彩带的交互性。文章还展示了最终效果并提供了源代码链接。
摘要由CSDN通过智能技术生成

e851f213f1450b1de61bf9e535f26264.png

首先,请自行安装好软件

https://processing.org/reference/libraries/video/

「Part1 : 颜色追踪原理分析」

这里我们可以分为三点来分析:

1.获取坐标

计算颜色的相似度

判断并记录符合条件的像素的x,y坐标

我们选取某一帧进行图像分析。首先我们在这里调用一个用于存储图像的数据类型pixels[ ],它储存了一副画面的每个像素的颜色信息。然后我们需要将这一帧画面中的每一个pixel颜色进行对比判断,看颜色是否符合我们想要展示出来的颜色,将符合一定范围的颜色判断是跟踪的颜色,即trackcolor。

以宽度width为5为例:

如果我们想获取坐标为(3,2)这一点的颜色信息就是pixels[13]。

这个计算公式为 : pixels[ ]=纵坐标(y) * 宽度(width)+横坐标(x)

55e04473dd6151bcd0904e02818a7516.png

2.相似度

计算颜色与目标颜色(trackColor)之间的相似度

这里我们将color(R,G,B)转换为三维坐标(x,y,z),将currentColor(当前颜色)与trackColor(跟踪颜色)看成两个点,当两点之间距离最短,也是亮点的颜色最为相近的时候,所以我们用dis表示颜色相似度。

20c76abf3fe3a0f6bd54dd5ac026f384.png

4b4ca7b6fc8c88f0b924dadde2d191ec.gif

3.试点

整理符合条件的(x,y)

计算出跟踪颜色的范围和稳定的位置

当第一次检测到trackcolor(跟踪颜色),我们用坐标为(minx,miny)(maxx,maxy)两点创建一个矩形(Box),属性来计算这个Box的大小,distThreshold 来存储距离临界值。

若每次检测到的trackcolor(跟踪颜色)的点坐标与Box的中心点坐标之间的距离小于distThreshold 则添加进Box范围,更新(minx,miny)(maxx,maxy)重新计算box的大小。

distThreshold 决定的box的最大size。

最后box的中心点就是我们跟踪颜色的位置。

f4927c58d0281659c3aa6a0403f912d8.gif

「Part2 : 彩带生成原理分析」

这里我们先用鼠标模拟一下颜色跟踪,为了轨迹生成图形做准备,我们需要一个队列来记录鼠标位置的历史信息。

3c26dd6e345abdcc889dd8ba31afa091.gif

1.队列

ArrayList存储可变数量的对象

这里面,我们一共记录的30帧鼠标的历史位置,在循环中,每当记录新的位置,就会将最将“老”的信息,挤出队列。

以限制长度10为例:

如果size( )<10时,将所有的元素添加到数组队列;size( )>10时,就会先remove(0),移除掉最老的元素,也就是第一个(index为0的元素),然后add( )新的元素。

就像水管一样,数组列表里的数据不断地在更新。

98246ea9631bd1fc8132e5144ecf2830.gif

ArrayList存储原理

再把轨迹在原坐标的基础上添加上一个随机量,做成5条,我们的彩带就更具有交互性了。

34a3e156671cfc426a2db5f32619909d.gif

2.直线轨迹变曲线

利用bezierVertex() 贝塞尔曲线

使画面更生动

8c02c96f7a89359ad9e08162e64a7c03.gif

这个过程可以简单分为两步:

确定曲线方向和确定曲线宽度

第一步:确定曲线的方向

首先定义几个参数:

pos——当前点的位置坐标

'pos——上一个点的位置坐标

pos'——下一个点的位置坐标

leftMid——线段pos'pos的中点

rightMid——线段pospos'的中点

985d94e733f0964d79971fe7ae12fbac.gif

然后我们把点pos的运动方向设定为leftMid指向rightMid的连线方向,向量长度定义为单位长度1,记向量为dir。

第二步:确定曲线的宽度

在我们模拟曲线运动的过程受到速度影响,速度越快,曲线越长。所以我们用radius表示曲线半径。

f6415b52fd88b233aa3f06711eb63aff.png

接下来我们将向量dir分别顺时针、逆时针旋转90°,得到两个新的单位向量。

以下图为例:

点leftside为单位向量逆时针旋转90°得到新的单位向量,记为dir'。dir'乘以radius得到新的向量长度,最后加上点pos的位置坐标即可得到点leftside的位置坐标。

而这段向量长度我们用计算公式表示为:

|leftSide|=pos+dir.rotate(-90°)mult(radius),rightSide同理

19517875d156278a854c4dfefbd0dcc1.gif

接下来我们用同样的方法把前后的leftSide与rightSide都连接起来,找到各个线段的中点,得到了pos连线的轮廓扩展,接连起来就是绘制曲线bezier。

1e5441d1ec4e76013b0c75439de27dd4.gif

贝赛尔曲线的点类似于钢笔的锚点,只不过是用计算机绘制出来,我们同样需要让曲线闭合。

在beginShape()里,先绘制的左侧的边,

确定第一个锚点(上一个的nextLeftSideMid),

依次是两个控制点(leftSide与当前的nextLeftSideMid),

最后一个锚点(nextLeftSideMid),

因为我们只需要3个顶点,所以将最后的锚点和第二个控制点设置成同一个。

右侧边绘制也是相同的原理。

ca7385eb732a16f5d72bfcf2fd792bda.gif

【最终效果展示】

4f46548cdaf19a041511abf0ea9ec7c7.gif

▲让我们看一下杨总的宝贵影像

20c21d8e3c15fed0536e2f5c7870159a.gif

【源代码获取】

https://mp.weixin.qq.com/s?__biz=MzU4MDg4Mzg4MQ==&mid=2247484347&idx=1&sn=0f4854eedff6478f828f6718e6f74336&chksm=fd51477dca26ce6b5be0dc4c7eaa90305ed78f798821a19ae5c75b72db2bf5cf9ccbd64da734&token=1865694520&lang=zh_CN#rd

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值