Тема: Вычисление площади

Как написать макрос, который бы вызывал окно Boundary, вычислял площадь полученного объекта и показывал ее в MsgBox.

Re: Вычисление площади

(defun arr ()
    (bpoly (getpoint))
    (setq vlaobj (vlax-ename->vla-object (entlast))); Transforms entity to VLA-object
    (if (vlax-property-available-p vlaobj 'Area) ;if an object has a specified property
        (alert(rtos(vlax-get-property vlaobj 'Area)))     
    );if
);defun 

Re: Вычисление площади

а как, если можно, это сделать средствами VBA?

Re: Вычисление площади

Если этот объект Region или Polyline - то достаточно его выбрать (естественно програмно на VBA) и в свойствах этого объекта есть площадь: SelectObject.Area

Re: Вычисление площади

3dcad
Объект может быть образован линиями или многоугольниками.
С помощью boundary хотелось бы получить замкнутую полилинию. Потом получить ее площадь и удалить полилинию.
cadhelp
Макрос будет на кнопке.
Как тогда можно использовать приведеный Вами код.

Re: Вычисление площади

Mitya, зря Вы привязались к Boundary.
Воспользуйтесь командой REGION (есть пример на VBA) для создания из линий - региона. Далее, см. выше указанное.
А, что значит "...объект может быть образован многоугольниками" - не понял.

Re: Вычисление площади

3dcad, sorry неправильно написал.
объект может быть образован линиями или может быть многоугольником(Polygon, Rectangle).
Boundary нужен для того что бы можно было отметить одну точку внутри объекта, а не отмечать каждую линию.

Re: Вычисление площади

Попробую еще раз.
Вот пример на VBA, который создает из дуг и линий регион.
А недостаток у Boundary - огромный в том, что если все границы не попадают в текущее окно Acada, то Boundary не определяется.
Sub Example_AddRegion()
    ' This example creates a region from an arc and a line.
    Dim curves(0 To 1) As AcadEntity
    ' Define the arc
    Dim centerPoint(0 To 2) As Double
    Dim radius As Double
    Dim startAngle As Double
    Dim endAngle As Double
    centerPoint(0) = 5#: centerPoint(1) = 3#: centerPoint(2) = 0#
    radius = 2#
    startAngle = 0
    endAngle = 3.141592
    Set curves(0) = ThisDrawing.ModelSpace.AddArc(centerPoint, radius, startAngle, endAngle)
    ' Define the line
    Set curves(1) = ThisDrawing.ModelSpace.AddLine(curves(0).startPoint, curves(0).endPoint)
    ' Create the region
    Dim regionObj As Variant
    regionObj = ThisDrawing.ModelSpace.AddRegion(curves)
    regionObj(0).Color = acRed
'Теперь берите в свойствах площадь и считайте, что Вам надо.
''regionObj(0).Area
    ZoomAll
End Sub

Re: Вычисление площади

Более того, из опыта проектирования и программирования могу сказать, что намного удобнее сначала создавать (обводить) требуемый контур, а затем с ним работать.

Re: Вычисление площади

Дело в том, что макрос должен работать в уже готовых чертежах.
Программно создавать регион, в моем случае нет смысла.  Может, кто-то знает, как обрисовать замкнутый контур полилинией с помощью vba?

Re: Вычисление площади

Добавлю...
Что бы можно было указать одну точку внутри замкнутого контура.

Re: Вычисление площади

привет друзья по несчастью
У меня тот же вопрос: "Что бы можно было указать одну точку внутри замкнутого контура."
вы случайно в нём ещё не розабрались. Если разобрались то посоветуйте чего нибудь.

Re: Вычисление площади

Собственно вот выжимка из кода, удовлетворяющая поставленному вопросу.

Sub AreaCalc()
Dim sset As AcadSelectionSet
Dim Obj As Object
Dim Ar As Double
Dim MS As AcadModelSpace
Dim Pnt() As Double
Dim Coord As Variant
On Error Resume Next
Set MS = ThisDrawing.ModelSpace
Set sset = ThisDrawing.SelectionSets.Add("SS")
    Pnt = ThisDrawing.Utility.GetPoint(, "Укажите точку внутри контура:")
    Coord = Replace(Pnt(0), ",", ".") & "," & Replace(Pnt(1), ",", ".")
        ThisDrawing.SendCommand "-boundary" & vbCr
        ThisDrawing.SendCommand Coord & vbCr & vbCr
        sset.Select acSelectionSetLast
        Set Obj = sset(0)
        Ar = Obj.Area
        Obj.Delete
        MsgBox Ar
End Sub

Полностью макрос написан для автоматической простановки на чертеже номера и площади помещений. Если кому нужна полная версия, в которой в указанные точки вставляется блок с номером и площадью, могу ниже запостить.

Re: Вычисление площади

> Сидор Лютый
Дык в чем же дело, низко просим
А и кому польза будет
~'J'~

Re: Вычисление площади

> Mitya
Не уверен что сие писано в хорошей манере,
но вроде работает
Хотелось бы советов по поводу стиля, за 2 недели
трудно объять

Option Explicit
Public Function Get_Contour(ByVal intPoint As Variant) As AcadLWPolyline
Dim quant As Long
Dim strVal As String
Dim boundPoly As AcadLWPolyline
With ThisDrawing
quant = IIf(.ActiveSpace = acModelSpace, .ModelSpace.Count, _
.PaperSpace.Count)
strVal = CStr(Val(intPoint(0))) & "," & CStr(Val(intPoint(1)))
.SendCommand "_-boundary" & vbCr & strVal & vbCr & vbCr
With IIf(.ActiveSpace = acModelSpace, .ModelSpace, .PaperSpace)
If .Count > quant Then
Set boundPoly = .Item(.Count - 1)
Set Get_Contour = boundPoly
End If
End With
End With
End Function
Public Sub Test_Get_Contour()
Dim internPnt As Variant
Dim boundPoly As AcadLWPolyline
Dim planPnt(0 To 1) As Variant
On Error GoTo 0
internPnt = ThisDrawing.Utility.GetPoint(, " >> Select a point inside >> ")
planPnt(0) = internPnt(0): planPnt(1) = internPnt(1)
Set boundPoly = Get_Contour(planPnt)
MsgBox "Area is: " & vbCr & vbCr & CStr(boundPoly.Area), , "Contour Area"
boundPoly.Delete
End Sub

~'J'~

Re: Вычисление площади

А это обещанный макрос:

Sub AreaCalc()
'Вычисление и простановка площади помещений
Dim sset As AcadSelectionSet
Dim Obj As Object
Dim Ar As Double
Dim MS As AcadModelSpace
Dim Bltmp As Object
Dim Pnt() As Double
Dim nnew As Integer, n As Integer
Dim ArAtr As Variant
Dim Coord As Variant
On Error Resume Next
Set MS = ThisDrawing.ModelSpace
Call SSCheck("SS")
Set sset = ThisDrawing.SelectionSets("SS")
n = 1
nnew = ThisDrawing.Utility.GetInteger("Начальный номер <1>:")
If nnew <> Empty Then
n = nnew
End If
Do
    Erase Pnt
    Pnt = ThisDrawing.Utility.GetPoint(, "Укажите точку в области:")
    If Pnt(0) = 0 And Pnt(1) = 0 And Pnt(2) = 0 Then
        Exit Sub
    Else
        Coord = Replace(Pnt(0), ",", ".") & "," & Replace(Pnt(1), ",", ".")
        ThisDrawing.SendCommand "-boundary" & vbCr & Coord & vbCr & vbCr
        sset.Select acSelectionSetLast
        Set Obj = sset(0)
        Ar = Round(Obj.Area, 1)
        Obj.Delete
        Set Bltmp = MS.InsertBlock(Pnt, "BLOCKNAME", 1#, 1#, 1#, 0)
        If Bltmp.Name = "" Then
            MsgBox "Блок BLOCKNAME не найден"
            Exit Sub
        Else
        ArAtr = Bltmp.GetAttributes
        ArAtr(0).TextString = n
        ArAtr(1).TextString = FormatNumber(Ar, 1#, -1, 0, 0)
        End If
    End If
    n = n + 1
Loop Until Pnt(0) = 0 And Pnt(1) = 0 And Pnt(2) = 0
End Sub
'---------------------------------------------------------------------------
'Функция предназначена для проверки наличия указанного SelSet-а в чертеже
'Если такого SelectionSet-а нет, он создается, если есть, - вычищается.
Function SSCheck(SSNM As String)
    Dim SelSet As AcadSelectionSet
    Dim CheckFlag As Boolean
    CheckFlag = False
        For Each SelSet In ThisDrawing.SelectionSets
            If SelSet.Name = SSNM Then
            CheckFlag = True
            End If
        Next SelSet
        If CheckFlag = False Then
            ThisDrawing.SelectionSets.Add (SSNM)
        Else
            ThisDrawing.SelectionSets(SSNM).Clear
        End If
End Function

Некоторые особенности для тех кто будет использовать макрос в работе:
1) Вставка блока работает только в ModelSpace. При необходимости можно будет переделать для работы и в PaperSpase тоже.
2) В чертеже уже должен присутствовать блок c именем BLOCKNAME и, как минимум, двумя видимыми атрибутами, первый из которых будет принимать значение номера помещения, второй - площади помещения.
3) Логика цикла такова, что перед каждым запросом точки, предыдущие координаты обнуляются и если их не сделать отличными от нуля (нажать при запросе ESC или Enter, например) то макрос завершит работу. Поэтому, если при указании точки вы попадете мышкой в ноль по всем осям (при особом желании можно))), то макрос так же завершается)

Re: Вычисление площади

> Сидор Лютый
Работает как часы. А как сделать чтобы при пустом
вводе начального номера помещения принималось
значение default для n?
~'J'~

Re: Вычисление площади

> Олег(jr.)
Ничего. Просто нажать Enter на запрос номера. Или вообще закоментировать чаcть кода:

nnew = ThisDrawing.Utility.GetInteger("Начальный номер <1>:")
If nnew <> Empty Then
n = nnew
End If

Тогда запроса вообще не будет и после каждого вызова макроса нумерация будет начинаться с единички.

Re: Вычисление площади

> Сидор Лютый
Спасибо, теперь прояснилось :)
~'J'~