見出し画像

ARプログラミング入門 ④ ランダムな線でアートを描こう!

あなたは、夜空に輝く星々や、海岸線に打ち寄せる波の形に、どんな法則性があると思いますか?

自然界には、規則的な形だけでなく、ランダムな要素で構成された、複雑で美しい形がたくさん存在します。

Voxelamming(ボクセラミング)の世界でも、ランダムな要素を取り入れることで、より自然で、そして個性的な表現に挑戦することができます。

今回は、Pythonの random パッケージを使って、ランダムな線を描く方法を学び、Voxelammingで新しいアート表現に挑戦してみましょう!

ランダムな要素が織りなす、予想外の美しさに、きっと驚くはずです

読み始める前に
この記事では、私たちが開発した無料ARプログラミング学習アプリ「Voxelamming(ボクセラミング)」の使い方を、Pythonを使ったサンプルコードと共に詳しく解説していきます。

iPhone/iPad/Vision Proをお持ちの方は、App StoreからVoxelammingアプリをダウンロードして、ぜひ一緒にプログラミングに挑戦してみましょう!

この記事は、連載第1回目の内容を理解し、Pythonのインストール、voxelammingパッケージのインストール、そしてVS Code(または別のIDE)の設定が完了していることを前提としています。


前回の復習と今回の目標

図1 前回作成した球体

前回は、if 文を使って条件分岐を学び、球体や円錐、ドーナツなどの複雑な形状をVoxelammingで表現する方法を習得しました。

条件分岐を使いこなすことで、Voxelammingの可能性が大きく広がることを実感できたのではないでしょうか。

今回は、Pythonの random パッケージを使って、ランダムな要素をVoxelammingの世界に取り入れていきます。

random パッケージは、乱数と呼ばれる、予測できない数値を生成するための機能を提供してくれます。

この乱数を使って、ランダムな位置や色を持つ線を描くことで、今までとは全く異なる、ユニークなARアート作品を生み出すことができます。

今回の目標は、random パッケージの使い方を学び、ランダムな線で構成された、美しいARアートを作成することです。

さあ、ランダムな要素が織りなす、予想外の表現に挑戦してみましょう!

今回使うPythonの知識

randomパッケージ:予測不能な世界を創造する

Pythonには、様々な機能を持った標準パッケージが用意されています。

標準パッケージとは、Pythonをインストールした時点で、最初から使えるようになっているパッケージのことです。

randomパッケージは、その名の通り、乱数を生成するための標準パッケージです。

乱数とは、サイコロを振るように、予測できないランダムな数値のことです。

randomパッケージを使うことで、Voxelammingでランダムな位置や色を持つボクセルを配置したり、ランダムな長さや方向の線を描いたりすることができます。

randomパッケージの関数

randomパッケージには、様々な種類の乱数を生成するための関数が用意されています。

今回は、以下の2つの関数を使います。

  • random(): 0以上1未満のランダムな小数を生成します。

  • uniform(a, b): a以上b未満のランダムな浮動小数点数を生成します。

mathパッケージ:数学関数を使いこなす

math パッケージは、数学的な計算を行うための標準パッケージです。

Voxelammingで複雑な図形を描くときには、数学的な計算が必要になることがよくあります。

math パッケージには、平方根を求める sqrt 関数や、三角関数(sin, cos, tan)、対数関数など、様々な数学関数が用意されています。

mathパッケージの代表的な関数


| 関数            | 説明                                                         | 例                  | 結果                 |
| :--------------- | :----------------------------------------------------------- | :-------------------- | :-------------------- |
| `ceil(x)`      | x 以上の最小の整数を返す                                     | `math.ceil(4.2)`     | `5`                  |
| `floor(x)`     | x 以下の最大の整数を返す                                     | `math.floor(4.2)`    | `4`                  |
| `trunc(x)`     | x の整数部分を返す                                            | `math.trunc(4.2)`    | `4`                  |
| `fabs(x)`      | x の絶対値を返す                                             | `math.fabs(-4.2)`    | `4.2`                |
| `sqrt(x)`      | x の平方根を返す                                             | `math.sqrt(16)`      | `4.0`                |
| `pow(x, y)`    | x の y 乗を返す                                               | `math.pow(2, 3)`     | `8.0`                |
| `exp(x)`       | e の x 乗を返す (e は自然対数の底)                          | `math.exp(1)`       | `2.718281828459045` |
| `log(x)`       | x の自然対数を返す                                          | `math.log(10)`      | `2.302585092994046` |
| `log10(x)`     | x の常用対数を返す                                          | `math.log10(100)`    | `2.0`                |
| `sin(x)`       | x の正弦を返す (x はラジアン)                               | `math.sin(math.pi/2)` | `1.0`                |
| `cos(x)`       | x の余弦を返す (x はラジアン)                               | `math.cos(math.pi)`   | `-1.0`               |
| `tan(x)`       | x の正接を返す (x はラジアン)                               | `math.tan(0)`       | `0.0`                |
| `degrees(x)`   | ラジアン x を度に変換する                                    | `math.degrees(math.pi)` | `180.0`              |
| `radians(x)`   | 度 x をラジアンに変換する                                    | `math.radians(180)`   | `3.141592653589793` |
| **`pi`**      | **円周率πの値**                                              | **`math.pi`**       | **`3.141592653589793`** |

注意: これらの関数を使用する前に、`import math` で `math` パッケージをインポートする必要があります。

while文:条件が満たされる限り繰り返す

for文は、指定した回数だけ処理を繰り返す場合に便利な構文でしたが、while文は、指定した条件が満たされている間、処理を繰り返す場合に便利な構文です。

while文の基本的な構造は次のとおりです。

while 条件式:
    条件式が真(True)の場合に実行される処理
  • 条件式: 真(True)または偽(False)のどちらかの値になる式を記述します。

  • 条件式が真(True)の場合に実行される処理: 条件式が真(True)である間、繰り返し実行される処理を記述します。

while文の注意点

while文を使う場合は、条件式がいつかは偽(False)になるように注意する必要があります。

もし、条件式が常に真(True)になってしまうと、プログラムは無限にループし続けてしまい、停止しなくなってしまう可能性があります。

まとめ

今回は、Pythonの random パッケージ、math パッケージ、そして while 文について解説しました。

これらの知識を駆使することで、Voxelammingでさらに複雑で表現力豊かなARアート作品を作成することができます。

次の章では、いよいよサンプルコードを見ていきましょう!

サンプルコード解説

ランダムな線を描く

今回のサンプルコードでは、random パッケージを使って、ランダムな位置と色を持つ線を描画します。VS Codeで「random_lines.py」という名前のPythonファイルを作成して、次のコードを記述してください。

from random import random, uniform
# voxelammingパッケージからVoxelammingクラスをインポートします
from voxelamming import Voxelamming

# 変数の設定
line_length = 50
line_num = 100

# Voxelammingアプリに表示されている部屋名を指定してください
room_name = "1000"
# Voxelammingクラスのインスタンスを生成します
vox = Voxelamming(room_name)
# ボクセルの設定を行います
vox.set_box_size(0.2)
vox.set_build_interval(0.01)

# ボクセルを配置するため、位置と色を設定します
vox.transform(0, line_length, 0)  # 全体を上に移動

for _ in range(line_num):
    x = uniform(-line_length, line_length)
    y = uniform(-line_length, line_length)
    z = uniform(-line_length, line_length)
    r = random()
    g = random()
    b = random()
    vox.draw_line(0, 0, 0, x, y, z, r=r, g=g, b=b, alpha=1)

# ボクセルデータをアプリに送信します。
vox.send_data("random_lines")

上記のコードは、Voxelammingパッケージのバージョン0.3.0以降で有効です。それ以前のバージョンをインストール済みの方は「pip install --upgrade voxelamming」コマンドでアップデートを行なってください。

コード解説 パート1:準備

最初の数行を見てみましょう。

from random import random, uniform
# voxelammingパッケージからVoxelammingクラスをインポートします
from voxelamming import Voxelamming

# 変数の設定
line_length = 50
line_num = 100

# Voxelammingアプリに表示されている部屋名を指定してください
room_name = "1000"
# Voxelammingクラスのインスタンスを生成します
vox = Voxelamming(room_name)
# ボクセルの設定を行います
vox.set_box_size(0.2)
vox.set_build_interval(0.01)
  • 1行目と2行目は、random パッケージと voxelamming パッケージから必要な関数とクラスをインポートしています。

  • 4行目と5行目は、生成する線の長さと本数を設定する変数を定義しています。

  • 7行目は、Voxelammingアプリに表示されているルーム名を変数 room_name に代入しています。

  • 9行目は、Voxelammingクラスのインスタンスを生成し、変数 vox に代入しています。

  • 11行目と12行目は、ボクセルのサイズと配置間隔を設定しています。

コード解説 パート2:線の描画

次に、線を描画する部分を見ていきましょう。

# ボクセルを配置するため、位置と色を設定します
vox.transform(0, line_length, 0)  # 全体を上に移動

for _ in range(line_num):
    x = uniform(-line_length, line_length)
    y = uniform(-line_length, line_length)
    z = uniform(-line_length, line_length)
    r = random()
    g = random()
    b = random()
    vox.draw_line(0, 0, 0, x, y, z, r=r, g=g, b=b, alpha=1)
  • vox.transform(0, line_length, 0) このコードは、これから描画するすべてのオブジェクトを、y軸方向に line_length だけ移動します。これは、生成される線が平面アンカーの下に隠れて見えないようにするためです。transform メソッドを使うと、このようにボクセル全体を移動させることができます。

  • for _ in range(line_num): : この for 文は、 line_num で指定された回数だけ、線を描画する処理を繰り返します。 _ は、ループ内で使用しない変数を表す慣用的な記号です。

ループの中では、以下の処理を行っています。

  1. x = uniform(-line_length, line_length) 、 y = uniform(-line_length, line_length) 、 z = uniform(-line_length, line_length) : 線の終点の座標を、-line_length から line_length の範囲でランダムに決定します。

  2. r = random() 、 g = random() 、 b = random() : 線の色を、赤、緑、青の各成分を0以上1未満のランダムな値で決定します。

  3. vox.draw_line(0, 0, 0, x, y, z, r=r, g=g, b=b, alpha=1) : 始点 (0, 0, 0) から終点 (x, y, z) まで、指定した色の線を描画します。

コード解説 パート3:ボクセルデータの送信

最後に、以下のコードで作成したボクセルデータをVoxelammingアプリに送信します。

vox.send_data("random_lines")
  • vox.send_data("random_lines"): 作成したボクセルデータを "random_lines" という名前でVoxelammingアプリに送信します。

この章では、random パッケージを使って、ランダムな線を描くコードを解説しました。

次の章では、実際にこのコードを実行して、AR空間にランダムな線で構成されたアート作品を出現させてみましょう!

サンプルコードを実行する

それでは、いよいよサンプルコードを実行して、AR空間に球体を出現させてみましょう!

1. ルーム名を確認

まず、Voxelammingアプリを起動し、画面中央に表示されているルーム名を確認してください。

2. ルーム名をコードに反映

サンプルコードの room_name 変数の値を、アプリに表示されているルーム名に書き換えます。書き換え後、保存するのを忘れないようにしてください。

room_name = "XXXX" # XXXXをアプリのルーム名に書き換える

3. コードを実行

VS Codeでターミナルを開き、次のコマンドを実行します。

ターミナルからコマンドを実行する

python random_lines.py
図2 ランダムな線を描く

プログラムが正常に実行されると、Voxelammingアプリ上に、ランダムな色と方向を持つ線が多数描画されます。美しいアート作品が完成しました!

このアート作品は、ランダム要素を持つため、毎回異なる、予想もつかない形が生成されます。このプログラムのように、ランダムな要素を取り入れてアート作品を作ることを クリエイティブコーディング と呼びます。

line_length や line_num の値を変更すると、線の長さや本数が変わり、アート作品の印象も大きく変わります。ぜひ、色々な値を試して、あなただけのオリジナル作品を作り出してみてください!

実行できないときは

もし、うまく線が描画されない場合は、以下の点を確認してみてください。

  • Voxelammingアプリとパソコンが同じWi-Fiネットワークに接続されているか

  • サンプルコードの room_name 変数の値が、アプリに表示されているルーム名と一致しているか

  • 回線が混み合っている場合は、時間をおいてから再度、コマンドを実行してください。

次の章では、応用として、今回作成した球体を改造して、オリジナル作品作りに挑戦してみましょう!

応用:オリジナル作品作りに挑戦!

問題1: ランダムな花火を打ち上げよう!

random パッケージと draw_line メソッドを使って、夜空に打ち上がる花火を表現してみましょう!

図3 2段目で3つに分岐する線

今回は、花火を表す線が2段階に分かれて炸裂する様子をfor文を2段にすることで表現しています。

挑戦する前に

自分で考えてコードを書いてみると、プログラミングの理解がより深まります。時間がない方は、回答例を参考にしてください。

回答例

VS Codeで「fireworks.py」という名前のファイルを作成し、以下のコードを記述してください。

from random import random, uniform
from math import sin, cos, pi
from voxelamming import Voxelamming

# Voxelammingアプリに表示されている部屋名を指定してください
room_name = "1000"
# Voxelammingクラスのインスタンスを生成します
vox = Voxelamming(room_name)
# ボクセルの設定を行います
vox.set_box_size(0.2)
vox.set_build_interval(0.01)

# 花火の玉の初期位置
initial_x = 0
initial_y = 0
initial_z = 0

# 花火の玉を打ち上げる高さ
height = 30

# 花火の線の数
line_num = 3

# # 花火の玉の軌跡を描画
# for i in range(height + 1):
#     vox.create_box(initial_x, initial_y + i, initial_z, 1, 1, 0)

# 花火が開いたときの線の描画
for _ in range(line_num):
    # ランダムな角度と速度を設定
    angle = uniform(0, 2 * pi)
    speed = uniform(20, 30)

    # 1段目の線の終点座標を計算
    x1 = initial_x + speed * cos(angle)
    y1 = initial_y + height + speed * sin(angle)
    z1 = initial_z + uniform(-5, 5)

    # ランダムな色を設定
    r = random()
    g = random()
    b = random()

    # 1段目の線を描画
    vox.draw_line(initial_x, initial_y + height, initial_z, x1, y1, z1, r=r, g=g, b=b, alpha=1)

    # 2段目の分岐線を描画
    for j in range(3):
        # 分岐角度を設定
        branch_angle = j * 2 * pi / 3
        # 減衰率を設定
        speed_decay = 0.5

        # 2段目の線の終点座標を計算
        x2 = x1 + speed * speed_decay * cos(angle + branch_angle)
        y2 = y1 + speed * speed_decay * sin(angle + branch_angle)
        z2 = z1 + uniform(-5, 5)

        # 線を描画
        vox.draw_line(x1, y1, z1, x2, y2, z2, r=r, g=g, b=b, alpha=1)

# ボクセルデータをアプリに送信します。
vox.send_data("fireworks")

解説

このコードでは、まず花火の玉が打ち上がる軌跡を描画し、その後、花火が開いた瞬間を、ランダムな方向に伸びる2段階の線で表現しています。

  • for i in range(height + 1):: 花火の玉が打ち上がる軌跡を、height + 1 個のボクセルで表現しています。

  • for _ in range(line_num):: 花火が開いた瞬間を、line_num 本の線で表現しています。_ は、ループ内で使用しない変数を表す慣用的な記号です。

  • angle = uniform(0, 2 * pi): 各線の角度を、0から360度(2πラジアン)の範囲でランダムに決定しています。

  • speed = uniform(20, 30): 各線の速度を、20から30の範囲でランダムに決定しています。

  • x1, y1, z1: 1段目の線の終点座標を計算し、格納しています。

  • for j in range(3):: 1段目の線の終点から、3方向に分岐する花火の線を描画するためのループです。

    • branch_angle = j * 2 * pi / 3: 分岐角度を計算しています。 j が 0, 1, 2 と変化することで、それぞれ0度、120度、240度の方向に分岐します。

    • speed_decay = 0.5: 2段目の線の長さを調整するための減衰率です。

    • x2 = x1 + speed * speed_decay * cos(angle + branch_angle) 、 y2 = y1 + speed * speed_decay * sin(angle + branch_angle) 、 z2 = z1 + uniform(-5, 5) : 三角関数を使って、2段目の線の終点座標を計算しています。分岐角度を加算することで、3方向に広がるようにしています。

このプログラムを実行すると、花火を打ち上げることができます。

図4 花火を打ち上げる

挑戦してみよう!

  • 花火の色をもっとカラフルにしてみよう

  • 花火の線の数を増やしてみよう

  • 分岐の数を変えてみよう

  • 複数のfor文を使って、同時に複数の花火を打ち上げてみよう

  • speed_decayの値を変えて、2段目の線の長さを調整してみよう

問題2: 螺旋を描く

while 文を使って、螺旋状に上昇する、一本の線を描いてみましょう。

回答例

VS Codeで「spiral.py」という名前のファイルを作成し、以下のコードを記述してください。

from random import random
from math import sin, cos
from voxelamming import Voxelamming

# Voxelammingアプリに表示されている部屋名を指定してください
room_name = "1000"
# Voxelammingクラスのインスタンスを生成します
vox = Voxelamming(room_name)
# ボクセルの設定を行います
vox.set_box_size(0.2)
vox.set_build_interval(0.01)

# 螺旋の半径
radius = 10
# 螺旋の高さ
height = 30
# 角度
angle = 0
# 高さ方向の現在位置
current_height = 0

# 螺旋の始点座標
x1 = 0
y1 = 0
z1 = 0

# 螺旋を描く
while current_height < height:
    # x, y, z 座標を計算
    x2 = radius * cos(angle)
    y2 = current_height
    z2 = radius * sin(angle)

    # ランダムな色を設定
    r = random()
    g = random()
    b = random()

    # 線を描画
    vox.draw_line(x1, y1, z1, x2, y2, z2, r=r, g=g, b=b, alpha=1)

    # 始点座標を更新
    x1 = x2
    y1 = y2
    z1 = z2

    # 角度と高さを更新
    angle += 0.5
    current_height += 0.5

# ボクセルデータをアプリに送信します。
vox.send_data("spiral")

解説

このコードでは、while 文を使って、螺旋が指定した高さに到達するまで、線を描画する処理を繰り返しています。

  • while current_height < height: : current_height が height より小さい間、ループを繰り返します。

  • x2 = radius * cos(angle) 、 y2 = current_height 、 z2 = radius * sin(angle) : 三角関数を使って、螺旋上の点の座標を計算しています。

  • angle += 0.5 : 角度を0.5ラジアンずつ増やすことで、螺旋状に線を描画しています。

  • current_height += 0.5 : 高さを0.5ずつ増やすことで、螺旋が上昇していくようにしています。

  • x1 = x2, y1 = y2, z1 = z2: 今回の螺旋は、1本の連続した線で表現するため、前回の線の終点を、次の線の始点に設定しています。

コードを実行すると、蛇がトグロを巻くように登っていく線が描かれます。

図5 スパイラル(螺旋)

挑戦してみよう!

  • 螺旋の半径や高さを変えてみよう

  • 角度の増分を調整して、螺旋の密度を変えてみよう

  • 色を変化させながら螺旋を描いてみよう

random パッケージと while 文を組み合わせることで、Voxelammingで表現できる世界はさらに広がります。

ぜひ、色々なアイデアを試して、あなただけのオリジナル作品作りに挑戦してみてください!

まとめ

今回は、ランダムな要素繰り返し処理を組み合わせることで、Voxelammingで表現できる世界の幅をさらに広げました。

  • random パッケージを使って、ランダムな位置や色を持つ線を描画できるようになりました。

  • while 文を使って、条件が満たされる限り処理を繰り返す方法を学びました。

ランダムな要素と繰り返し処理を組み合わせることで、複雑で美しい、そして予想もつかない、個性的なARアート作品を生み出すことができます。
ぜひ、今回のサンプルコードを参考に、様々なアイデアを試して、あなただけのオリジナル作品作りに挑戦してみてください!

次回は、いよいよVoxelammingでアニメーションに挑戦します!
Voxelammingで作った作品を動かすことで、さらに表現の幅が広がります。

AR プログラミング入門シリーズ

ARプログラミング入門シリーズの一覧です。全8回で完結します。
次回、中級編は構想中です。ご期待ください!

第1回 Voxelammingについて
第2回 ボクセルアートの色と形を変えてみよう!
第3回 球体を作る
第4回 ランダムな線でアートを描こう!
第5回 アニメーションで命を吹き込もう!
第6回 タートルグラフィックスで図形を描こう!
第7回 文字でAR空間にメッセージを描こう!
第8回 再帰関数でフラクタルに挑戦!

サンプルコードを公開

GitHubレポジトリでサンプルコードを公開しています。記事を読むときに参照してください。

ARプログラミング入門講座 サンプルコード


この記事が気に入ったらサポートをしてみませんか?