兰州人 发表于 2007-2-17 13:04:00

[求助]圆和空间任意直线垂直公式

<p>要求见图,求一个通用公式,圆要与空间任意直线垂直的公式.</p><p>原因是在Autocad可中画圆,在X-Y平面完成,用VB处理UCS编程方法麻烦.有个数学公式,简单明了.</p><p></p><p>我现在做法比较麻烦,下面的例子用反正切方法,解绕Z轴得出公式</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><p>用</p><p>L=SQR(dx^2+dy^2+dz^2)方程。</p><p>&nbsp;&nbsp;&nbsp; alfa = (x - x1) / Sqr((x - x1) ^ 2 + (y - y1) ^ 2 + (z - z1) ^ 2)&nbsp;&nbsp; 绕X轴<br/>&nbsp;&nbsp;&nbsp; beta = (y - y1) / Sqr((x - x1) ^ 2 + (y - y1) ^ 2 + (z - z1) ^ 2)  绕Y轴<br/>&nbsp;&nbsp;&nbsp; theta = (z - z1) / Sqr((x - x1) ^ 2 + (y - y1) ^ 2 + (z - z1) ^ 2)  绕Z轴<br/>也还需要很多判断语句</p><p>请教各位大侠是否还有其它什么公式可以一次性解决.</p>

tqr 发表于 2007-2-17 14:41:00

<p>这样也可以:</p><p>在XY平面画圆,再从圆心画平行与Z轴的直线作辅助线,然后用对齐命令使圆到位。</p>

兰州人 发表于 2007-2-17 20:11:00

<p>这要用到3X3的矩阵,才能编程,在线段a-b外找一点c,过c点垂直线段a-b且交于线段a点??,才有解.通过a-c点,采用rotate3d point1,point2,Pi/2 才能实现.</p><p>我现在已经找到3X3矩阵公式,</p><p>形体的旋转变换有绕主轴旋转,或绕空间任一直线旋转等多种形式。若令Rθ表示绕z轴转θ角,Rβ表示绕y轴转β角,Rγ表示绕x轴转γ角,则点P绕x、y、z轴转γ、β、θ角的变换公式是<br/>R=RθRβRγ<br/>&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp; cosθ&nbsp;&nbsp; sinθ&nbsp;&nbsp; 0 |<br/>Rθ= | -sinθ&nbsp;&nbsp; cosθ&nbsp;&nbsp;&nbsp; 0&nbsp; |<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp; 0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0&nbsp;&nbsp;&nbsp;&nbsp; 1&nbsp; |</p><p><br/>&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp; cosβ&nbsp; -sinβ&nbsp;&nbsp; 0&nbsp; |<br/>Rβ= |&nbsp;&nbsp; 0&nbsp;&nbsp;&nbsp;&nbsp; 1&nbsp;&nbsp;&nbsp;&nbsp; 0&nbsp;&nbsp; |<br/>&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp; sinβ&nbsp; cosβ&nbsp;&nbsp;&nbsp; 1&nbsp;&nbsp; |</p><p>&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp; 1&nbsp;&nbsp;&nbsp;&nbsp; 0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0&nbsp;&nbsp; |<br/>Rγ= |&nbsp; 0&nbsp;&nbsp;&nbsp; cosγ&nbsp;&nbsp; sinγ&nbsp; |<br/>&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp; 0&nbsp;&nbsp;&nbsp;&nbsp; -sinγ&nbsp; cosγ |<br/></p><p>如何展开3X3矩阵公式,</p><p>求</p><p>X = </p><p>Y =</p><p>Z = </p><p>这是我的终极目标.</p><p>楼上所述,只能手动调试,不适合于编程.</p>

兰州人 发表于 2007-2-18 14:00:00

<p><strong>计算点到圆的最近距离及交点坐标:</strong><br/><br/>如果该点在圆心,因为圆心到圆周任一点的距离相等,返回<font face="宋体, MS Song">UNDEFINED</font>。<br/><br/>连接点<font face="宋体, MS Song">P</font>和圆心<font face="宋体, MS Song">O</font>,如果<font face="宋体, MS Song">PO</font>平行于<font face="宋体, MS Song">X</font>轴,则根据<font face="宋体, MS Song">P</font>在<font face="宋体, MS Song">O</font>的左边还是右边计算出最近点的横坐标为<font face="宋体, MS Song">centerPoint.x - radius </font>或<font face="宋体, MS Song"> centerPoint.x + radius</font>。如果<font face="宋体, MS Song">PO</font>平行于<font face="宋体, MS Song">Y</font>轴,则根据<font face="宋体, MS Song">P</font>在<font face="宋体, MS Song">O</font>的上边还是下边计算出最近点的纵坐标为<font face="宋体, MS Song"> centerPoint.y -+radius</font>或<font face="宋体, MS Song"> centerPoint.y - radius</font>。如果<font face="宋体, MS Song">PO</font>不平行于<font face="宋体, MS Song">X</font>轴和<font face="宋体, MS Song">Y</font>轴,则<font face="宋体, MS Song">PO</font>的斜率存在且不为<font face="宋体, MS Song">0</font>,这时直线<font face="宋体, MS Song">PO</font>斜率为<font face="宋体, MS Song">k = </font>(<font face="宋体, MS Song"> P.y - O.y </font>)<font face="宋体, MS Song">/ ( P.x - O.x )</font>。直线<font face="宋体, MS Song">PO</font>的方程为:<font face="宋体, MS Song">y = k * ( x - P.x) + P.y</font>。设圆方程为<shapetype id="_x0000_t75" stroked="f" filled="f" path="m@4@5l@4@11@9@11@9@5xe" opreferrelative="t" ospt="75" coordsize="21600,21600"><font face="宋体, MS Song">
                                        <stroke joinstyle="miter"></stroke><formulas><f eqn="if lineDrawn pixelLineWidth 0"></f><f eqn="sum @0 1 0"></f><f eqn="sum 0 0 @1"></f><f eqn="prod @2 1 2"></f><f eqn="prod @3 21600 pixelWidth"></f><f eqn="prod @3 21600 pixelHeight"></f><f eqn="sum @0 0 1"></f><f eqn="prod @6 1 2"></f><f eqn="prod @7 21600 pixelWidth"></f><f eqn="sum @8 21600 0"></f><f eqn="prod @7 21600 pixelHeight"></f><f eqn="sum @10 21600 0"></f></formulas><path oconnecttype="rect" gradientshapeok="t" oextrusionok="f"></path><lock aspectratio="t" vext="edit"></lock></font></shapetype><shape id="_x0000_i1025" alt="" type="#_x0000_t75" style="WIDTH: 12pt; HEIGHT: 12pt;"><imagedata ohref="http://www.vfor.net/forum/images/smilies/frown.gif" src="file:///C:\DOCUME~1\NINGYO~1\LOCALS~1\Temp\msohtml1\01\clip_image001.gif"></imagedata></shape><font face="宋体, MS Song">x - O.x ) ^2 + ( y - O.y ) ^2 = r ^2</font>,联立两方程组可以解出直线<font face="宋体, MS Song">PO</font>和圆的交点,取其中离<font face="宋体, MS Song">P</font>点较近的交点即可。</p><p>这是一种X-Y平面求交点的解法.<br style="mso-special-character: line-break;"/><br style="mso-special-character: line-break;"/></p>

兰州人 发表于 2007-2-21 12:22:00

本帖最后由 作者 于 2007-2-21 12:51:46 编辑 <br /><br /> <p>采用offset平移,作平行线方法,搞定效果见图。</p><p></p><p>&nbsp;</p><p>offset 线段a-b与线段a'-b'平行,b-b'与a-b是垂直的。</p><p>现在关键问题是要找参数方程公式求解.省去建立临时线段和删除线段的无用功。</p><p>Function Rotate3dEntity(ByVal EnterEintity As Object, ByVal ll As Object) As Object<br/>&nbsp; Dim theta As Double<br/>&nbsp; Dim x As Double, x1 As Double, y As Double, y1 As Double, z As Double, z1 As Double<br/>&nbsp; Dim Point1 As Variant, Point2 As Variant<br/>&nbsp; Dim l1 As Object, l2 As Object<br/>&nbsp; 'Dim Point1(0 To 2) As Double, Point2(0 To 2) As Double<br/>&nbsp; Point1 = ll.StartPoint<br/>&nbsp; Point2 = ll.EndPoint</p><p>&nbsp; x = Point1(0): x1 = Point2(0)<br/>&nbsp; y = Point1(1): y1 = Point2(1)<br/>&nbsp; z = Point1(2): z1 = Point2(2)<br/>'<br/>&nbsp; theta = (z - z1) / Sqr((x - x1) ^ 2 + (y - y1) ^ 2 + (z - z1) ^ 2)<br/>&nbsp; theta = Format(ArcCos(theta) - Pi / 2, "0.00")<br/>&nbsp; If Format(x - x1, "0.00") = 0 And Format(y - y1, "0.00") = 0 Then<br/>&nbsp;&nbsp; If z1 - z &lt; 0 And Format(x - x1, "0.00") = 0# And Format(y - y1, "0.00") = 0# Then<br/>&nbsp;&nbsp;&nbsp;&nbsp; Point2(0) = Point2(0) + 2<br/>&nbsp;&nbsp;&nbsp;&nbsp; Point2(1) = Point2(1)<br/>&nbsp;&nbsp;&nbsp;&nbsp; Point2(2) = Point2(2)<br/>&nbsp;&nbsp;&nbsp;&nbsp; EnterEintity.Rotate3D ll.EndPoint, Point2, Pi<br/>&nbsp;&nbsp; End If<br/>&nbsp; <br/>&nbsp; ElseIf x - x1 &lt;&gt; 0 Or y - y1 &lt;&gt; 0 Then<br/>&nbsp;&nbsp; ll.Offset 10<br/>&nbsp;&nbsp; With obj_ModelSpace<br/>&nbsp;&nbsp;&nbsp;&nbsp; Set l1 = .Item(.Count - 1)<br/>&nbsp;&nbsp;&nbsp;&nbsp; Set l2 = .AddLine(ll.EndPoint, l1.EndPoint)<br/>&nbsp;&nbsp;&nbsp;&nbsp; l1.Delete<br/>&nbsp;&nbsp; End With<br/>&nbsp;&nbsp; If Format(z - z1, "0.00") = 0 Then<br/>&nbsp;&nbsp;&nbsp;&nbsp; EnterEintity.Rotate3D ll.EndPoint, l2.EndPoint, Pi / 2<br/>&nbsp;&nbsp; ElseIf z - z1 &lt;&gt; 0 Then<br/>&nbsp;&nbsp;&nbsp;&nbsp; EnterEintity.Rotate3D ll.EndPoint, l2.EndPoint, theta<br/>&nbsp;&nbsp;&nbsp;&nbsp; If z1 - z &lt; 0 Then<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; EnterEintity.Rotate3D ll.EndPoint, l2.EndPoint, Pi<br/>&nbsp;&nbsp;&nbsp;&nbsp; End If<br/>&nbsp;&nbsp; End If</p><p>&nbsp;&nbsp; l2.Delete<br/>&nbsp;End If</p><p><br/>End Function</p><p>&nbsp;</p><p>Function lll()<br/>' Dim Point1 As Variant, Point2 As Variant</p><p>&nbsp;If boo = False Then<br/>&nbsp;&nbsp; AutoCADConnect<br/>&nbsp;End If<br/>&nbsp;Dim ll As Object, ss As Object, ReturnEntity As Object<br/>&nbsp;For Each ll In obj_ModelSpace<br/>&nbsp;&nbsp; If ll.objectname = "AcDbLine" Then<br/>&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp; Set ss = obj_ModelSpace.AddCone(ll.EndPoint, 3, 10)<br/>&nbsp;&nbsp;&nbsp;&nbsp; Set ReturnEntity = Rotate3dEntity(ss, ll)<br/>&nbsp;&nbsp; End If<br/>&nbsp;Next ll<br/>&nbsp;obj_Doc.Regen (0)<br/>End Function<br/></p><p>&nbsp;</p>

pjf2000qq 发表于 2007-3-1 16:55:00

不好意思没有看明白
页: [1]
查看完整版本: [求助]圆和空间任意直线垂直公式