PSM

python する man

ProcessingでPythonを使ってみる(実践編1)

前回
muromura.hatenablog.com
の続き


[:contens]

Pvectorを使う

f:id:muromura:20180328160203p:plain

def setup():
    global v1, v2
    noLoop() #draw once
    size(400, 300) #size of window
    v1 = PVector(100, 40)
    v2 = PVector(80, 120)


def draw():
    ellipse(v1.x, v1.y, 12, 12) #draw cicle
    ellipse(v2.x, v2.y, 24, 24)
    v2.add(v1) #pvector can be added
    ellipse(v2.x, v2.y, 36, 36)
    
    save("pvector.png") # save file

tips
pythonで書きたいときはvoid→defのように書き換えたりと,pythonの記法に直す
・save("ファイル名.拡張子")で描画結果を保存できる
・pVectorを使って点を扱える
・pVector ではpVector.xのようにしてx成分を抜き出したり,.addなどでベクトル全体の演算ができる



マウスを四角がおっかける

f:id:muromura:20180219184239g:plain

add_library('gifAnimation')

def setup():
    global speed, xPos, yPos, gifMaker
    size(400, 400)
    speed = 0.05
    xPos = 0
    yPos = 0

    gifMaker = GifMaker(this, "maze.gif")
    gifMaker.setRepeat(0)
    gifMaker.setDelay(10)


def draw():
    global xPos, yPos
    background(100)
    c1 = color(255, 255, 255, 255)
    fill(c1)
    stroke(c1)
    rectMode(CENTER)
    xDiff = (xPos - mouseX) * speed
    yDiff = (yPos - mouseY) * speed

    xPos -= xDiff
    yPos -= yDiff
    rect(xPos, yPos, 10, 10)

    gifMaker.addFrame()
    if (frameCount > 100):
        gifMaker.finish()
        exit()

Tips
・global変数はsetup()の中でまとめて宣言すると見やすい

pythonでdelaunay図

pVectorを使ってdelaunay図の実装.
(計算量がo(N^4)だしpythonだしで,めちゃくちゃ遅いです)
f:id:muromura:20180329195100p:plain

N = 50

def setup():
    global pVec
    size(800, 600)
    pVec = [None for i in range(N)]
    for i in range(N):
        pVec[i] = PVector(random(width), random(height))
    smooth()
    noLoop()  # draw once


def draw():
    background(255)

    stroke(0)
    for i in range(N - 2):
        v1 = pVec[i]
        for j in range(i+1, N - 1, 1):
            v2 = pVec[j]
            for k in range(j+1,N,1):
                v3 = pVec[k]

                tmp = 2.0 * \
                    ((v2.x - v1.x) * (v3.y - v1.y) -
                     (v2.y - v1.y) * (v3.x - v1.x))
                
                center = PVector(
                    ((v3.y - v1.y) * (v2.x * v2.x - v1.x * v1.x + v2.y * v2.y - v1.y * v1.y) +
                     (v1.y - v2.y) * (v3.x * v3.x - v1.x * v1.x + v3.y * v3.y - v1.y * v1.y)) / tmp,
                    ((v1.x - v3.x) * (v2.x * v2.x - v1.x * v1.x + v2.y * v2.y - v1.y * v1.y) +
                        (v2.x - v1.x) * (v3.x * v3.x - v1.x * v1.x + v3.y * v3.y - v1.y * v1.y)) / tmp
                )
                r = PVector.dist(center, v1) - 0.01

                flg = False
                for l in range(N):
                    if (PVector.dist(center, pVec[l]) < r):
                        flg = True
                        break
                if (not(flg)):
                    line(v1.x, v1.y, v2.x, v2.y)
                    line(v2.x, v2.y, v3.x, v3.y)
                    line(v3.x, v3.y, v1.x, v1.y)

tips
 ・line(始点のx座標,始点のy座標 , 終点のx座標, 終点のy座標)で線が引ける
 ・pythonではbooleanの反転はnot()



迷路生成

いつかの穴掘り方による迷路作成をProcessingに移行して実装してみました.
muromura.hatenablog.com

f:id:muromura:20180211201854g:plain

add_library('gifAnimation')
import random
import math


def setup():
    global h, w, maze, wl, stt, stt2, ps, dr, gifMaker

    frame.setTitle("Maze")
    h = 45
    w = 45

    maze = [[1 if 0 < i < w - 1 else 0 for i in range(w)] if 0 < j < h - 1 else [
        0 for i in range(w)] for j in range(h)]  # path:0 wall:1
    wl = [[2 * i + 2, 2 * j + 2]
          for i in range(int((w - 1) / 2) - 1) for j in range(int((h - 1) / 2) - 1)]  # prepare wall
    stt = wl.pop(random.randint(0, len(wl) - 1))  # start point
    stt2 = stt
    ps = [stt]  # paths
    maze[stt[1]][stt[0]] = 0  # change start point to 0
    dr = [[-1, 0], [1, 0], [0, -1], [0, 1]]  # direction list of search

    size(h * 10, w * 10)
    frameRate(4000)
    noStroke()
    background(10)

    gifMaker = GifMaker(this, "maze.gif")
    gifMaker.setRepeat(0)
    gifMaker.setDelay(10)


def draw():
    global h, w, maze, wl, stt, stt2, ps, dr, gifMaker

    fill(255, 0, 255)
    rect(stt2[0] * 10, stt2[1] * 10, 10, 10)

    random.shuffle(dr)  # random order of search direction

    for i in range(4):
        nxtx = stt[0] + dr[i][0] * 2
        nxty = stt[1] + dr[i][1] * 2
        nxtx2 = stt[0] + dr[i][0]
        nxty2 = stt[1] + dr[i][1]

        if maze[nxty][nxtx] == 1:
            wl.remove([nxtx, nxty])  # remove searched point
            ps.append([nxtx, nxty])  # append searched point

            maze[nxty][nxtx] = 0  # 2 block
            maze[nxty2][nxtx2] = 0  # middle block

            fill(255, maze[nxty2][nxtx2] * 255 +
                 math.sin(frameCount ** 1.2 / 500) * 255, 255)
            rect(nxtx2 * 10, nxty2 * 10, 10, 10)

            fill(255, maze[nxty][nxtx] * 255 +
                 math.sin(frameCount ** 1.2 / 500) * 255, 255)
            rect(nxtx * 10, nxty * 10, 10, 10)
            break

    if i == 3:  # end of direction
        ps.remove([stt[0], stt[1]])

    gifMaker.addFrame()
    if (len(ps) == 0):
        gifMaker.finish()
        exit()
    else:
        stt = ps[random.randint(0, len(ps) - 1)]  # next point

Tips
・探索終了とgif作成の終わりを分岐にまとめておくとすっきりする