'BZPIP.Angle обязательно так назвать скрипт, он вызывается в следующем скрипте
'Внутренняя функция, возвращающая угол наклона линии в радианах
'заданной координатами (x1, y1) - (x2, y2) - 4 параметра
'или двумя точками p1-p2 - 2 параметра
'или линией line - 1 параметр
if (Self.Count=4) then
p1= Self.Get(0)@Self.Get(1)
p2= Self.Get(2)@Self.Get(3)
elseif (Self.Count=2) then
p1= Self.Get(0)
p2= Self.Get(1)
elseif (Self.Count=1) then
p1= Self.Get(0).ReturnStart
p2= Self.Get(0).ReturnEnd
else Return 0
end
pi= Number.GetPi d= p2-p1 angle= (d.GetY/d.GetX).atan
if (d.GetX<0) then
angle= angle+pi
elseif (d.GetY<0) then
angle= angle+pi+pi
end
Return angle '.AsDegrees
следующий скрипт повесить на панель инструментов вида
условия: активная тема линейная и включена на редактирование
в теме выделен один отрезок линии (линия между 2-мя точками
выбрать этот инструмент
щелкнуть мышкой ВОЗЛЕ точки отрезка с той стороны, в какую сторону провести перпендикуляр
В линейной теме появится перпендикуляр заданной длины
если нарисовался в другую сторону, этот перпенд удалить и щелкнуть с другой сороны.
подработав этот скрипт можно решить и вашу ситуацию
пока
'bzpip.PerpendicularForLine
'построение перпендикуляра к линии к точке в конце линии
theView = av.getactivedoc
theTheme=theView.GetActiveThemes.Get(0)
if (theTheme.GetFtab.IsEditable.not) then
MsgBox.Error("Тема"++theTheme.GetSrcName.GetName++"не включена на редактирование",
"Перпендикуляр")
exit
end
theFtab=theTheme.GetFtab
theClass=theFtab.GetShapeClass.GetClassName
if ( theClass<>"PolyLine") then
MsgBox.Error("Тема<"++theTheme.GetSrcName.GetName++"> не линейная",
"Перпендикуляр")
exit
end
aDisp=theView.GetDisplay
aSel=theFtab.GetSelection
pi=180.AsRadians
z=vector.Make(0,0,1)
aCount=aSel.Count
if (aCount=0) then
MsgBox.Error("Нет выделенных объектов. Обработка не проводится",
"Перпендикуляр")
exit
end
if (aCount>1) then
MsgBox.Error("Выделено более одного объекта. Обработка не проводится",
"Перпендикуляр")
exit
end
aPoint=theView.GetDisplay.ReturnUserPoint
'rectLine=rect.Make(312993@626515,10@40)
PointList={} PointNew={}
aPosition=aSel.GetNextSet(-1)
theShape=theFtab.FindField("shape")
anObj=theFtab.ReturnValue(theShape,aPosition)
LineList=anObj.explode
dist=1000
for each rec in LineList
for each rec1 in rec.AsList
for each rec2 in 0..(rec1.AsList.Count-2)
aLine=Line.Make(rec1.Get(rec2),rec1.Get(rec2+1))
dTemp=aPoint.Distance(aLine)
if (dist>dTemp) then dist=dTemp end
end
end
end
for each rec in LineList
for each rec1 in rec.AsList
for each rec2 in 0..(rec1.AsList.Count-2)
aLine=Line.Make(rec1.Get(rec2),rec1.Get(rec2+1))
dTemp=aPoint.Distance(aLine)
if (dist=dTemp) then
MyLine=aLine
end
end
end
end
sPoint=MyLine.returnStart
ePoint=MyLine.returnEnd
dist1=sPoint.Distance(aPoint)
dist2=ePoint.Distance(aPoint)
if (dist1<dist2) then
MyPoint=sPoint st=1
else
MyPoint=ePoint st=2
end
ugMyLine=av.Run("BZPIP.Angle",{0@0,ePoint-sPoint}).AsDegrees
ugMyPoint=av.Run("BZPIP.Angle",{0@0,aPoint-sPoint}).AsDegrees
if (st=1) then
aVec=vector.Make(sPoint.GetX-ePoint.GetX,sPoint.GetY-ePoint.GetY,0)
if (ugMyLine>ugMyPoint) then
aVec90=aVec.Rotate(90,z)
else
aVec90=aVec.Rotate(270,z)
end
elseif (st=2) then
aVec=vector.Make(ePoint.GetX-sPoint.GetX,ePoint.GetY-sPoint.GetY,0)
if (ugMyLine<ugMyPoint) then
aVec90=aVec.Rotate(90,z)
else
aVec90=aVec.Rotate(270,z)
end
end
intensityValue=msgbox.Input("Введите длину перпендикуляра","Построение перпендикуляра","100")
if (intensityValue=Nil) then exit end
intensityValue=intensityValue.Translate(",",".").AsNumber
aVec90.SetIntensity (intensityValue)
theFtab.BeginTransaction
new=theFtab.addrecord
if (st=1) then
theFtab.SetValue(theShape,new,PolyLine.Make({{sPoint,(aVec90.AsPoint+sPoint)}}))
else
theFtab.SetValue(theShape,new,PolyLine.Make({{ePoint,(aVec90.AsPoint+ePoint)}}))
end
theFtab.EndTransaction
theTheme.invalidate(true)
theView.Invalidate