はじめに
数学の勉強をやりたいが続かない。
blender使ってやると楽しいかもしれないのでやってみた。
環境
blender:2.92.0
python:3.7.7
やりたいこと
まずは直線を描画
描画結果

実施内容
基礎知識
直線の種類
y=mx+n(基本形)
メリット:グラフ書きやすい
デメリット:Y軸と平行な線(x=x1)が表せない
ax+by+c=0(一般式)
メリット:すべての直線が表せる、法線ベクトルが見てわかる
Y軸と平行な線(x=x1)は a≠0,b=0(ax+0y-c=0)で表記可能
X軸と平行な線(y=y1)は a=0,b≠0(0x+by-c=0)で表記可能
デメリット:式が少し複雑
※メモ1
切片系という別の形もあるようだが、用途少なそうなので省略。
※メモ2
基本形は以下の式に変えて使うことが多い
(理由:切片がわからなくても使用可能)
[傾きと1点(x1,y1)の座標がわかる場合]
y-y_{1} = m(x-x_{1}) \\\\ \scriptsize {m:傾き} \\\\ x_{1},y_{1}:傾き上にある任意の点

切片が0の場合は青い線のイメージ
切片が0以外の場合は青い線がx1,y1分だけズラしたものとも言える。
y1=mx1+n → n=mx1-y1 → y=mx+n の n に代入 → y-y1=m(x-x1)
[2点の座標がわかる場合]
y-y_{1} = \frac {y_{2}-y_{1}} {x_{2}-x_{1}} (x-x_{1})
傾きm を横と縦の移動量で表しただけの式。
展開して以下の形にすると0割(x2=x1)を気にしなくて良くなる。
(x_{2}-x_{1})(y-y_{1})-(x-x_{1})(y_{2}-y_{1})=0
プログラム組む時は一般式で進めるのが良さそう。
計算式
直線上のY点を算出するまでの流れ

X=10mの時のY座標を算出する方法を確認。
基本形、一般式、どちらも確認。
プログラム
任意の点P1を通る傾きmの直線から
横幅10mまでの直線を描画。
描画するための座標計算は
y=mx+n
ax+by+c=0
の2パターンを試す。
import bpy
import mathutils
# delete all
for item in bpy.data.meshes:
bpy.data.meshes.remove(item)
# set input line( slope, P1 )
slope_m = 3
p1 = mathutils.Vector((1.0, 2.0, 0))
# line draw (x:-10m ~ +10m)
start_x = 10
end_x = -10
########## line1 ( y = mx + n ) ##########
# start/end calc y.
start_y = slope_m * start_x - slope_m * p1.x + p1.y
end_y = slope_m * end_x - slope_m * p1.x + p1.y
base_lines_pos = [[start_x, start_y, 0], [end_x, end_y, 0]]
base_edges_pos = [[0,1]]
# create mesh
msh = bpy.data.meshes.new("cubemesh") #Meshデータの宣言
msh.from_pydata(base_lines_pos, base_edges_pos, []) # 頂点座標と各面の頂点の情報でメッシュを作成
# set object
obj = bpy.data.objects.new("line1_mn", msh) # メッシュデータでオブジェクトを作成
bpy.context.scene.collection.objects.link(obj) # シーンにオブジェクトを配置
########## line2 ( ax + by + c = 0 ) ##########
a = slope_m
b = -1
c = -slope_m * p1.x + p1.y
# start/end calc y.
start_y = -a / b * line1_max_x + (-c / b)
end_y = -a / b * line1_min_x + (-c / b)
base_lines_pos = [[start_x, start_y, 0], [end_x, end_y, 0]]
base_edges_pos = [[0,1]]
# create mesh
msh = bpy.data.meshes.new("cubemesh") #Meshデータの宣言
msh.from_pydata(base_lines_pos, base_edges_pos, []) # 頂点座標と各面の頂点の情報でメッシュを作成
# set object
obj = bpy.data.objects.new("line1_abc", msh) # メッシュデータでオブジェクトを作成
bpy.context.scene.collection.objects.link(obj) # シーンにオブジェクトを配置
振り返り
以下の勘違いで理解に時間かかってしまった。
- n と c の関係がイメージできず混乱
- x と x1 を時々混同(同じものとしてイメージ)
- Blenderで正面から見ると、縦方向がZになる
プログラム混乱するので、Blenderの視点を真上からに変更(テンキーの7押下)
Blenderで直線引くの結構大変だった
(オブジェクトだとやり方わからなかったので、点を2つ、辺を1つ設定したメッシュを新規作成、登録することで対応)
想定どおり、机上でやるより楽しく学べた。
描いた直線を回転して見れるのも以外に楽しい。
このまま進めてみる。

コメント