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

acad的向量/矩阵函数

本人'我正在开发一个小库,用于在vba、I&#039中转换实体等;我已经有了一个开始,但正如我所做的那样'多年来,我对vba的一些语法和正确结构的细节有点生疏
有什么关于如何继续的建议吗
我看到的第一个问题是将数组分配给其他数组,有没有比将每个项目分配给另一个数组中的每个项目更简单的方法;t似乎能够在没有编译错误的情况下完成这样的事情-Dim a1(2)作为Double,a2作为Double;用一些值填充a1
&039;将a1分配给a2=a1和#039<-唐#039;正如您在下面的代码中所看到的,我一直在使用变体传递返回值,然后将各个元素分配给适当的数组,有更好的方法吗
谢谢
'''''''''------- 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
我还有很多要添加的内容,将发布它们,但在我产生太多垃圾之前,我希望得到一些建议

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

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

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

我在考虑创建一些类,这似乎是合乎逻辑的,但我可以通过一些函数逃脱惩罚,我只需要编写一次,我'我只是懒惰,为什么不呢?我们说的是vb类;我们不是吗?

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


没有。用户定义类型不是类。将C结构视为您所使用的最接近的类似数据类型'我们熟悉
让我举个例子来说明。。。

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

&燃气轮机&燃气轮机;C结构很酷
不过,我确实还有最后一个问题,比如说我有一个矩阵udt,我仍然需要将它分配给一个数组,以传递给transformBy方法……不过我想我可以在运行时修正一个函数。

Bryco 发表于 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 玩得开心

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

谢谢议员,我会在周末过来看看,19号打电话过来;我会告诉你我过得怎么样。再次谢谢。

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

我的荣幸,米克。看看你的解决方案会是什么样子,我会很感兴趣的。

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

哇,议员,这很有启发性
我正要建议:
Dim a1(2)为Double,a2()为Double'a2为动态;用一些值填充a1
&039;将a1分配给a2=a1和#039<-应该可以工作,并且函数VecCross(v1()作为Double,v2()作为doug)作为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 注意:数组必须在没有任何元素的情况下声明,才能将另一个数组分配给;它
页: [1] 2
查看完整版本: acad的向量/矩阵函数