jkbanana 发表于 2007-3-2 13:16:00

关于求直线垂足方法的讨论

一、对于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)vbEmpty Then
   If LBound(returnPnt)
'***********************************************************


二、对于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

兰州人 发表于 2007-3-3 00:10:00

我特感兴趣,有时间好好讨论一下

wuyunpeng888 发表于 2009-6-22 21:38:00

比较费劲
可通过VLAX类来调用VLISP的vlax-curve-getClosestPointTo函数直接返回曲线上离指定点最近的点
这么简单的方法就不需要讨论了吧

monkey_w 发表于 2012-7-18 19:10:00

多谢分享,下来参考学习学习

njyulei 发表于 2012-7-25 17:25:00

有时间好好讨论一下

guohq 发表于 2012-8-14 12:26:00


最近点不一定是垂足!!

wuyunpeng888 发表于 2013-2-2 11:06:00

最近点不是垂足?你举个反例看看

wuyunpeng888 发表于 2013-4-16 21:28:00

指定点是你自己给的,直线不是无限长的,一个判断交点就知道是不是在延长线上了,直接就排除
页: [1]
查看完整版本: 关于求直线垂足方法的讨论