sql行数少于10
by Eric Davidson
埃里克·戴维森(Eric Davidson)
如何用少于100行的代码创建生成艺术 (How to Create Generative Art In Less Than 100 Lines Of Code)
Generative art, like any programming topic, can be intimidating if you’ve never tried it before. I’ve always been interested in it because I love finding new ways that programming can be utilized creatively. Furthermore, I think anyone can appreciate the concept of artwork that literally creates itself.
如果您从未尝试过生成艺术,那么与任何编程主题一样,它可能会令人生畏。 我一直对此感兴趣,因为我喜欢找到可以创造性地利用编程的新方法。 此外,我认为任何人都可以欣赏真正创造自己的艺术品的概念。
什么是生成艺术? (What is generative art?)
Generative art is the output of a system that makes its own decisions about the piece, rather than a human. The system could be as simple as a single Python program, as long as it has rules and some aspect of randomness.
生成艺术是系统对作品(而不是人类)做出自己的决定的结果。 只要具有规则和某种程度上的随机性 ,该系统就可以像单个Python程序一样简单。
With programming, it’s pretty straightforward to come up with rules and constraints. That’s all conditional statements are. Having said that, finding ways to make these rules create something interesting can be tricky.
通过编程,提出规则和约束非常简单。 这就是所有条件语句。 话虽如此,寻找使这些规则产生有趣效果的方法可能很棘手。
The Game of Life is a famous set of four simple rules that determine the “birth” and “death” of each cell in the system. Each of the rules play a part in advancing the system through each generation. Although the rules are simple and easy to understand, complex patterns quickly begin to emerge and ultimately form fascinating results.
生命游戏是一组著名的四个简单规则,它们确定系统中每个单元的“出生”和“死亡”。 每条规则在每一代的系统升级中都发挥着作用。 尽管规则简单易懂,但复杂的模式很快就开始出现并最终形成了令人着迷的结果。
Rules may be responsible for creating the foundation of something interesting, but even something as exciting as Conway’s Game of Life is predictable. Since the four rules are the determining factors for each generation, the way to produce unforeseeable results is to introduce randomization at the starting state of the cells. Beginning with a random matrix will make each execution unique without needing to change the rules.
规则可能会为有趣的事物打下基础,但即使像康威的人生游戏这样令人兴奋的事物也是可以预见的。 由于这四个规则是每一代的决定因素,因此产生不可预知结果的方法是在细胞的起始状态引入随机化。 以随机矩阵开头将使每次执行都是唯一的,而无需更改规则。
The best examples of generative art are the ones that find a combination of predictability and randomness in order to create something interesting that is also statistically irreproducible.
生成艺术的最好例子是那些发现可预测性和随机性相结合的例子,以创造出一些在统计上也无法再现的有趣事物。
为什么要尝试呢? (Why should you try it?)
Not all side projects are created equal, and generative art may not be something you’re inclined to spend time on. If you decide to work on a project however, then you can expect these benefits:
并非所有的副项目都是平等创建的,生成艺术可能不是您倾向于花费时间的东西。 但是,如果您决定从事一个项目,那么您可以期望获得以下好处:
Experience — Generative art is just another opportunity to hone some new and old skills. It can serve as a gateway to practicing concepts like algorithms, data structures, and even new languages.
经验 -生成艺术只是磨练一些新技能和旧技能的另一个机会。 它可以充当实践算法,数据结构甚至新语言等概念的门户。
Tangible Results — In the programming world we rarely get to see any thing physical come out of our efforts, or at least I don’t. Right now I have a few posters in my living room displaying prints of my generative art and I love that programming is responsible for that.
有形的结果 —在编程世界中,我们很少能看到从我们的努力中产生的任何实际结果,或者至少我没有发现。 现在,我的客厅里有几张海报,展示着我的生成艺术作品,我喜欢编程对此负责。
Attractive Projects — We’ve all had the experience of explaining a personal project to someone, possibly even during an interview, without an easy way to convey the effort and results of the project. Generative art speaks for itself, and most anyone will be impressed by your creations, even if they can’t fully understand the methods.
有吸引力的项目 -我们都有过向某人解释个人项目的经验,甚至在面试过程中,都没有简单的方法来传达项目的成果和努力。 生成艺术本身就可以说明一切,即使他们不能完全理解这些方法,大多数人也会对您的创作印象深刻。
你应该从哪里开始? (Where should you start?)
Getting started with generative art is the same process as any project, the most crucial step is to come up with an idea or find one to build upon. Once you have a goal in mind, then you can start working on the technology required to achieve it.
生成艺术的入门与任何项目都是相同的过程,最关键的一步是想出一个主意或找到一个要建立的主意。 一旦有了目标,就可以开始研究实现该目标所需的技术。
Most of my generative art projects have been accomplished in Python. It’s a fairly easy language to get used to and it has some incredible packages available to help with image manipulation, such as Pillow.
我的大部分生成艺术项目都是使用Python完成的。 这是一种相当容易使用的语言,并且它提供了一些令人难以置信的软件包来帮助图像处理,例如Pillow 。
Luckily for you, there’s no need to search very far for a starting point, because I’ve provided some code down below for you to play with.
幸运的是,您无需在很远的地方寻找起点,因为我在下面提供了一些代码供您使用。
精灵生成器 (Sprite Generator)
This project started when I saw a post showing off a sprite generator written in Javascript. The program created 5x5 pixel art sprites with some random color options and its output resembled multi-colored space invaders.
当我看到一个帖子展示了用Java语言编写的Sprite生成器时,该项目开始了。 该程序创建了具有一些随机颜色选项的5x5像素美术图片,其输出类似于多色空间入侵者。
I knew that I wanted to practice image manipulation in Python, so I figured I could just try to recreate this concept on my own. Additionally, I thought that I could expand on it since the original project was so limited in the size of the sprites. I wanted to be able to specify not only the size, but also the number of them and even the size of the image.
我知道我想用Python练习图像操作,所以我想自己可以尝试重新创建这个概念。 另外,我认为我可以扩展它,因为原始项目的精灵大小非常有限。 我希望不仅可以指定大小,还可以指定它们的数量,甚至图像的大小。
Here’s a look at two different outputs from the solution I ended up with:
这是我最终得到的解决方案的两个不同输出:
These two images don’t resemble each other at all, but they’re both the results of the same system. Not to mention, due to the complexity of the image and the randomness of the sprite generation, there is an extremely high probability that even with the same arguments, these images will forever be one of a kind. I love it.
这两张图片一点都不相似,但是它们都是同一系统的结果。 更不用说,由于图像的复杂性和子画面生成的随机性 ,即使具有相同的论点,这些图像也将永远是其中之一的可能性非常高。 我喜欢它。
环境 (The environment)
If you want to start playing around with the sprite generator, there’s a little foundation work that has to be done first.
如果您想开始使用Sprite生成器,那么首先需要完成一些基础工作。
Setting up a proper environment with Python can be tricky. If you haven’t worked with Python before, you’ll probably need to download Python 2.7.10. I initially had trouble setting up the environment, so if you start running into problems, you can do what I did and look into virtual environments. Last but not least, make sure you have Pillow installed as well.
使用Python设置适当的环境可能很棘手。 如果您以前从未使用过Python,则可能需要下载Python 2.7.10。 最初,我在设置环境时遇到了麻烦,因此,如果您开始遇到问题,则可以做我所做的事情,并研究虚拟环境 。 最后但并非最不重要的一点,请确保还安装了枕头 。
Once you have the environment set up, you can copy my code into a file with extension .py and execute with the following command:
设置好环境后,可以将我的代码复制到扩展名为.py的文件中,并使用以下命令执行:
python spritething.py [SPRITE_DIMENSIONS] [NUMBER] [IMAGE_SIZE]
For example, the command to create the first matrix of sprites from above would be:
例如,从上方创建子画面的第一个矩阵的命令为:
python spritething.py 7 30 1900
代码 (The code)
import PIL, random, sysfrom PIL import Image, ImageDraw
origDimension = 1500
r = lambda: random.randint(50,215)rc = lambda: (r(), r(), r())
listSym = []
def create_square(border, draw, randColor, element, size): if (element == int(size/2)): draw.rectangle(border, randColor) elif (len(listSym) == element+1): draw.rectangle(border,listSym.pop()) else: listSym.append(randColor) draw.rectangle(border, randColor)
def create_invader(border, draw, size): x0, y0, x1, y1 = border squareSize = (x1-x0)/size randColors = [rc(), rc(), rc(), (0,0,0), (0,0,0), (0,0,0)] i = 1
for y in range(0, size): i *= -1 element = 0 for x in range(0, size): topLeftX = x*squareSize + x0 topLeftY = y*squareSize + y0 botRightX = topLeftX + squareSize botRightY = topLeftY + squareSize
create_square((topLeftX, topLeftY, botRightX, botRightY), draw, random.choice(randColors), element, size) if (element == int(size/2) or element == 0): i *= -1; element += i
def main(size, invaders, imgSize): origDimension = imgSize origImage = Image.new('RGB', (origDimension, origDimension)) draw = ImageDraw.Draw(origImage)
invaderSize = origDimension/invaders padding = invaderSize/size
for x in range(0, invaders): for y in range(0, invaders): topLeftX = x*invaderSize + padding/2 topLeftY = y*invaderSize + padding/2 botRightX = topLeftX + invaderSize - padding botRightY = topLeftY + invaderSize - padding
create_invader((topLeftX, topLeftY, botRightX, botRightY), draw, size)
origImage.save("Examples/Example-"+str(size)+"x"+str(size)+"-"+str(invaders)+"-"+str(imgSize)+".jpg")
if __name__ == "__main__": main(int(sys.argv[1]), int(sys.argv[2]), int(sys.argv[3]))
This solution is a long way from perfect, but it shows that creating generative art doesn’t take a ton of code. I’ll try my best to explain the key pieces.
这个解决方案离完美还差很远,但是它表明创建生成艺术并不需要大量代码。 我将尽力解释关键部分。
The main function starts by creating the initial image and determining the size of the sprites. The two for loops are responsible for defining a border for each sprite, basically dividing the dimensions of the image by the number of sprites requested. These values are used to determine the coordinates for each one.
主要功能从创建初始图像并确定子画面的大小开始。 两个for循环负责为每个sprite定义一个边界,基本上将图像的尺寸除以请求的sprite的数量。 这些值用于确定每个坐标。
Let’s ignore padding and take a look at the image below. Imagine that each of the four squares represents a sprite with a size of 1. The border that is being passed to the next function refers to the top left and bottom right coordinates. So the tuple for the top left sprite would be (0,0,1,1) whereas the tuple for the top right would be (1,0,2,1). These will be used as the dimensions and base coordinates for the squares of each sprite.
让我们忽略填充,看看下面的图片。 想象一下,四个正方形中的每个正方形代表一个大小为1的精灵。传递给下一个函数的边框是指左上角坐标和右下角坐标。 因此,左上方精灵的元组为(0,0,1,1),而右上方精灵的元组为(1,0,2,1)。 这些将用作每个精灵的尺寸和基本坐标。
The function create_invader determines the border for each square within the sprite. The same process for determining the border is applied here and represented below, only instead of the full image we’re using a pre-determined border to work inside. These final coordinates for each square will be used in the next function to actually draw the sprite.
函数create_invader确定精灵中每个正方形的边界。 确定边界的过程与此处相同,并在下面进行了介绍,只是在内部使用预先确定的边界代替完整图像。 每个正方形的这些最终坐标将在下一个函数中用于实际绘制精灵。
To determine the color, a simple array of three random RGB tuples and three blacks are used to simulate a 50% chance of being drawn. The lambda functions near the top of the code are responsible for generating the RGB values.
为了确定颜色,使用了一个由三个随机RGB元组和三个黑色组成的简单数组来模拟被绘制的机会为50%。 代码顶部附近的lambda函数负责生成RGB值。
The real trick of this function is creating symmetry. Each square is paired with an element value. In the image below you can see the element values increment as they reach the center and then decrement. Squares with matching element values are drawn with the same color.
此功能的真正技巧是创建对称性。 每个正方形都与一个元素值配对。 在下图中,您可以看到元素值在到达中心时增加,然后减少。 具有匹配元素值的正方形用相同的颜色绘制。
As create_square receives its parameters from create_invader, it uses a queue and the element values from before to ensure symmetry. The first occurrence of the values have their colors pushed onto the queue and the mirrored squares pop the colors off.
当create_square从create_invader接收其参数时,它将使用队列和之前的元素值来确保对称。 值的第一次出现将其颜色压入队列,并且镜像的正方形弹出颜色。
I realize how difficult it is to read through and understand someone else’s solution for a problem, and the roughness of the code certainly does not help with its complexity, but hopefully you’ve got a pretty good idea for how it works. Ultimately it would be incredible if you are able to scrap my code altogether and figure out an entirely different solution.
我意识到通读并理解别人对问题的解决方案有多么困难,并且代码的粗糙性当然不会帮助解决它的复杂性,但是希望您对它的工作原理有了一个很好的认识。 最终,如果您能够完全删除我的代码并找出完全不同的解决方案,那将是不可思议的。
结论 (Conclusion)
Generative art takes time to fully appreciate, but it’s worth it. I love being able to combine programming with a more traditional visual, and I have definitely learned a lot in every one of my projects.
生成艺术需要时间来充分欣赏,但这是值得的。 我喜欢能够将编程与更传统的视觉效果相结合,并且我在每个项目中都学到了很多东西。
Overall there may be more useful projects to pursue and generative art may not be something you need experience with, but it’s a ton of fun and you never know how it might separate you from the crowd.
总体而言,可能会有更多有用的项目需要追求,而生成艺术可能并不是您需要的经验,但这是一大堆乐趣,而且您永远都不知道它如何使您与众不同。
Thank you for reading!
感谢您的阅读!
翻译自: https://www.freecodecamp.org/news/how-to-create-generative-art-in-less-than-100-lines-of-code-d37f379859f/
sql行数少于10