• ベストアンサー

行列を利用した座標変換をVBAでコードに

今 P1(x1、y1)   P2(x2、y2)   P3(x3、y3)      略   Pn(xn,yn) の点群があったとします。この点群が座標原点に対して 角度k度反時計方向に回転する場合の新座標値の解法に ついて(行列を用いる前提で)エクセルVBAでコード 作成のサンプルをご教示お願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • inara
  • ベストアンサー率72% (293/404)
回答No.4

状況を整理します ・実験設備でデータが次々と10秒おきに入ってくる ・データは200列あたりまで連続する ・A列はx値、B列はy値、D列に新x値、E列に新y値 C列を飛ばすようなので、回転の計算は5列おきにやるわけですね。複数のデータ組を計算するプログラムを作ってみました(動作確認済み)。プログラム中の変数 M はデータ組の数です(新x値は 列5*(M-1)+4に、新y値はその次の列に書き込まれる)。MとNdataの値は適当に変えてください。 Dim i As Long, j As Long, i0 As Long, j0 As Long, i1 As Long, j1 As Long, jj As Long, Ndata As Long Dim x0 As Double, y0 As Double, c As Double, sn As Double, cs As Double Dim xy() As Double ' 回転後の xn,yn Dim Ndada As Long ' データ数 Dim M As Long ' データ組の数 Dim k As Double ' 回転角度(度) ' i0 = 1 ' x1があるセルの行 j0 = 1 ' 最初のx1があるセルの列(A列 i1 = 1 ' 回転後のx1を書き込むセルの行 j1 = 4 ' 最初の回転後x1を書き込むセルの列(D列) Ndata = 10000 ' データ数 M = 100 ' データ組の数 k = 90 ' 角度(度) ' ReDim xy(Ndata, 2) As Double c = 3.14159265358979 / 180 sn = Sin(c * k) cs = Cos(c * k) ' Application.ScreenUpdating = False ' Excelグラフの再描画を禁止する For j = 0 To M - 1 jj = j0 + 5 * j For i = 0 To Ndata - 1 x0 = Val(Cells(i0 + i, jj)) y0 = Val(Cells(i0 + i, jj + 1)) xy(i, 0) = x0 * cs - y0 * sn xy(i, 1) = x0 * sn + y0 * cs Next i Range(Cells(i1, jj + 3), Cells(i1 + Ndata - 1, jj + 4)) = xy() Next j Application.ScreenUpdating = True ' Excelグラフの再描画を許可する

catshoes01
質問者

お礼

動作速度まで試していただき完璧です。 これで極めて複雑なデータの振舞いを グラフ表示で視認できます。 ありがとうございました。

その他の回答 (3)

  • inara
  • ベストアンサー率72% (293/404)
回答No.3

一括計算するプログラムを作ってみました(動作確認済み)。マクロの作成方法と実行方法は以下のとおりです。プログラム中に変数の意味うを書いておきましたので、数値は適当に直してください。 【マクロ作成】 「ツール」→「マクロ」→「マクロ」→マクロ名に名前(kaiten)を入力→「作成」→ sub kaiten() と End Sub の間の行に以下のコードを貼り付ける 【実行方法】  ワークシートに戻り、「表示」→「ツールバー」→「Visual Basic」→出てきたツールバーの「マクロの実行(▲)」をクリック→「実行」をクリックすると計算される ↓----ここからコピー Dim i As Long, i0 As Long, j0 As Long, i1 As Long, j1 As Long, Ndata As Long Dim x0 As Double, y0 As Double, c As Double, sn As Double, cs As Double Dim xy() As Double ' 回転後の xn,yn Dim Ndada As Long ' ' データ数 Dim k As Double ' 回転角度(度) ' i0 = 1 ' x1があるセルの行 j0 = 1 ' x1があるセルの列 i1 = 1 ' 回転後のx1を書き込むセルの行 j1 = 3 ' 回転後のx1を書き込むセルの列 Ndata = 10000 ' データ数 k = 90 ' 角度(度) ' ReDim xy(Ndata, 2) As Double c = 3.14159265358979 / 180 sn = Sin(c * k) cs = Cos(c * k) ' Application.ScreenUpdating = False ' Excelグラフの再描画を禁止する Range(Cells(i1, j1), Cells(i1 + Ndata - 1, j1 + 1)).ClearContents ' 結果セルの消去 ' ' ------- xn,yn の読み込み&回転計算 ' For i = 0 To Ndata - 1 x0 = Val(Cells(i0 + i, j0)) y0 = Val(Cells(i0 + i, j0 + 1)) xy(i, 0) = x0 * cs - y0 * sn xy(i, 1) = x0 * sn + y0 * cs Next i ' ' ------- 計算結果の書き出し ' Range(Cells(i1, j1), Cells(i1 + Ndata - 1, j1 + 1)) = xy() ' Application.ScreenUpdating = True ' Excelグラフの再描画を許可する ' ↑----ここまでコピー ちなみに、このプルグラムでの計算時間はデータ数が10000で1秒くらいです。 ANo.2の方法(user関数)だと1分くらいかかります。

  • inara
  • ベストアンサー率72% (293/404)
回答No.2

どうしてもVBAで書きたいのなら、 (1) Excelワークシートで「ツール」→「マクロ」→「Visual Basic Editor」 (2) Visual Basic Editor で 「挿入」→「標準モジュール」で出てきた画面に以下をコピー Const c As Double = 3.14159265358979 / 180 Function new_x( k As Double, x As Double, y As Double) As Double new_x = x * Cos(c * k) - y * Sin(c * k) End Function Function new_y( k As Double, x As Double, y As Double) As Double new_y = x * Sin(c * k) + y * Cos(c * k) End Function (3) Excelワークシートに戻って、C1 に =new_x(90,A1,B1)、D1 に =new_y(90,A1,B1) と記入(k = 90度 の場合)し、C1とD1のセルをn 行までコピーする。 ANo.1 で書いたのと同様、 A列 に xn、B 列に yn が書かれていて、A1にx1、B1にy1があるとします。

catshoes01
質問者

お礼

すみません。何とかしてURLを探しました。 http://www.sis.otsuma.ac.jp/~tsutsumi/lecture/graphics/s6.htm このような例です。ここのURLからの引用になりますが、 Excel VBAでもできないのか?という相談です。 当方は下記のそれぞれの式の意味が全く理解できていないので P(xn,yn)としたときどう表示するかを聞きたいのですが・・・ 下記は多分エクセルではなくてVBだと思いますが・・・ Private Sub Multi_Mat_Vec_Click() Const pi = 3.1415927 Dim mat_a(1 To 2, 1 To 2) Dim vec_b(1 To 2), vec_c(1 To 2) rot_ang = Val(InputBox("回転角度は")) rot_ang = rot_ang * pi / 180 mat_a(1, 1) = Cos(rot_ang): mat_a(1, 2) = -Sin(rot_ang) mat_a(2, 1) = Sin(rot_ang): mat_a(2, 2) = Cos(rot_ang) vec_b(1) = Val(InputBox("xの値は ")) vec_b(2) = Val(InputBox("yの値は ")) '行列の掛け算の定番プログラム----------------------------------------  For i = 1 To 2 vec_c(i) = 0# For j = 1 To 2 vec_c(i) = vec_c(i) + mat_a(i, j) * vec_b(j) Next j Next i Print "変換結果は ("; Format(vec_c(1), "0.000"); ","; Format(vec_c(2), "0.000"); ")" End Sub 上記のどこにnが相当するかさえ理解できていません。

catshoes01
質問者

補足

すみません。データ量(n個)が多いのと速度を優先させるために matrixを利用したいのです。データ量は約10000行あります。 (一度に処理するデータ) これを一定の座標変換処理で A列はx値 B列はy値 として 一定の角度変換処理でD列に新x値 E列に新y値この操作が 200列あたりまで連続します。シートが数字だらけになるのです。 この操作を極力早く処理するためにMatrixを利用する必要が あるのです。

  • inara
  • ベストアンサー率72% (293/404)
回答No.1

VBAで書くほどでもないと思います。 Excelのワークシートの A列 に xn、B 列に yn が書かれているとき(A1にx1、B1にy1があるとにます) C1 に =A1*cos(k/180*PI())-B1*sin(k/180*PI()) D1 に =A1*sin(k/180*PI())+B1*cos(k/180*PI()) という式を書けば、C1 がx1'、D1 がy1'となります。あとはC1とD1をn行までコピーすれば xn, yn まで計算されます。

catshoes01
質問者

お礼

すみません。VBAコードでないと処理しきれないのです。 実験設備でデータが次々と10秒おきに入ってくる状況を 想定してください。似たような状況が存在しています。

関連するQ&A

  • 数学の大学入試問題の解き方

    Oを原点とする座標平面上の点Pn(Xn,Yn)(n=1,2,3,••••)は次のように帰納的に定義されている。 X1=1 Y1=√5 Xn+1=1/6(4Xn-√2Yn) Yn+1=1/6(√2Xn+4Yn) (n=1,2,3••••) また線分OPnの長さをpn, ∠PnOPn+1=θn 線分PnPn+1の長さをLnとする すべての自然数nについて pn+1=アpn cosθn=イ Ln=ウpn このア,イ,ウについて解く時に行列を用いずに解く方法はありますか? ありましたら長くなっても構いませんので詳しく解答をしていただけるとありがたいです

  • 点がx軸上に来ない

    ある問題で、「点Pn(Xn,Yn)がx軸上に来ないことを示せ」とあり、点Pnのy座標(=Yn)が5の倍数でないことまで判明しています。 しかし、その後行き詰まり、解答を見たところ… 「Ynは5の倍数でない。すなわち、点Pのy座標は0となることはないから、点Pはx軸上に来ない(終)」 となっていました。この「すなわち」の言いかえがどうも分かりません。 どなたか教えてください。

  • 行列式に関する質問です。

    行列式に関する質問です。 ファンデルモンドの行列式を用いて、「座標平面のn個の点(x1,y1)…(xn,yn)を通る(n-1)次曲線 y=a(n-1)x^(n-1)+a(n-2)x^(n-2)+…+a1x+a0はただ一つであることを示せ。」という問題です。 どの様にして証明すればいいのでしょうか?よろしくお願いします。

  • 座標変換について

    座標系XYZの空間に点A(X1,Y1,Z1)、点B(X2,Y2,Z2)、点C(X3,Y3,Z3)があります。 この3点を通る円の中心をP(X0,Y0,Z0)とし、 円の存在する平面をx'y'平面とします。 さらに原点を点P、x'軸はPAを通る直線とします。 座標系x'y'z'から円周上の点D(X',Y',Z')を求め 座標系XYZに変換した(X4,Y4,Z4)を求めたいのですが、どうすればよいのでしょうか? 以下のようにすれば求まると思うのですが角度α、β、γの求め方が分かりません。 X'' = X' * cosα - Y' * sinα Y'' = X' * sinα + Y' * cosα Z'' = Z' X''' = X'' Y''' = Y'' * cosβ - Z'' * sinβ Z''' = Y'' * sinβ + Z'' * cosβ X4 = X''' * cosγ + Z''' * sinγ Y4 = Y''' Z4 = Z''' * cosγ - X''' * sinγ よろしくお願いします。

  • 三角形の数列

    原点O(0,0)、A(1,0)、B(0,1)を頂点とする 三角形OABがある。 3つの線分OA、AB、BOの中点をそれぞれ、P1、Q1、R1とする。 また、3つの線分P1Q1、Q1R1、R1P1の 中点をそれぞれ、 R2、P2、Q2とする。 同様にしてRn、Pn、Qnまで定まったとき、線分PnQn、QnRn、RnPnの中点をそれぞれ、Rn、Pn、Qnとする。 Pn(xn,yn)とおく。 この時の、 Pnの座標を求めるときに 回答では、それぞれの中点を引き算を使って求めています. (x2=1/2-1/4=1/2など。) でも普通、 中点のx座標は、 線分の両端のx成分を足して2でわりますよね?? (y座標も同様) どうして引き算 もちこむのですか?? 仮にそれが、 この問題の解法だとしたら、 x2=1/2-1/4=1/2の -1/4は、どこからきたんですか?? 回答よろしくお願いします

  • 3次元空間で3点を通る平面を2次元座標で表すには

    3次元のベクトル(?)に関して質問させてください。 いまxyz座標の3次元空間の中に原点O(0,0,0), 点A(ax,ay,az), 点B(bx, by, bz)の3つの点があるとします。 3次元空間の中に3つの点があるので、これら3点を通る平面がひとつだけ決まります。 この平面がXY平面となるような、新しいXYZ空間を下記の条件で定義したいです。 原点O(0,0,0)に対応する点   → O'(0, 0, 0) 点A(ax,ay,az)に対応する点  → A'(αx, 0, 0) ただし αx = √(ax^2 + ay^2 + az^2) 点B(bx, by, bz)に対応する点 → B'(βx, βy, 0) このときのβx, βyの決め方を教えていただけないでしょうか? (おそらくβyの符号で2通りあると思います) ----- 具体的な目的は、以下のようなものです。 xyz座標の関数として値が決まるf(x, y, z)があります。 これを点O, A, Bを通る平面上でメッシュを切って計算しました。 この結果をgnuplotのpm3d mapでグラフ化したいのですが、gnuplotの入力は以下のようなフォーマットです。 X1 Y1 f(x1,y1,z1) X2 Y2 f(x2,y2,z2) X3 Y3 f(x3,y3,z3) X4 Y4 f(x4,y4,z4) ... そこでxyz空間の平面OAB上の点Pn(xn,yn,zn)を対応するXY平面上の点Pn'(Xn,Yn)に変換したいです。 よろしくお願いします。

  • 閉曲線の凹みの判定法

    座標の列(x1,y1),(x2,y2),...,(xn,yn)で与えられる、各点が次の点と接続する閉曲線があります((xn,yn)は(x1,y1)に接続します)。 この曲線のどこかに凹みがあるかどうかを判定するにはどうしたらよいのでしょうか?

  • 行列式です

    座標(3、1)の点を原点周りに30°動かす。どこに動くか行列式を用いて求めよ。答えは3√31/2と3+√3/2になりますか??あと座標(2.1)をY=Xに対して線対称移動したらどこに動くか行列を用いて求めろ。という問題はどうなりますか?おねがいします

  • mathematicaでリストの格納

    mathematicaでTable関数で作成したリスト {{x1, y1, z1, f(x1,y1,z1)}, {x2, y2, z2, f(x2,y2,z2)}, ... , {xn, yn, zn, f(xn,yn,zn)}} 中のx1~xnまでの各成分とy1~ynまで(、z1~znまで、 f(x1,y1,z1)~f(xn, yn, zn)までの各成分)をそれぞれ配列に格納するにはどうすればいいのでしょうか?(C言語のようにループ文で配列に格納することはできないのでしょうか?) もしくは、行列中で列の成分を取り出すことはできますか? どなたか解法を示していただければ幸いです。

  • 三角形 角度が同じ

    角度が等しくなる。ことがわからないので質問します。 Oを原点とするxy平面の第1象限にOP1=1を満たす点P1(x1,y1)をとる。このとき、線分OP1とx軸のなす角をθ(0<θ<π/2)とする。点(0,x1)を中心とする半径x1の円と、線分OP1との交点をP2(x2,y2)(x2>0)とする。次に、点(0,x2)を中心とする半径x2の円と線分OP1との交点をP3(x3,y3)(x3>0)とする。以下同様にして、点Pn(xn,yn)(xn>0)(n=1,2,・・・・)を定める。 (1)x2をθを用いて表せ 解答には、添付した画像のような図がのっているのですが、点(0,x1)を点Bとし、点Bから線分OP1におろした垂線の足をHとして、∠OBH=∠P2BH=θになることがわかりません。三角形OP1x1と三角形OBH,三角形P2BHが相似になっているかと思たのですが、相似の条件がわかりません。角がθになる理由は、円周角や接弦定理ではないと思うのです。どなたか∠OBH=∠P2BH=θとなる理由を教えてください。