計算アルゴリズム

このエントリーをはてなブックマークに追加
925デフォルトの名無しさん:2005/10/12(水) 14:02:16
>>924

多分それであってるんだと思いますが、
初心者なので、どのライブラリを使えば、逆正接できるのかわかりません。
926921:2005/10/12(水) 14:04:55
X,Y座標をインプットすると、各種計算結果が出てくるライブラリはネットに転がってたりしないんでしょうか?
927924:2005/10/12(水) 14:06:53
#include<math.h>
typedef struct {double x, double y} Point;

getDegree(Point p1, Point p2){
return (atan2(abs(p1.y-p2.y), abs(p1.x-p2.x)));
}
928924:2005/10/12(水) 14:09:55
>>926
逆正接(逆タンジェント)はC/C++の標準ライブラリにあります。

最近のC++なら先頭2行は:
#include<cmath>
struct {double x, double y} Point;
929921:2005/10/12(水) 14:13:23
>>927-928
ご回答=解答有難うございました。
C++を使ってるので、そのままコピペ致します。
930924:2005/10/12(水) 14:13:35
関数の返値書き忘れた。doubleね。
931924:2005/10/12(水) 14:16:37
>>929
別にコピーしてもいいけど、意味ちゃんとわかった?
あと、うっかりgetDegreeって書いちゃったけど結果は「度」じゃなくてラジアン単位ね。
932921:2005/10/12(水) 14:19:41
>>930-931

実は結構理解していません。

でも、C++は普通に出来るので、動かしてみて〜直してみて、を繰り返そうと思いまつ。
933ポカの多い924:2005/10/12(水) 14:23:30
あとよく思い返したらCだとabsじゃなくてfabsだなぁ。
C++ならabsでいいんだが。
あとあの按配だとリンカのフラグ指定もわからなかったりしてなぁ。
934デフォルトの名無しさん:2005/10/12(水) 14:25:01
>>927 absはイランだろ 問題は2つの直線のなす角だから、

1、2つの直線の水平との角度をそれぞれ求めて差を出す(必要なら差の結果のモジュラ演算)
2、ArcCos(2つのベクトルの内積÷(abs(a)*abs(b))

935921:2005/10/12(水) 14:30:31
やっぱ、回答が2種類になったら、
どちらを取ると見やすくてバグが出難くなるか検討しないといけないから、
図形的な理解すべきかも知れませんね。

別に性能は求めてないので、どちらでも問題は無いのですが。
936& ◆49i8jszFnA :2005/10/12(水) 14:32:31
>>932
数値計算で理解せずに「動かしてみて」なんてやってるとキリがないぞ?

正接tan(x)は高校で習ったろ?
atan(x)はtan()の逆関数つまり
x==atan(tan(x))、y==tan(atan(y))だ。
でatan2(y,x)==atan(y/x)だ。
(ただし実際の計算では誤差があるので==ではない)
937デフォルトの名無しさん:2005/10/12(水) 14:36:23
>>921は線分の傾き(入力は座標2つであらわされる線分が一本)かとオモていタが。
2つの線分のなす角度か。だったら>>934だな。
938921:2005/10/12(水) 15:04:14
実は、結構934の内容理解できません。

>1、2つの直線の水平との角度をそれぞれ求めて差を出す(必要なら差の結果のモジュラ演算)

モジュラ演算は無視して良いですか?

>2、ArcCos(2つのベクトルの内積÷(abs(a)*abs(b))

ベクトルの内積とは、x1*x2 + y1*y2、で良いですか?

absのaとbは何を表すのでしょうか?


939& ◆YJ.BPNLN7E :2005/10/12(水) 15:08:48
とするとまぁ、線分は方向ベクトルであらわしておいて内積とるのが無難だね。
いろいろポカがあったんで極力ちゃんと書いてみた。

#include<cmath>

struct Point2D {
double x;
double y;
Point2D(x, y) : x(x), y(y) {;}
};

struct Vector2D {
double x;
double y;
Vector2D(const Point2D& p)
: x(p.x), y(p.y) {;}
Vector2D(const Point2D& p1, const Point2D& p2)
: x(p1.x-p2.x), y(p1.y-p2.y) {;}
Vector2D getUnitVector(void) const;
};
940子供の頃から忘れ物の多い924:2005/10/12(水) 15:10:14
inline double innerProduct(const Vector2D& v1, const Vector2D& v2){
return(v1.x*v2.x+v1.y*v2.y);
}

inline double norm(const Vector2D& v){
return(innerProduct(v,v));
}

inline double abs(const Vector2D& v){
return(sqrt(norm(v,v)));
}

inline Vector2D Vector2D::getUnitVector(void) const {
double absv = abs(*this);
return(Vector2D(x/absv, y/absv));
}

inline double getRadian(const Vector2D& v1, const Vector2D& v2) {
return (acos(innerProduct(v1.getUnitVector(), v2.getUnitVector()));
}
941938:2005/10/12(水) 15:11:06
>>939
有難うございます。それを動かします。(動くまで自分で直してみます)
942デフォルトの名無しさん:2005/10/12(水) 15:25:08
>モジュラ演算は無視して良いですか?
 結果が-300度とかになっても問題なければ無視してもいい
 +90度と-90度も 線分の場合は区別する場合と、区別しない場合もあるしね

>ベクトルの内積とは、x1*x2 + y1*y2、で良いですか?
>absのaとbは何を表すのでしょうか?
 a,bが判らないのと同じく x1 x2も判らんけど、座標っぽい雰囲気があるなあ
 座標じゃなくて方向ベクトルだから線分の終点-始点 でなければいけないよ。

 でabsはその方向ベクトルの絶対値 sqr( x2^2+y2^2 )* abs( x1^2+x1^2)

943デフォルトの名無しさん:2005/10/12(水) 15:27:00
× でabsはその方向ベクトルの絶対値 sqr( x2^2+y2^2 )* abs( x1^2+x1^2)
○ でabsはその方向ベクトルの絶対値 sqr( x1^2+y1^2 ) と sqr( x2^2+y2^2 )
944921:2005/10/12(水) 15:29:23
>>942

有難うございました。


>>モジュラ演算は無視して良いですか?
> 結果が-300度とかになっても問題なければ無視してもいい
> +90度と-90度も 線分の場合は区別する場合と、区別しない場合もあるしね

あ、これは重要ですね。




C/C++標準ライブラリにあるかどうか知りたいです。
(自分でググりますが、「モジュラ演算とは」だと0件ですた)
945デフォルトの名無しさん:2005/10/12(水) 15:37:12
よーだ:ルーキー、fmod()をつかえ。>>944
946デフォルトの名無しさん:2005/10/12(水) 15:38:20
次スレは950が建てるの?
947デフォルトの名無しさん:2005/10/12(水) 15:48:26
出来れば・・・・もう1のネタは尽きたようだから

プログラミングの為の数学と算数 vol.2
http://pc8.2ch.net/test/read.cgi/tech/1094368921/

に合流してくれ
948デフォルトの名無しさん:2005/10/12(水) 16:19:11
2点間の距離を出すC/C++標準ライブラリとかあるんでしょうか?
949デフォルトの名無しさん:2005/10/12(水) 16:39:45
>>948
>>939-940のabs(const Vector2D&)を使うかそれと同等な計算をすれば出る。
950949:2005/10/12(水) 16:43:38
ちなみに正確な距離を出したいのではなく遠い近いを比較したいだけならnorm()で十分。
951デフォルトの名無しさん:2005/10/12(水) 16:45:04
hypotを使った方がいいよ
sqr(dx^2+dy^2) == hypot(dx,dy)
952950:2005/10/12(水) 16:46:45
なんかここよりあっちの方が
若干Lv高くて敷居高そうな感じもあるが、
まぁ次スレは建てず続きは

プログラミングの為の数学と算数 vol.2
http://pc8.2ch.net/test/read.cgi/tech/1094368921/

で。
953デフォルトの名無しさん:2005/10/12(水) 16:50:17
>>951
C/C++の標準ライブラリにはないXe(希ガス)。
954デフォルトの名無しさん:2005/10/12(水) 16:53:11
>>950

なんか、
[C++ Error] : E2268 Call to undefined function 'norm'
みたいでつ。

955デフォルトの名無しさん:2005/10/12(水) 16:54:22
>>951
>>953

ライブラリ足せば良いのでしょうか?
956デフォルトの名無しさん:2005/10/12(水) 16:55:33
>>952
 新スレたてても、ネタ士が居ないと維持は難しいです。

>>953 え? そうなの?
http://www12.plala.or.jp/ksp/prog/c/c_function.html とはでは標準ライブラリ扱いなんだけど


957デフォルトの名無しさん:2005/10/12(水) 17:07:11
>>955
#include <math.h> で hypot( dx, dy)が使えると思うよ。 ダメだったら諦める
958955:2005/10/12(水) 17:10:57
>>957
hypotはコンパイル通りますた。

normは >>954 の通りなんですよね。
959949:2005/10/12(水) 17:11:20
>>950のnorm()は>>939-940のnorm(const Vector2D&)のことな。
960955:2005/10/12(水) 17:12:30
>>959
あ、了解。
961デフォルトの名無しさん:2005/10/12(水) 17:15:40
ポータブル テンプレート 行列クラスライブラリ

ttp://sklab-www.pi.titech.ac.jp/~hase/soft/ptm/PTM.html

 ↑
このTMatrixとか、TVectorって便利ですか?
それとも行列クラスライブラリは別にデファクトモノがあったりするのかな?
962デフォルトの名無しさん:2005/10/12(水) 17:18:43
>>957-958
ANSI C/C++、POSIXなどの標準規格では<cmath>や<math.h>には含まれないが
UNIX環境では割とあることが多いらしいそうな。System V系にはあるそうな。
後は処理系によってあったりなかったり。
963デフォルトの名無しさん:2005/10/12(水) 17:20:02
MTLが有名。数値計算で使っている人も多い。
http://www.osl.iu.edu/research/mtl/
964デフォルトの名無しさん:2005/10/12(水) 17:27:38
>>961

Blitz++
MTL
POOMA
A++/P++

・・・なんてのがあるらしいよ。あとはこのキーワードでググってみて管祭。
965デフォルトの名無しさん:2005/10/12(水) 17:32:42
>>963 >>964

ダウンロードしたり、演算リンク集なんか見てみましたが、
巨大だし、ドキュメントは英語ですね。

自作するよりは良いんでしょうが、大変そう。
966デフォルトの名無しさん:2005/10/12(水) 17:33:52
Blitz++ :テンプレート・メタプログラミングを使った最初のC++線形計算パッケージ
http://www.oonumerics.org/blitz/
MTL :割とメジャー
http://www.osl.iu.edu/research/mtl/
POOMA :並列計算を主に考えているらしい
http://acts.nersc.gov/pooma/
A++/P++ :Fortran90と同等の配列処理をC++で行う
http://www.sai.msu.su/sal/B/2/A++P++.html

・・・なのか?
967デフォルトの名無しさん:2005/10/12(水) 17:42:46
>>965
自作するよりはよいどころではなく多分割と劇的に性能が違うと思うよ。
特にある程度以上の大きさの行列では。
968965:2005/10/12(水) 17:56:03
劇的に良いわけですか。

質問ばかりですみませんが、座標系(言い方変ですか?)のライブラリのデファクトはどうなんでしょう?

やりたい事は、座標変換や面積計算やトポロジー的なことです。2次元、将来3次元かもです。
969デフォルトの名無しさん:2005/10/12(水) 18:42:35
数学的な問題を解くのが目的か、グラフィックスとかの応用が目的か、
問題の規模や、リアルタイム・アプリケーションなのかそうでないかとか
あるいは単に宿題や趣味プログラミングかとか
その辺が分からないとなんともいえないよね。

例えば>>966で紹介したライブラリ群とかは
概ね浮動小数点演算で大規模な問題を効率よく解くのには向いているが、
3次元で展開するリアルタイムゲームのエンジン部分とか
小さな行列をリアルタイムで解くような問題にはあまり向いてない。
また3Dグラフィックスならむしろグラフィック・ハードウェアの
演算機能を生かす必要があるから一般的な行列ライブラリより
OpenGLとかDirectXとか考えたほうがいいわけだろうし。
970デフォルトの名無しさん:2005/10/12(水) 18:45:00
グラフィックスとかの応用が目的で、リアルタイムじゃないものお願いします。
971デフォルトの名無しさん:2005/10/12(水) 19:02:50
グラフィックへの応用が目的なら、勉強がてらそこらへん自作するのも手だよ。
結局、応用するには基礎が出来てないとどうしようもない。
基礎を勉強するには、一度は苦労しないとね
972デフォルトの名無しさん:2005/10/13(木) 01:25:59
>>961 >>964 >966
用途によっては
Boost::numeric::ublas
も使えるかも。Boost準標準だし。
973デフォルトの名無しさん:2005/10/13(木) 08:04:23
しかし、2直線が挟む角度を求めるだけで、
こんなに話を膨らませられる君たちは天才だね。
974デフォルトの名無しさん
なんなら、2直線が平行に近い場合の
ArcCos内積 を使う場合の精度問題について膨らませてもいいぞ。