余温

两次绘制了棋盘格,有了一些经验了,顺着学习态势,我们再接再厉,挖一些技巧。这一次要使用pixels[]数组绘制矩形rect和圆形ellipse,也就是代替rect()ellipse()两个函数。

我们先来看一看如何绘制矩形。其实大概原理上节已经说得很清楚了,控制步长,判断状态,循环定义!看代码:

void drawRect(int c, int x, int y, int w, int h) {
fill(c);
for (int i = x; i < x+w; i++) {
for (int j = y; j < y+h; j++) {
pixels[i+j*width] = c;
}
}
}

for()循环条件式找那个包含了诸多逻辑。首先是两层for循环的循环遍历,很明显,控制了输出像素点的坐标,那么也就能推断出条件式i = xj = y是定义初始绘画锚点,接下来的条件式i < x+wj < y+h是定义了图形的步长,也就是矩形的长宽。什么?没懂,没关系,慢慢理解。因为现在的i、j是像素坐标信息,不能承载具体长度信息(由pixels[]函数使用决定的),只能借助判断条件式来控制步长,控制长短,i++j++很明显的事,除非你想搞事情,做些不同寻常的,比如留空矩形、"雀斑矩形"。说了这么多,其函数的形参你也就全搞明白了,c表示颜色,x、y表示起始绘画点,w,h表示长和宽。

如果将其套在之前的例子中,也能完成绘制棋盘格的任务。完整代码:

int increW;
int increH;
int WCOUNT = 10;
int HCOUNT = 10; void drawRect(int c, int x, int y, int w, int h) {
fill(c);
for (int i = x; i < x+w; i++) {
for (int j = y; j < y+h; j++) {
pixels[i+j*width] = c;
}
}
} void settings() {
size(800, 800);
}
void setup() {
increW = width/WCOUNT;
increH = height/HCOUNT;
int k = 0;
int c = 0;
loadPixels();
for (int x = 0; x < width; x += increW)
{
for (int y = 0; y < height; y += increH)
{
if (k % 2 == 0)
c = color(255);
else
c = color(0);
drawRect(c, x, y, increW, increH);
k++;
}
k++;
}
updatePixels();
} void draw() {
}

画个圆

我们来画个圆试试。正常调用Processing的ellipse()函数(以正圆为例):

void drawEllipse(int c, int x, int y, int r)
{
fill(c);
noStroke();
ellipse(x, y, r, r);
}

画矩形简单点,因为我们的像素点排列正式方方正正的一排一排、一列一列,然而现在是要画一不那么规则的图,enmm..."第一排一个点,第二排三个点,第三排8个点。。。。。这些点要填色。。。。" 太难了。。。现在换到控制像素点颜色来绘制,绘制思路完全颠覆了是不是!哦,我想到了GPU渲染管线了。。。。是的,shader着色器。比如在fragment shader片元着色器中去绘制一些图形的思路是不是可以用来参考参考。可以去询问编程大佬们,"如何用shader来绘制一个圆"。这里我给出一个答案供参考[GLSL](我不是大佬):

uniform vec2 u_resolution;

float circleshape(vec2 position,float radius){
return step(radius,length(position - vec2(0.5))); //主要是这里的逻辑,step()就相当于if() 判断两值大小,前比后大,取1,反之取0。length()计算两点距离
} void main(){
vec2 position = gl_FragCoord.xy / u_resolution;
vec3 color = vec3(0.0);
float circle = circleshape(position,0.3); color = vec3(circle);
gl_FragColor = vec4(color,1.0);
}

很明显,计算出一个点(定为圆点)到另一个点(在圆的边上)的距离,再与一个值(定为半径)判断大小,这样的方式控制像素点是否填充相应颜色值。那么,我们也可以借鉴过来。见代码:

void drawEllipse( int x, int y,int c, int X, int Y, int r) {
int _length = (int)dist(x, y, X, Y); //在Processing中两点距离用 dist()
if (_length <= r) //判断,与半径比大小
pixels[x+y*width] = c;
}

注意一点,这里有两套x,y。小写的x、y表示传进来的画布上的坐标点,大写的X、Y表示定义的圆点坐标。然后在外部去遍历像素点:

for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
int c = color(255); //假设要画白色的正圆
drawEllipse(x,y,c,width/2,height/2,100);
}
}

当然做pixel相关操作,loadPixels()updatePixels()不能缺!好了,我们的“像素圆”已经呈现在画布上。如图:



完整代码如下:

void drawEllipse( int x, int y,int c, int X, int Y, int r) {
int _length = (int)dist(x, y, X, Y);
if (_length <= r)
pixels[x+y*width] = c;
} void setup() {
size(400, 400);
loadPixels();
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
int c = color(255);
drawEllipse(x,y,c,width/2,height/2,100);
}
}
updatePixels();
} void draw() {
}

延伸

这么一来,是不是可以思考用这种方法也能绘制shader着色器绘制的唯妙图像呢?enmmm...好像可以。不管了,总之多多思考,有益处,就像这种另类的绘画方式一样,你可以感受到着色器的绘画方式,以及增强对数字图像处理的理性认识。

Processing 使用pixels[]像素数组绘制矩形rect和圆形ellipse的更多相关文章

  1. opencv::轮廓周围绘制矩形框和圆形框

    基于RDP算法实现,目的是减少多边形轮廓点数 approxPolyDP(InputArray curve, OutputArray approxCurve, double epsilon, bool ...

  2. canvas学习总结六:绘制矩形

    在第三章中(canvas学习总结三:绘制路径-线段)我们提高Canvas绘图环境中有些属于立即绘制图形方法,有些绘图方法是基于路径的. 立即绘制图形方法仅有两个strokeRect(),fillRec ...

  3. canvas 绘制矩形

    XXX(x,y,width,height)   x矩形左上角x坐标                                   y矩形左上角y坐标                       ...

  4. opencv2 使用鼠标绘制矩形并截取和保存矩形区域图像

    前言 好长时间没写博文了,今天偷偷懒写篇关于opencv2中鼠标响应操作的文章. 鼠标操作属于用户接口设计,以前一直使用Qt来做,但是如果只需要简单的鼠标,键盘操作,直接调用opencv库的函数也未尝 ...

  5. canvas 绘制矩形和圆形

    canvas绘制有两神方法:1).填充(fill)填充是将图形内部填满. 2).绘制边框 (stroke)绘制边框是不把图形内部填满,只是绘制图形的外框. 当我们在绘制图形的时候,首先要设定好绘制的样 ...

  6. 在OpenCV中利用鼠标绘制矩形和截取图像的矩形区域

    这是两个相关的程序,前者是后者的基础.实际上前一个程序也是在前面博文的基础上做的修改,请参考<在OpenCV中利用鼠标绘制直线> .下面贴出代码. 程序之一,在OpenCV中利用鼠标绘制矩 ...

  7. Javascript高级编程学习笔记(86)—— Canvas(3)绘制矩形

    绘制矩形 矩形是唯一一种可以直接在2D上下文中绘制的形状. 与矩形有关的方法包括: fillRect() strokeRect() clearRect() 上述方法都接收四个参数: 绘制矩形的 X 坐 ...

  8. knova绘制矩形

    效果: 源码: <!DOCTYPE html> <html lang="en"> <head> <meta charset="U ...

  9. canvas绘制矩形

    canvas绘制矩形 方法 fillRect(x, y, width, height) 画一个实心的矩形 clearRect(x, y, width, height) 清除一块儿矩形区域 stroke ...

  10. html5--5-4 绘制矩形

    html5--5-4 绘制矩形 学习要点 掌握绘制矩形的方法:strkeRect()/fillRect() 掌握绘制路径的 beginPath()和closePath() 矩形的绘制方法 rect(x ...

随机推荐

  1. 12C++循环结构-for循环(2)——教学

    一.循环变量为字符型 (第32课 26个兄弟姐妹)参考视频1 试编一程序,按字典顺序输出26个字母. 流程图: 思考:先顺序输出26个小写英文字母,再逆序输出26个大写英文字母. 循环可以是递增型循环 ...

  2. apache kylin的一些注意事项(解决kylin报错Storage schema reading not supported)

    1.目前我所使用的kylin版本为2.6.2,有时在完成一次构建后会出现fail to locate kylin.properties的异常,如图所示 经排查,定位到kylin源码中的 org.apa ...

  3. 性能优化!突破性能瓶颈的尖兵CPU Cache

    大家好,我是呼噜噜,今天我们来介绍计算机的储存器之一,CPU高速缓冲存储器也叫高速缓存,CPU Cache 缓存这个专业术语,在计算机世界中是经常使用到的.它并不是CPU所独有的,比如cdn缓存网站信 ...

  4. Qt/C++音视频开发79-采集websocket视频流/打开ws开头的地址/音视频同步/保存到MP4文件/视频回放

    一.前言 随着音视频的爆发式的增长,各种推拉流应用场景应运而生,基本上都要求各个端都能查看实时视频流,比如PC端.手机端.网页端,在网页端用websocket来接收并解码实时视频流显示,是一个非常常规 ...

  5. Qt编写物联网管理平台43-告警短信转发

    一.前言 系统在运行过程中,会实时采集设备的数据,当采集到的数据发生报警后,可以将报警信息以短信的形式发送给指定的管理员(可以是多个),这样管理员就算不在现场,也能第一时间知道哪里发生了报警,可以紧急 ...

  6. 《Bootstrap4Web设计与开发实战》源代码下载

    <Bootstrap4Web设计与开发实战>源代码下载: 链接:https://pan.baidu.com/s/1GaIo390c-l-gsT6-6RaaJA 提取码:fgiq 版权声明: ...

  7. 大端地址 小端地址 网络字节序 intel主机字节序

    小端字节序:低字节数据存放在内存低地址处,高字节数据存放在内存高地址处:大端字节序:高字节数据存放在内存低地址处,低字节数据存放在内存高地址处. 网络字节序: MSB 高字节前存法 Most Sign ...

  8. 重温Go语法笔记 | 容器

    容器 数组的声明 // 初始化声明 q := [...]int{1,2,3} // 仅声明 var a [3]int 切片 切片的概念 对数组连续片段的引用 // 根据数组生成切片 var a = [ ...

  9. Python 安装package 问题汇总

    1. pip 命令使用国内源安装 pip install torch==1.8.1 -i https://mirrors.aliyun.com/pypi/simple/腾讯云: https://mir ...

  10. linux 手动释放内存

    在 Linux 系统中,内存管理通常由系统自动处理,但在某些情况下,手动释放内存可能是必要的.例如,当业务应用比较繁忙时会频繁存取文件,物理内存会被缓存大量占用,有时会出现内存不足的情况发生,甚至会导 ...