blender&計算1_直線を描画_2D

はじめに

数学の勉強をやりたいが続かない。
blender使ってやると楽しいかもしれないのでやってみた。

環境

blender:2.92.0
python:3.7.7

やりたいこと

まずは直線を描画

描画結果

Blenderによる描画結果

実施内容

基礎知識

直線の種類

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つ設定したメッシュを新規作成、登録することで対応)

想定どおり、机上でやるより楽しく学べた。
描いた直線を回転して見れるのも以外に楽しい。
このまま進めてみる。

コメント

タイトルとURLをコピーしました