プロが教える店舗&オフィスのセキュリティ対策術

今 P1(x1、y1)
  P2(x2、y2)
  P3(x3、y3)
     略
  Pn(xn,yn)

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

A 回答 (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グラフの再描画を許可する
    • good
    • 0
この回答へのお礼

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

お礼日時:2007/03/30 07:47

一括計算するプログラムを作ってみました(動作確認済み)。

マクロの作成方法と実行方法は以下のとおりです。プログラム中に変数の意味うを書いておきましたので、数値は適当に直してください。

【マクロ作成】 「ツール」→「マクロ」→「マクロ」→マクロ名に名前(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分くらいかかります。
    • good
    • 0

どうしても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があるとします。

この回答への補足

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

補足日時:2007/03/29 19:33
    • good
    • 0
この回答へのお礼

すみません。何とかしてURLを探しました。
http://www.sis.otsuma.ac.jp/~tsutsumi/lecture/gr …
このような例です。ここの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が相当するかさえ理解できていません。

お礼日時:2007/03/29 20:33

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 まで計算されます。
    • good
    • 0
この回答へのお礼

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

お礼日時:2007/03/29 19:28

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!