本帖最后由 作者 于 2007-5-14 13:11:06 编辑
一、对于2维空间的直线 给定2维空间的直线objline和点m, 可以用直线的Angle属性获得直线objline和x轴的夹角ang, 这样就可以计算出垂线和x轴的夹角为(ang + pi / 2), 过点m画出直线objline的一个垂直线段, 找出它于直线objline的交点即为所要的垂点. 参考代码如下: Option Explicit Public Sub Sample() Dim objline As AcadLine Dim lineObj As AcadLine Dim returnPnt As Variant Dim sp(0 To 2) As Double Dim ep(0 To 2) As Double Dim ang As Double Dim pt(0 To 2) As Double Const pi = 3.14159 '1. 一条线两端点坐标(x1,y1);(x2,y2) :设该直线为objline ' 如果只有两端点坐标(x1,y1);(x2,y2), 可用 addline 方法画出该直线 ThisDrawing.Utility.GetEntity objline, pt, "Select a line" ang = objline.Angle returnPnt = ThisDrawing.Utility.GetPoint(, "Enter a point: ") sp(0) = returnPnt(0) sp(1) = returnPnt(1) sp(2) = returnPnt(2) '2.做直线objline的一个垂直线段lineObj ep(0) = sp(0) + Cos(ang + pi / 2) ep(1) = sp(1) + Sin(ang + pi / 2) ep(2) = sp(2) Set lineObj = ThisDrawing.ModelSpace.AddLine(sp, ep) '3.找出直线objline和它的垂直线段lineObj的交点pt returnPnt = lineObj.IntersectWith(objline, acExtendNone) If VarType(returnPnt) <> vbEmpty Then If LBound(returnPnt) <= UBound(returnPnt) Then pt(0) = returnPnt(0) pt(1) = returnPnt(1) pt(2) = returnPnt(2) End If End If returnPnt = lineObj.IntersectWith(objline, acExtendBoth) If VarType(returnPnt) <> vbEmpty Then If LBound(returnPnt) <= UBound(returnPnt) Then pt(0) = returnPnt(0) pt(1) = returnPnt(1) pt(2) = returnPnt(2) End If End If lineObj.Delete '4.画垂线(作为检查) Dim obj1 As AcadLine Set obj1 = ThisDrawing.ModelSpace.AddLine(sp, pt) End Sub '*********************************************************** 二、对于3维空间的直线, 可以通过以下2种方法来找出其垂足. A. 通过坐标系转换 把3维空间(在此为WCS)内由给定直线和点所确定的平面转换到2维空间(在此为UCS) (所谓2维不过是z=0的一个特殊坐标系), 就可以用前面提供的代码找出其垂足, 然后再把它转换回到3维空间(WCS)即可. 步骤如下: 1. 先确定由给定直线objline (s, e)和点m所确定的2维空间(UCS), 使给定直线和点 在UCS中的z = 0 1) UCS的原点 假设直线的一个端点s为UCS的原点Origin 2) UCS 的坐标轴 假设UCS 的x , y, z轴的单位方向矢量分别设为 x', y', z' 给定直线假设为UCS 的x 轴, 其上一点坐标为 XAxisPoint=Origin+ x' 由给定直线的一个端点s指向给定点m的矢量设为v = p - s, 则UCS 的 z 轴的单位方向矢量 z' = x' × v / | x' × v | 由右手法则, y轴的单位方向矢量 y'= z' × x' , y 轴上一点坐标为 YAxisPoint=Origin+ y' 3) 产生UCS 利用Add方法产生UCS RetVal = object.Add(Origin, XAxisPoint, YAxisPoint, Name) object =ThisDrawing.UserCoordinateSystems 2. 求坐标系转化矩阵 ActiveX提供了获得坐标系转化矩阵的方法, 但它是从当前坐标系UCS转化到世界坐标系WCS的转化矩阵R(4x4). R = object.GetUCSMatrix() 在此问题中, 把3维空间(WCS)内由给定直线和点所确定的平面转换到2维空间(UCS)时要用它的逆转化矩阵V, V的前3x3项可以由R的转置获得, 即V(i,j)=R(j,i) (i,j =1,3) V的第4列的平移部分通过R的前3x4项计算获得, 即 V(i,4)=-R(j,i)*R(j,4) (i,j =1,3) V的第4行同R的第4行, 均为(0,0,0,1), V(4,i)=R(4,i) (i =1,4) 3. 坐标转换 坐标转换用TransformBy方法 object.TransformBy Matrix ( Matrix = R or V ) B. 建立数学模型求垂足 模型如下: 直线的两端点假设为s(s1,s2,s3), e(e1,e2,e3), 给定点m(m1,m2,m3) 直线端点s作为1维坐标轴的原点, 直线上任意点P(x,y,z)在该1维坐标的坐标设为t 直线的单位方向矢量设为 u = (e1-s1, e2-s2, e3-s3)/((e1-s1)^2+(e2-s2)^2+(e3-s3)^2)^0.5 = (u1,u2,u3) 直线上任意点P(x,y,z)的参数方程可表示为, P = s + t*u 垂线mp满足以下方程, mp·u = 0 解此方程得 t = u1(m1 - s1) + u2(m2 - s2) + u3(m3 - s3) 后, 垂足的坐标就可以算出 x=s1+u1*t y=s2+u2*t z=s3+u3*t |