[求助]圆和空间任意直线垂直公式
<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/> Dim EntAngle As Double<br/> Dim deltaX As Double, deltaY As Double, deltaZ As Double<br/> deltaX = sPoint(0) - ePoint(0): deltaY = sPoint(1) - ePoint(1): deltaZ = sPoint(2) - ePoint(2):<br/> <br/> If deltaY >= 0 And deltaX > 0 Then<br/> EntAngle = Atn(deltaY / deltaX)<br/> ElseIf deltaY >= 0 And deltaX < 0 Then<br/> EntAngle = Pi + Atn(deltaY / deltaX)<br/> ElseIf deltaY < 0 And deltaX < 0 Then<br/> EntAngle = Pi + Atn(deltaY / deltaX)<br/> ElseIf deltaY < 0 And deltaX > 0 Then<br/> EntAngle = 2 * Pi + Atn(deltaY / deltaX)<br/> End If<br/> <br/> If deltaX = 0 Then<br/> If deltaY > 0 Then<br/> EntAngle = Pi / 2<br/> ElseIf deltaY > 0 Then<br/> EntAngle = Pi * 1.5<br/> End If<br/> End If<br/> <br/> <br/> RotateZ_Axis = EntAngle<br/>End Function</p><p>Function RotateX_Axis(txtEnt As String) As Double<br/> Dim Ent As AcadLine<br/> <br/> Dim EntAngle As Double<br/> Set Ent = ThisDrawing.HandleToObject(txtEnt)<br/> <br/> If deltaY >= 0 And deltaX > 0 Then<br/> EntAngle = Atn(deltaY / deltaX)<br/> ElseIf deltaY >= 0 And deltaX < 0 Then<br/> EntAngle = Pi + Atn(deltaY / deltaX)<br/> ElseIf deltaY < 0 And deltaX < 0 Then<br/> EntAngle = Pi + Atn(deltaY / deltaX)<br/> ElseIf deltaY < 0 And deltaX > 0 Then<br/> EntAngle = 2 * Pi + Atn(deltaY / deltaX)<br/> End If<br/> <br/> If deltaX = 0 Then<br/> If deltaY > 0 Then<br/> EntAngle = Pi / 2<br/> ElseIf deltaY > 0 Then<br/> EntAngle = Pi * 1.5<br/> End If<br/> End If<br/> <br/> <br/> 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> alfa = (x - x1) / Sqr((x - x1) ^ 2 + (y - y1) ^ 2 + (z - z1) ^ 2) 绕X轴<br/> beta = (y - y1) / Sqr((x - x1) ^ 2 + (y - y1) ^ 2 + (z - z1) ^ 2) 绕Y轴<br/> theta = (z - z1) / Sqr((x - x1) ^ 2 + (y - y1) ^ 2 + (z - z1) ^ 2) 绕Z轴<br/>也还需要很多判断语句</p><p>请教各位大侠是否还有其它什么公式可以一次性解决.</p> <p>这样也可以:</p><p>在XY平面画圆,再从圆心画平行与Z轴的直线作辅助线,然后用对齐命令使圆到位。</p> <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/> | cosθ sinθ 0 |<br/>Rθ= | -sinθ cosθ 0 |<br/> | 0 0 1 |</p><p><br/> | cosβ -sinβ 0 |<br/>Rβ= | 0 1 0 |<br/> | sinβ cosβ 1 |</p><p> | 1 0 0 |<br/>Rγ= | 0 cosγ sinγ |<br/> | 0 -sinγ cosγ |<br/></p><p>如何展开3X3矩阵公式,</p><p>求</p><p>X = </p><p>Y =</p><p>Z = </p><p>这是我的终极目标.</p><p>楼上所述,只能手动调试,不适合于编程.</p> <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:51:46 编辑 <br /><br /> <p>采用offset平移,作平行线方法,搞定效果见图。</p><p></p><p> </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/> Dim theta As Double<br/> Dim x As Double, x1 As Double, y As Double, y1 As Double, z As Double, z1 As Double<br/> Dim Point1 As Variant, Point2 As Variant<br/> Dim l1 As Object, l2 As Object<br/> 'Dim Point1(0 To 2) As Double, Point2(0 To 2) As Double<br/> Point1 = ll.StartPoint<br/> Point2 = ll.EndPoint</p><p> x = Point1(0): x1 = Point2(0)<br/> y = Point1(1): y1 = Point2(1)<br/> z = Point1(2): z1 = Point2(2)<br/>'<br/> theta = (z - z1) / Sqr((x - x1) ^ 2 + (y - y1) ^ 2 + (z - z1) ^ 2)<br/> theta = Format(ArcCos(theta) - Pi / 2, "0.00")<br/> If Format(x - x1, "0.00") = 0 And Format(y - y1, "0.00") = 0 Then<br/> If z1 - z < 0 And Format(x - x1, "0.00") = 0# And Format(y - y1, "0.00") = 0# Then<br/> Point2(0) = Point2(0) + 2<br/> Point2(1) = Point2(1)<br/> Point2(2) = Point2(2)<br/> EnterEintity.Rotate3D ll.EndPoint, Point2, Pi<br/> End If<br/> <br/> ElseIf x - x1 <> 0 Or y - y1 <> 0 Then<br/> ll.Offset 10<br/> With obj_ModelSpace<br/> Set l1 = .Item(.Count - 1)<br/> Set l2 = .AddLine(ll.EndPoint, l1.EndPoint)<br/> l1.Delete<br/> End With<br/> If Format(z - z1, "0.00") = 0 Then<br/> EnterEintity.Rotate3D ll.EndPoint, l2.EndPoint, Pi / 2<br/> ElseIf z - z1 <> 0 Then<br/> EnterEintity.Rotate3D ll.EndPoint, l2.EndPoint, theta<br/> If z1 - z < 0 Then<br/> EnterEintity.Rotate3D ll.EndPoint, l2.EndPoint, Pi<br/> End If<br/> End If</p><p> l2.Delete<br/> End If</p><p><br/>End Function</p><p> </p><p>Function lll()<br/>' Dim Point1 As Variant, Point2 As Variant</p><p> If boo = False Then<br/> AutoCADConnect<br/> End If<br/> Dim ll As Object, ss As Object, ReturnEntity As Object<br/> For Each ll In obj_ModelSpace<br/> If ll.objectname = "AcDbLine" Then<br/> <br/> Set ss = obj_ModelSpace.AddCone(ll.EndPoint, 3, 10)<br/> Set ReturnEntity = Rotate3dEntity(ss, ll)<br/> End If<br/> Next ll<br/> obj_Doc.Regen (0)<br/>End Function<br/></p><p> </p> 不好意思没有看明白
页:
[1]