购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

创建Point类

为了更好地在画面中绘制和操作多个点,我们把点的几何属性和运算抽象成一个Point类来表示,如点的位置坐标分量、计算两点之间的距离、点围绕另一点旋转等。而绘制点所用到的其他形态属性和方法可以用一个VisualPoint类来封装,如点的大小、颜色、更新、绘制等,并且让VisualPoint类继承Point类,继承Point类的所有几何属性和方法,这样就可以用VisualPoint类创建的实例访问和调用自己以及父类Point的属性和方法,这样做有利于抽象分离关键代码和之后对代码的复用。如右图所示。

下面是初步创建的Point类,包含x、y两个坐标属性,通过构造函数传入值来初始化这两个属性。同时还包含一个重载的构造函数(不需要传入参数),在函数体内会将x、y默认设置为0。另外,还包含一个copy()方法,返回Point实例的一个复本。

然后再创建一个Point的子类VisualPoint类,通过extends关键字实现继承。VisualPoint类继承了Point类的属性和方法,并在类中添加了w(大小)和c(颜色)属性,还有用于在画面中绘制点的display()方法。在Processing中可以通过point()函数在画面中绘制一个点,点的位置使用x、y参数来指定,注意坐标原点在左上角,y轴负方向为正。在绘制之前可以用stroke()和strokeWeight()函数分别设置点的颜色和大小,颜色可以直接设置为明度值,或分别设置红、绿、蓝、不透明度四个分量,点的大小为点的直径长度。

接着在render()函数体中,通过for循环和new关键字在画面坐标系中创建1000个点,每个点的位置、大小和颜色均为随机,使用random()函数可以返回一个在指定区间的随机数。所有点都事先存储在了数组中,通过for循环遍历所有点,并用VisualPoint类的display()方法绘制所有点。

运行结果如下图所示。

上面创建的图形通过随机位置生成点,点出现在画面某个位置上的概率是相同的,所以得到了一个均匀分布在画面中的1000个点。我们可以把随机数通过幂函数来进行变换,得到不均匀的分布,使用random(1)生成0到1之间的随机数,然后用pow()函数对随机数进行转换,得到一个0到1之间的数值,最后再通过map()函数把刚才的运算结果映射为需要的区间值。例如下面的程序对y坐标的生成用幂函数做了改变,生成从下到上、由密到疏的点。

运行结果如下图所示。

还可以把所有随机生成的点都限制在一个大的圆内。可以在创建点的时候,生成随机角度和半径,再通过三角函数计算每个点的x、y坐标达到目的。下图为根据半径和弧度求圆上一点的坐标公式。

首先生成随机角度,因为在Processing中,三角函数使用弧度来计算,所以需要生成0到TAU之间的数(TAU常数表示两倍圆周率)。然后以大圆的半径为上限生成随机半径,再用cos()、sin()函数分别计算点的x、y坐标。因为画面的坐标原点默认在左上角,所以在绘制所有点的时候还需用translate(width/2, height/2)把坐标系原点移动到画面中心位置。

运行结果如下图所示。

可以发现上面程序生成的点在圆内的分布并不均匀,这是因为在不同半径的同心圆内,点出现的概率相同,所以就会出现中间密集、越向外越稀疏的情况。可以通过对生成半径的随机数开方来解决这个问题,开方相当于1/2次方。运行结果如下图所示。

当然你也可以通过指定不同的指数来达到不一样的分布效果,例如把指数设置为 0.1。运行结果如下图所示。

接下来把点按行和列规则排列成一个矩阵,通过双重for循环来实现,并且判断每个点的编号是否为偶数。如果是偶数,把点的大小设置为10,明度设置为0。如果不是偶数,大小设置为5,明度设置为150。运行结果如下图所示。

除了把点按矩阵排列,还可以让点在指定圆内规则排列。点在圆内均匀规则排列稍微有些复杂,可以把点按顺序放在等间隔半径的同心圆上,但是如果每个同心圆上的点的数量相同的话,会产生不均匀分布,因为不管大的半径或小的半径的同心圆,点的数量都相同,这会使小的半径同心圆上的点看起来比较密集,这样就会产生中间密集、外面松散的情况。解决这个问题可以让点在同心圆上按照等弧长间隔排列,首先让点在最内层的第一个同心圆上按等弧长排列,如果累积弧长超过周长表示第一个同心圆的点已经排满,如果排满,增加同心圆半径转移到第二个同心圆继续排列,重复上面的步骤,直到所有点排满为止。下面的算法做了一些改进,在同心圆上开始排列所有点之前,通过周长和指定弧长间距计算点的个数,然后逐个排列点,当满足个数以后移动到下一个同心圆继续排列。

运行结果如下图所示。

现在对上面的程序做一些延伸,生成2到10000之间的数,并且判断每个数是否为质数(质数是指除了1和它本身以外不再有其他因数)。如果是质数,把点的大小设置为10、明度设置为0;如果不是,大小设置为5、明度设置为150。判断一个数是否为质数,这里把它封装成了prime()函数,通过判断是否能被2到它1/2倍加1之间的数整除来实现(当然你也可以自己实现一个判断质数更高效的算法)。

运行结果如下图所示。 2JDnMTmg4OacRH5Q2Ct/UAY1bYAaVB9RRP01UhaXh6UBuG5Zugo+FLkT94XpTguc

点击中间区域
呼出菜单
上一章
目录
下一章
×