エディタ製作日記1028

アバター
TOMY
記事: 53
登録日時: 11年前
住所: 愛知県
連絡を取る:

エディタ製作日記1028

投稿記事 by TOMY » 10年前

うん・・いまだにエディタ作ってんだ。ペース遅いよね。
という話は置いといて、現在ちょっと数式で停滞中。

求めたいのは2点の座標からなる線分ベクトルAの始点に垂直な指定距離の線分ベクトルBの終点の座標という文章で書くと長ったらしくてわかりづらいものだが、
図解すれば、すぐに解きたいことはわかると思う。
数学が苦手なためそんなクッソくだらない所で停滞中。
うーんマジで分からない。どうしよう・・・
添付ファイル
すうがく.png
すうがく.png (15.33 KiB) 閲覧数: 1206 回
最後に編集したユーザー TOMY on 2013年10月28日(月) 03:23 [ 編集 1 回目 ]

アバター
h2so5
副管理人
記事: 2212
登録日時: 13年前

Re: エディタ製作日記1028

投稿記事 by h2so5 » 10年前

こうかな。

CODE:

#include 
#include 

typedef struct {
	float x, y;
} vec2;

void calc(vec2 a1, vec2 a2, float power, vec2* b1, vec2* b2)
{
	float length;
	vec2 a3 = { 
		-(a2.y - a1.y),
		a2.x - a1.x
	};
	
	length = hypot(a3.x, a3.y);
	a3.x /= length;
	a3.y /= length;
	
	b1->x = a2.x + a3.x * power;
	b1->y = a2.y + a3.y * power;
	b2->x = a2.x + a3.x * -power;
	b2->y = a2.y + a3.y * -power;
}

int main(void) {
	vec2 a1 = { 1.0f, 0.0f };
	vec2 a2 = { 1.0f, 2.0f };
	
	vec2 b1, b2;
	calc(a1, a2, 3.0f, &b1, &b2);
	printf("(%f, %f), (%f, %f)", b1.x, b1.y, b2.x, b2.y);
	
	return 0;
}
最後に編集したユーザー h2so5 on 2013年10月28日(月) 06:39 [ 編集 1 回目 ]

アバター
TOMY
記事: 53
登録日時: 11年前
住所: 愛知県
連絡を取る:

Re: エディタ製作日記1028

投稿記事 by TOMY » 10年前

わざわざソースコードに記載していただきありがとうございます。参考にさせていただきます。

アバター
TOMY
記事: 53
登録日時: 11年前
住所: 愛知県
連絡を取る:

Re: エディタ製作日記1028

投稿記事 by TOMY » 10年前

でも僕が知りたいのはコードじゃなくて、数式と何故それで求まるのかというアルゴリズムなのです・・・
答えのコードだけを入手しても根本を理解できていないと、また似たような状況に陥った時結局は解決できなくなってしまうので・・・

アバター
usao
記事: 1887
登録日時: 11年前

Re: エディタ製作日記1028

投稿記事 by usao » 10年前

(1)ベクトルAと垂直なベクトル = ベクトルAを90度回転したベクトル を求める.
 →例えば,2次元の回転マトリクスをググって,回転角θ=90度の場合だと結局どうなるのかを見ればいい.
  sinθ=1, cosθ=0 になるので
  最終的には,元のベクトルのXとYを入れ替えて一方に-1を掛けたもの になる
(2)求めたベクトルの長さを所望の長さにする(単位化してから欲しい長さを掛ければいい)
(3)あとは 原点+そのベクトル が求めたい位置.(逆方向も欲しいならベクトルを逆向きに使えばいいだけ)

アバター
usao
記事: 1887
登録日時: 11年前

Re: エディタ製作日記1028

投稿記事 by usao » 10年前

h2so5さんのコードで言えば,だいたい
(1)が11行目
(2)が16行目~ (単位化)
(3)が20行目~
な感じ.
最後に編集したユーザー usao on 2013年10月28日(月) 13:43 [ 編集 2 回目 ]

アバター
TOMY
記事: 53
登録日時: 11年前
住所: 愛知県
連絡を取る:

Re: エディタ製作日記1028

投稿記事 by TOMY » 10年前

usaoさん。わざわざ御解説ありがとうございます。アドバイスを 一行一行 解読しています。改めて自分の数学能力の残念さを実感してます・・・

アバター
usao
記事: 1887
登録日時: 11年前

Re: エディタ製作日記1028

投稿記事 by usao » 10年前

>解読
というほどの内容でもないと思いますが,
もし,「あるベクトルに垂直なベクトルを求める」部分に数学的な難しさを感じられているのだとすれば,
もっと簡単に以下のように考えるとよいかもです.

・方眼紙か何かを用意する.どっかを適当に原点としてX軸とY軸くらいを書く.
・適当な点Aを決める.ここでは例えば A=(3,1) としましょう.
 その座標に●を書く.さらに原点と●を線分で結んでみたりする.
・この●を(原点を中心として)90度回転させた場所
 (線分を90度回転したときの端点の場所)ってどこだろう? と考えてみる.
・考えるというよりも,むしろ実際に垂直っぽい方向に線を引いてみればわかる.
 (長さは原点から●までの長さと同じに)
・結果として (1,-3) と (-1,3 ) である.
 これは 元の座標A=(3,1)の, 「X座標とY座標を入れ替えて,さらにどちらか一方の符号を反転させたもの」に見える.
 このルールがすべての点について成り立つだろうか?
・Aの座標をいろいろ変えてやってみる.
 →どうやら 法則が成り立つ模様.
・OK.

アバター
TOMY
記事: 53
登録日時: 11年前
住所: 愛知県
連絡を取る:

Re: エディタ製作日記1028

投稿記事 by TOMY » 10年前

usao さんが書きました:(1)ベクトルAと垂直なベクトル = ベクトルAを90度回転したベクトル を求める.
 →例えば,2次元の回転マトリクスをググって,回転角θ=90度の場合だと結局どうなるのかを見ればいい.
  sinθ=1, cosθ=0 になるので
  最終的には,元のベクトルのXとYを入れ替えて一方に-1を掛けたもの になる
上記の式は任意の角度で回転させたい際、

x' = x * cos(theta) - y * sin (theta); //thetaはradian値
y' = x * sin (theta) + y * cos (theta); //

で、間違いないでしょうか?Wikipedia直下で見た式ですが・・・

アバター
usao
記事: 1887
登録日時: 11年前

Re: エディタ製作日記1028

投稿記事 by usao » 10年前

よいのではないでしょうか.
回転というのは総量(回転中心からの距離)を保ったままXとYとの間で値をやりとりする操作(Xの値が減ったら,Yの値が増える,みたいな)
で,そのやりとりに cosとsin を使っているわけですね.

式が不安な場合は,
回転前の座標が (1,0) とか (0,-1) とかいうわかりやすい例で検算とかしてみればよいと思います.

無駄に私個人の話をすると,何か数学チックなものに出くわした場合,
数式で考える&理解することはもちろん必要なのですが,
それだけだと,なんか次の日には結局「よくわかってない」というか,ぼんやりとしか把握できないというか.
どうにも身につかない.
直感で把握というか,感覚的というか,そういう側の方が無いとどうにもダメ.

なので(?),あなた自身が書かれているように
>実際に実験
してみて,そういう把握感(?)を得るのが重要なのではないかと思います.
自前で何かをくるくるさせるだけのコードを5分で書いて楽しみましょう! 画像を自前で1度単位で回転とか.

アバター
TOMY
記事: 53
登録日時: 11年前
住所: 愛知県
連絡を取る:

Re: エディタ製作日記1028

投稿記事 by TOMY » 10年前

色々ググった結果、ようやく式の意味を理解出来ました・・・行列の計算を利用していたのですね・・・なんで学生時代にこれが理解できなかったんだ・・・・俺・・・