MickD 发表于 2007-12-6 21:11:09

acad的向量/矩阵函数

我正在开发一个小lib,用于在vba中转换实体等,我已经有了一点点开始,但是由于我多年没有接触vba,我对一些语法和适当结构的细节有点生疏了。
关于如何继续,有什么建议吗?
我看到的第一个问题是将数组分配给其他数组,是否有比将每个项目分配给其他数组中的每个项目更简单的方法,我似乎无法在不出现编译错误的情况下做到这一点-
Dim a1(2) As Double,a2 As Double
'用一些值填充a1
'
' assign a1 to a2
a2 = a1 '
正如您在下面的代码中可以看到的,我一直在使用变量来传递返回值,然后将各个元素分配给适当的数组,是否有更好的方法
谢谢。
'''''''''------- Vector Methods --------------'''''''''''
Public Function VecNorm(vec() As Double) As Double()
'Normalises the incoming vector.
Dim vecn(2) As Double
Dim unit As Double
unit = Sqr(vec(0) * vec(0) + vec(1) * vec(1) + vec(2) * vec(2))
vecn(0) = vec(0) / unit: vecn(1) = vec(1) / unit: vecn(2) = vec(2) / unit
VecNorm = vecn
End Function
Function VecCross(v1() As Double, v2() As Double) As Variant
    Dim vec(2)
    vec(0) = v1(1) * v2(2) - v2(1) * v1(2)
    vec(1) = v1(2) * v2(0) - v2(2) * v1(0)
    vec(2) = v1(0) * v2(1) - v2(0) * v1(1)
    VecCross = vec
End Function
'''''''''--------- Matrix Methods ------------'''''''''''
Public Function xFormMat(vx() As Double, vy() As Double, vz() As Double) As Variant
'Uses the incoming vectors to transform the entity being passed in
Dim mat(0 To 3, 0 To 3) As Double
mat(0, 0) = vx(0): mat(0, 1) = vy(0): mat(0, 2) = vz(0): mat(0, 3) = 0#
mat(1, 0) = vx(1): mat(1, 1) = vy(1): mat(1, 2) = vz(1): mat(1, 3) = 0#
mat(2, 0) = vx(2): mat(2, 1) = vy(2): mat(2, 2) = vz(2): mat(2, 3) = 0#
mat(3, 0) = 0#: mat(3, 1) = 0#: mat(3, 2) = 0#: mat(3, 3) = 1#
xFormMat = mat
End Function
Public Function GetMatFromLine(line As AcadLine) As Variant
'builds a matrix based on the line's sp, ep and normal
Dim mat(0 To 3, 0 To 3) As Double
Dim vx(2) As Double, vy(2) As Double, vz(2) As Double
'get the lines ep-sp vector to create the z axis:
vz(0) = line.EndPoint(0) - line.StartPoint(0)
vz(1) = line.EndPoint(1) - line.StartPoint(1)
vz(2) = line.EndPoint(2) - line.StartPoint(2)
'normalise it:
Dim retvec As Variant
retvec = VecNorm(vz)
vz(0) = retvec(0): vz(1) = retvec(1): vz(2) = retvec(2)
'get the line's normal for the x vector:
vx(0) = line.Normal(0)
vx(1) = line.Normal(1)
vx(2) = line.Normal(2)
'create the y vector by xproduct of z over x:
retvec = VecCross(vz, vx)
vy(0) = retvec(0): vy(1) = retvec(1): vy(2) = retvec(2)
'normalise it:
retvec = VecNorm(vy)
vy(0) = retvec(0): vy(1) = retvec(1): vy(2) = retvec(2)
'plug 'em into the matrix:
mat(0, 0) = vx(0): mat(0, 1) = vy(0): mat(0, 2) = vz(0): mat(0, 3) = 0#
mat(1, 0) = vx(1): mat(1, 1) = vy(1): mat(1, 2) = vz(1): mat(1, 3) = 0#
mat(2, 0) = vx(2): mat(2, 1) = vy(2): mat(2, 2) = vz(2): mat(2, 3) = 0#
mat(3, 0) = 0#: mat(3, 1) = 0#: mat(3, 2) = 0#: mat(3, 3) = 1#
GetMatFromLine = mat
End Function

我还有很多要添加的内容,我会将它们张贴出来,但在我产生太多垃圾之前,我需要一些建议
**** Hidden Message *****

MickD 发表于 2007-12-6 21:24:28

嗨,米克。警告,下面这篇文章并不是我写过的最好的表达方式
如果您使用用户定义类型(UDT)(可以说,大括号与结构大致类似),您可以将一个UDT变量设置为同一类型的另一UDT变量,并将数据(有点像OO深度克隆)从一个复制到另一个,而不是将指针(我在这里滥用语言,因为UDT变量不是指针)分配给另一个(如果它们是对象而不是UDT,就会发生这种情况)
您的应用程序是否可以利用此漏洞
也许,通过矩阵和向量定义的类型。说到矩阵/向量数学,我是个白痴,所以我不能说
您想要一个简单的UDT代码示例吗?

MickD 发表于 2007-12-6 21:52:21

我在考虑创建一些类,这似乎是合乎逻辑的,但我可以使用一些函数,我只需要编写一次,我只是很懒<br>是的,为什么不呢?我们在谈论vb类,不是吗?

MickD 发表于 2007-12-6 21:56:04


没有。用户定义类型不是类。想想你所熟悉的最接近的类似数据类型的C结构。
让我举个例子来说明一下...

SEANT 发表于 2007-12-6 22:11:26

>>C结构
很酷!
我确实只有最后一个问题,比如我有一个矩阵udt,我仍然需要将其分配给数组以传递给transformBy方法...虽然我可以纠正一个功能来即时执行此操作,但我猜。

Dnereb 发表于 2007-12-6 22:23:00

又快又脏,希望它能照亮。
Option Explicit
Type TPoint
    X As Double
    Y As Double
    Z As Double
End Type
Type TLine
    P1 As TPoint
    P2 As TPoint
End Type
Sub Demo ( )
    Dim P1 As TPoint, _
      P2 As TPoint
    With P1
      .X = 20
      .Y = 20
    End With
   
    ''Set P2 = P1, remembering it's a copy of the data.
    ''Not the same as setting one object to another.
    ''If you're a .NET geek think of UDTs as value types
    ''(as opposed to reference types).
   
    P2 = P1
   
    ''Show P2's data
    With P2
      Debug.Print "P2's initial data:"
      Debug.Print "P2.X ="; .X; ", P2.Y = "; .Y
      Debug.Print
    End With
   
    ''prove P2 is not a pointer to P1 by assigning new
    ''data to P1 and reprinting P2's data
   
    With P1
      .X = 10
      .Y = 10
    End With
    ''show p2's data again (ha, still 20, 20)
    With P2
      Debug.Print "P2's data after P1 given new values:"
      Debug.Print "P2.X ="; .X; ", P2.Y = "; .Y
      Debug.Print
    End With
   
    ''now demonstrate a deeper copy
   
    Dim L1 As TLine, _
      L2 As TLine
      
    ''initialize L1 using previously defined P1 and P2
   
    With L1
      .P1 = P1
      .P2 = P2
    End With
   
    ''now force L2 to have a copy of L1's data (the deeper copy)
   
    L2 = L1
   
    ''show L2's data
   
    With L2
      Debug.Print "L2's data:"
      Debug.Print "L2, P1.x = "; .P1.X; " , P1.y = "; .P1.Y
      Debug.Print "L2, P2.x = "; .P2.X; " , P2.y = "; .P2.Y
    End With
   
    ''ha, cool you say; not too shabby for vb.
End Sub
玩得开心。

Dnereb 发表于 2007-12-6 22:28:12

谢谢议员,这个周末我会去看看,19号打电话过来
我会让你知道我的进展。
再次感谢。

Bryco 发表于 2007-12-6 22:31:08

这是我的荣幸,米克。看看你的解决方案的结果会很有趣。

Dnereb 发表于 2007-12-7 04:23:36

哇,议员,这很有启发性。
我正要建议:
Dim a1(2) As Double, a2() As Double 'a2 as
dynamic'fill a1 with some values
'
'a1 to a2
a2 = a1 '

and
Function VecCross(v1() As Double, v2() As Double) As Double()
但是这种方法并不像你发布的那么通用。

Bryco 发表于 2007-12-7 08:16:37

为了使你的代码更简洁,请使用这些语法
Sub Test()
    Dim A1(2) As Double
    Dim A2() As Double
    Dim A3() As Double
    Dim Var As Variant
   
   
    A1(0) = 1: A1(1) = 1: A1(2) = 2
    A2() = A1()
   
    Var = A1()
   
    A3() = Var
   

   
End Sub
注意:数组必须在没有任何元素的情况下进行de声明,以便能够为其分配另一个数组。
页: [1] 2
查看完整版本: acad的向量/矩阵函数