兰州人 发表于 2006-12-25 13:48:00

反正切函数确定空间直线的方向角

<p>问题提出:在空间坐标系中,插入一图块需要的基本条件是,插入的空间坐标点,X,Y,Z轴的方向角。</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 我的解决方法是用一个线段来确定插入空间坐标系中的方向角,特点是程序调试时对方向角的确认比较直观,提高工作效率。</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在空间任意两点可以确定一条直线,两点坐标确定,一种方法是输入坐标,另一种是通过交互式方法确定两点坐标。</p><p>Function RotateZ_Axis(ByVal sPoint As Variant, ByVal ePoint As Variant) As Double<br/>&nbsp;&nbsp;&nbsp; Dim EntAngle As Double<br/>&nbsp;&nbsp;&nbsp; Dim deltaX As Double, deltaY As Double, deltaZ As Double<br/>&nbsp;&nbsp;&nbsp; deltaX = sPoint(0) - ePoint(0): deltaY = sPoint(1) - ePoint(1): deltaZ = sPoint(2) - ePoint(2):<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp; If deltaY &gt;= 0 And deltaX &gt; 0 Then<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; EntAngle = Atn(deltaY / deltaX)<br/>&nbsp;&nbsp;&nbsp; ElseIf deltaY &gt;= 0 And deltaX &lt; 0 Then<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; EntAngle = Pi + Atn(deltaY / deltaX)<br/>&nbsp;&nbsp;&nbsp; ElseIf deltaY &lt; 0 And deltaX &lt; 0 Then<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; EntAngle = Pi + Atn(deltaY / deltaX)<br/>&nbsp;&nbsp;&nbsp; ElseIf deltaY &lt; 0 And deltaX &gt; 0 Then<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; EntAngle = 2 * Pi + Atn(deltaY / deltaX)<br/>&nbsp;&nbsp;&nbsp; End If<br/>&nbsp;&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp; If deltaX = 0 Then<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; If deltaY &gt; 0 Then<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; EntAngle = Pi / 2<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ElseIf deltaY &gt; 0 Then<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; EntAngle = Pi * 1.5<br/>&nbsp;&nbsp;&nbsp;&nbsp; End If<br/>&nbsp;&nbsp;&nbsp; End If<br/>&nbsp;&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp; RotateZ_Axis = EntAngle<br/>End Function</p><p>Function RotateX_Axis(txtEnt As String) As Double<br/>&nbsp;&nbsp;&nbsp; Dim Ent As AcadLine<br/>&nbsp;&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp; Dim EntAngle As Double<br/>&nbsp;&nbsp;&nbsp; Set Ent = ThisDrawing.HandleToObject(txtEnt)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp; If deltaY &gt;= 0 And deltaX &gt; 0 Then<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; EntAngle = Atn(deltaY / deltaX)<br/>&nbsp;&nbsp;&nbsp; ElseIf deltaY &gt;= 0 And deltaX &lt; 0 Then<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; EntAngle = Pi + Atn(deltaY / deltaX)<br/>&nbsp;&nbsp;&nbsp; ElseIf deltaY &lt; 0 And deltaX &lt; 0 Then<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; EntAngle = Pi + Atn(deltaY / deltaX)<br/>&nbsp;&nbsp;&nbsp; ElseIf deltaY &lt; 0 And deltaX &gt; 0 Then<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; EntAngle = 2 * Pi + Atn(deltaY / deltaX)<br/>&nbsp;&nbsp;&nbsp; End If<br/>&nbsp;&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp; If deltaX = 0 Then<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; If deltaY &gt; 0 Then<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; EntAngle = Pi / 2<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ElseIf deltaY &gt; 0 Then<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; EntAngle = Pi * 1.5<br/>&nbsp;&nbsp;&nbsp;&nbsp; End If<br/>&nbsp;&nbsp;&nbsp; End If<br/>&nbsp;&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp; RotateZ_Axis = EntAngle<br/>End Function<br/></p><p>RotateZ_Axis,RotateX_Axis,RotateY_Axis返回的的是直线在X,Y,Z坐标轴的方向角。</p><p>请问各位大侠是否还有更好的几何解决方法。</p>

highflybir 发表于 2006-12-25 14:52:00

<p>想法很好,但是算法可能可能复杂了一点:</p><p>我的建议:</p><p>已知两点pt1 (x1,y1,z1),pt2 (x2,y2,z2) </p><p>得到两点的矢量 (mapcar '- pt1 pt2)&nbsp;即 dx ,dy, dz和两点的距离 L </p><p>则其方向角为 acos (dx/L)&nbsp;,acos (dy/L) ,acos (dz/L)</p><p>acos为反余弦函数.</p><p></p><p></p>

兰州人 发表于 2006-12-26 09:36:00

本帖最后由 作者 于 2008-12-21 17:45:55 编辑

谢谢楼上给的思路,其解法如下Sub ll()
Dim objLine As AcadLine
Dim objCount As Integer
Dim rotateAngular As Double, rotateDegree As Double
Dim rotateAngularX As Double, rotateAngularY As Double, rotateAngularZ As Double
With ThisDrawing.ModelSpace
    objCount = .Count
    For ii = 0 To objCount - 1
      Set objLine = .Item(ii)
      With objLine
      rotateAngularX = ACos(.Delta(0) / .Length)
      Xx = RadToDeg(rotateAngularX)
      rotateAngularY = ACos(.Delta(1) / .Length)
      Yy = RadToDeg(rotateAngularY)
      rotateAngularZ = ACos(.Delta(2) / .Length)
      Zz = RadToDeg(rotateAngularZ)
      End With
    Next ii
   
   
End With
End Sub
Function ACos(ByVal Number As Double) As Double
If Number = 0 Then
    ACos = 2 * Atn(1)
Else
    ACos = Atn(-Number / Sqr(-Number * Number + 1)) + 2 * Atn(1)
End If
End Function
Function RadToDeg(Alfa As Double) As Double
RadToDeg = Alfa * 180 * Alfa / (Atn(1) * 4)
End Function


-----------------------------------------------
L=SQR(dx^2+dy^2+dz^2),我用过这种方程。
方程解如下:
    alfa = (x - x1) / Sqr((x - x1) ^ 2 + (y - y1) ^ 2 + (z - z1) ^ 2)
    beta = (y - y1) / Sqr((x - x1) ^ 2 + (y - y1) ^ 2 + (z - z1) ^ 2)
    theta = (z - z1) / Sqr((x - x1) ^ 2 + (y - y1) ^ 2 + (z - z1) ^ 2)

页: [1]
查看完整版本: 反正切函数确定空间直线的方向角