-
Notifications
You must be signed in to change notification settings - Fork 113
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
【译】圆形填充—Circle Packing #26
Comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
原文:Circle Packing
圆形填充是一个非常神奇的效果。蕴含数学魅力的它,看似非常复杂。在本教程中,我们将创建一个有趣的圆形填充效果。尽管它实现起来并不特别高效,但仍然很快。
老规矩,初始化 canvas。
现在,我将阐述一下实现流程,并因此而确定需要哪些变量。该实现流程并不是最高效的,但能完成工作。
流程如下:
因此,需要一个
circles
数组、totalCircles
、最小与最大半径和createCircleAttempts
变量。现在,我们将通过代码描绘整体实现流程。创建函数
createCircle
和doesCircleHaveACollision
函数,然后根据要求逐步填充实现细节。其中,包括调用createAndDrawCircle
函数totalCircles
次。创建带有
x
、y
和radius
属性的圆形对象。并将圆形对象填充到 circles 数组中,并进行绘制。尽管实际并不需要执行这一步,但这有助于了解代码流程。
现在 canvas 上充满了小圆圈。接着,让圆形每次增长 1 单位大小,直至发生碰撞。当发生碰撞时,半径大小减少 1,并退出循环。
哇,超级乱!原因是
doesCircleHaveACollision
一直返回false
。判断圆形之间是否发生碰撞,需要涉及一些三角学。我们需要遍历所有已绘制在 canvas 上的圆形,并将当前圆形与它们进行比较。若两者半径之和大于两者圆心距离,则发生碰撞。
通过勾股定理可计算出两圆心距离(哇,高中数学派上用场!)。
还有另一个小难题。当我们创建圆时,有可能出现在已有圆形内。
这就需要在创建圆形的循环内增加碰撞检测,尽管随机生成的位置会导致不那么高效。其实,除非要创建百万以上的圆形,否则不会看到任何迟缓的现象。
如果圆形找不到安全区域,那就放弃当次尝试。
哇,现在拥有了漂亮圆形的效果。尽管整个 canvas 被圆圈填满,但还剩一个小步骤要做,那就是增加圆形与边界的碰撞检测。我们将该工作拆分为两个判断语句,一个是检查上下边界,另一个是检查左右边界。
我们终于实现了!尽管这不是最完美的代码,但它是一个说明如何通过相对简单的数学来推理、思考并逐步完成较为复杂工作的好案例。
The text was updated successfully, but these errors were encountered: