Primeira vez aqui? Seja bem vindo e cheque o FAQ!
x

Quais métodos podemos usar, em Python, para desenhar círculos e formas derivadas?

+1 voto
236 visitas
perguntada Dez 10, 2019 em Estatística por Athos Carvalho (11 pontos)  

Partindo apenas de um círculo, quais formas podemos criar, em Python, por meio da variação de seu raio ou do seu ângulo de desenho?

Compartilhe

1 Resposta

+1 voto
respondida Dez 10, 2019 por Athos Carvalho (11 pontos)  

Uma biblioteca muito boa para arte digital em Python é a Pycairo, utilizada para criação de gráficos em diversos formatos. É ela que será usada para apresentar a resposta à sua pergunta.

Partindo de um conceito simples, o de se traçar retas em lados opostos de um círculo, podemos criar formas como as seguintes:

A imagem será apresentada aqui.

Nessa imagem, as retas passam de brancas para pretas enquanto rotacionam em volta de um ponto fixo.

Ela pode ser reproduzida por meio do seguinte código Python:

import cairo as cr
import math

WIDTH, HEIGHT = 500, 300

surface = cr.ImageSurface(cr.FORMAT_ARGB32, WIDTH, HEIGHT)
ctx = cr.Context(surface)
i = 0

ctx.set_line_width(0.2)
ctx.translate(WIDTH/2, HEIGHT/2)

while i < 180:

    ctx.set_source_rgb(1 - i/180, 1 - i/180, 1 - i/180)
    angle = math.radians(i)
    centrox = 0
    centroy = 0
    raio = 100
    oppangle = angle + math.pi

    x1 = centrox + raio*math.cos(angle)
    y1 = centroy + raio*math.sin(angle)

    x2 = centrox + raio*math.cos(oppangle)
    y2 = centroy + raio*math.sin(oppangle)

    ctx.rotate(1/180)



    ctx.move_to(x1, y1)
    ctx.line_to(x2, y2)
    ctx.stroke()

    i+= 1

Podemos pensar, então, em adicionar uma variável aleatória no tamanho do raio do círculo, de modo a obter o seguinte resultado:

A imagem será apresentada aqui.

A imagem foi obtida com uma pequena alteração no código, que fica dessa maneira:

import cairo as cr
import math
import random

WIDTH, HEIGHT = 500, 300

surface = cr.ImageSurface(cr.FORMAT_ARGB32, WIDTH, HEIGHT)
ctx = cr.Context(surface)
i = 0

ctx.set_line_width(0.1)
ctx.translate(WIDTH/2, HEIGHT/2)
radiusnoise = 0

while i < 360:

    raio = radiusnoise*550 + 1
    ctx.set_source_rgb(1 - i%180/180, 1 - i%180/180, 1 - i%180/180)
    angle = math.radians(i)
    centrox = 0
    centroy = 0
    oppangle = angle + math.pi

    x1 = centrox + raio*math.cos(angle)
    y1 = centroy + raio*math.sin(angle)

    x2 = centrox + raio*math.cos(oppangle)
    y2 = centroy + raio*math.sin(oppangle)

    ctx.rotate(1/180)

    ctx.move_to(x1, y1)
    ctx.line_to(x2, y2)
    ctx.stroke()

    i+= 1
    radiusnoise += random.random()*0.005

É possível também adicionar um efeito aleatório a rotação, obtendo o seguinte resultado:

A imagem será apresentada aqui.

O código gerador é:

    import cairo as cr
    import math
    import random

WIDTH, HEIGHT = 500, 300

surface = cr.ImageSurface(cr.FORMAT_ARGB32, WIDTH, HEIGHT)
ctx = cr.Context(surface)
i = 0

ctx.set_line_width(0.1)
ctx.translate(WIDTH/2, HEIGHT/2)
radiusnoise = 0
angnoise = 0

while i < 180:

    raio = radiusnoise*550 + 1
    ctx.set_source_rgb(1 - i%180/180, 1 - i%180/180, 1 - i%180/180)
    angle = math.radians(((angnoise*6)-3)*i)

    if angle > 360:
        angle -= 360
    if angle < 0:
        angle += 360

    centrox = 0
    centroy = 0
    oppangle = angle + math.pi

    x1 = centrox + raio*math.cos(angle)
    y1 = centroy + raio*math.sin(angle)

    x2 = centrox + raio*math.cos(oppangle)
    y2 = centroy + raio*math.sin(oppangle)

    ctx.rotate(1/180)

    ctx.move_to(x1, y1)
    ctx.line_to(x2, y2)
    ctx.stroke()

    i+= 1
    radiusnoise += random.random()*0.005
    angnoise += random.random()*0.005

Pode-se usar também, no lugar do pacote random alguma biblioteca de ruído Perlin, uma forma de ruído gradiente pseudo-aleatório, muito usado na computação gráfica por apresentar resultados mais "naturais" que outros algoritmos.

...