Тема: Кто-нибудь вычислял длину-ширину-высоту солида в форме параллелипипеда?

Кто-нибудь вычислял длину-ширину-высоту солида в форме параллелипипеда?
В свойствах ведь есть только объем.

Re: Кто-нибудь вычислял длину-ширину-высоту солида в форме параллелипипеда?

https://www.caduser.ru/forum/topic36136.html

Re: Кто-нибудь вычислял длину-ширину-высоту солида в форме параллелипипеда?

Спасибо,
но хотелось бы получить эти значения для использования в программе, а не наблюдать их в панели свойств

Re: Кто-нибудь вычислял длину-ширину-высоту солида в форме параллелипипеда?

Попробуй через метод GetBoundingBox:

Dim ss As AcadSelectionSet
    On Error Resume Next
    ThisDrawing.SelectionSets("TestSet").Delete
    Set ss = ThisDrawing.SelectionSets.Add("TestSet")
    ss.SelectOnScreen
    Dim v3DSolid As Acad3DSolid
    Dim minExt As Variant
    Dim maxExt As Variant
    Set v3DSolid = ss.Item(0)
    ' Return the bounding box for the line and return the minimum
    ' and maximum extents of the box in the minExt and maxExt variables.
    v3DSolid.GetBoundingBox minExt, maxExt
    ' Print the min and max extents
    MsgBox "The extents of the bounding box for the 3DSolid are:" & vbCrLf _
         & "Min Extent: " & minExt(0) & "," & minExt(1) & "," & minExt(2) _
         & vbCrLf & "Max Extent: " & maxExt(0) & "," & maxExt(1) & "," & maxExt(2), vbInformation, "GetBoundingBox Example"

Re: Кто-нибудь вычислял длину-ширину-высоту солида в форме параллелипипеда?

Можно попробовать через запись/чтение .SAT файла
Должно работать только для боксов, неразвернутых
в пространстве

Option Explicit
' request reference to Microsoft Scripting Runtime
' by Fatty T.O.H. () 2007 * all rights removed
Sub GetBoxSize()
     Dim ss As AcadSelectionSet
     Dim sat As String
     With ThisDrawing.SelectionSets
          While .Count > 0
               .Item(0).Delete
          Wend
          Set ss = .Add("$BOX$")
          ss.SelectOnScreen
          sat = ThisDrawing.Path & "\Box"
          ThisDrawing.Export sat, "sat", ss
          ss.Delete
     End With
     Dim col As Collection
     Set col = New Collection
     Set col = ReadPoints(ThisDrawing.Path & "\Box.sat")
     Dim pt As Variant, i As Integer
     Dim col1 As New Collection
     Dim col2 As New Collection
     Dim col3 As New Collection
     Dim col4 As New Collection
     Dim f As Variant
     f = col.Item(1)
     For Each pt In col
          If pt(2) = f(2) Then
               col1.Add pt
          Else
               col2.Add pt
          End If
     Next
     f = col1.Item(1)
     For Each pt In col2
          If pt(0) = f(0) Then
               col3.Add pt
          End If
     Next
     For Each pt In col2
          If pt(1) = f(1) Then
               col4.Add pt
          End If
     Next
     MsgBox "Box size is:" & vbCr & _
            "Length: " & vbTab & Get_Distance(col4.Item(1), col4.Item(2)) & vbCr & _
            "Width: " & vbTab & Get_Distance(col3.Item(1), col3.Item(2)) & vbCr & _
            "Height: " & vbTab & col1.Item(1)(2) - col2.Item(1)(2)
End Sub
Public Function ReadPoints(fname As String) As Collection
     Dim fn, sr As String, fs, ForReading
     Dim col As New Collection
     Dim tmp(1) As String
     ForReading = 1
     Set fs = CreateObject("Scripting.FileSystemObject")
     Set fn = fs.OpenTextFile(fname, ForReading, False)     ''<--full path
     Do While Not fn.AtEndOfStream
          sr = fn.Read(0)
          sr = fn.ReadLine
          If sr Like "point*" Then
               sr = Trim(Mid$(sr, 17, Len(sr) - 18))
               Dim vr As Variant
               vr = ParsePoint(sr)
               col.Add vr
          End If
     Loop
     fn.Close
     Set fn = Nothing
     Set fs = Nothing
     Set ReadPoints = col
End Function
Private Function ParsePoint(s As String) As Variant
     Dim x As Variant
     x = Split(s, Chr(32))
     Dim v(2) As Double
     Dim i As Integer
     For i = 0 To 2
          v(i) = CDbl(x(i))
     Next
     ParsePoint = v
End Function
Public Function Get_Distance(fPoint As Variant, sPoint As Variant) As Double
     Dim x1 As Double, x2 As Double
     Dim y1 As Double, y2 As Double
     Dim z1 As Double, z2 As Double
     Dim cDist As Double
     x1 = fPoint(0): y1 = fPoint(1): z1 = fPoint(2)
     x2 = sPoint(0): y2 = sPoint(1): z2 = sPoint(2)
     cDist = Sqr(((x2 - x1) ^ 2) + ((y2 - y1) ^ 2) + ((z2 - z1) ^ 2))
     Get_Distance = cDist
End Function

~'J'~

Re: Кто-нибудь вычислял длину-ширину-высоту солида в форме параллелипипеда?

Прошу прощения вставил старый черновик,
используйте лучше этот вариант
Должен работать при любой ориентации бокса

Option Explicit
' request reference to Microsoft Scripting Runtime
' by Fatty T.O.H. () 2008 * all rights removed
Sub GetBoxSize()
     Dim ss As AcadSelectionSet
     Dim sat As String
     With ThisDrawing.SelectionSets
          While .Count > 0
               .Item(0).Delete
          Wend
          Set ss = .Add("$BOX$")
          ss.SelectOnScreen
          sat = ThisDrawing.Path & "\Box"
          ThisDrawing.Export sat, "sat", ss
          ss.Delete
     End With
     Dim col As Collection
     Set col = New Collection
     Set col = ReadPoints(ThisDrawing.Path & "\Box.sat")
     MsgBox "Box size is:" & vbCr & _
            "Length: " & vbTab & Get_Distance(col.Item(1), col.Item(6)) & vbCr & _
            "Width: " & vbTab & Get_Distance(col.Item(1), col.Item(2)) & vbCr & _
            "Height: " & vbTab & Get_Distance(col.Item(2), col.Item(3))
End Sub
Public Function ReadPoints(fname As String) As Collection
     Dim fn, sr As String, fs, ForReading
     Dim col As New Collection
     Dim tmp(1) As String
     ForReading = 1
     Set fs = CreateObject("Scripting.FileSystemObject")
     Set fn = fs.OpenTextFile(fname, ForReading, False)     ''<--full path
     Do While Not fn.AtEndOfStream
          sr = fn.Read(0)
          sr = fn.ReadLine
          If sr Like "point*" Then
               sr = Trim(Mid$(sr, 17, Len(sr) - 18))
               Dim vr As Variant
               vr = ParsePoint(sr)
               col.Add vr
          End If
     Loop
     fn.Close
     Set fn = Nothing
     Set fs = Nothing
     Set ReadPoints = col
End Function
Private Function ParsePoint(s As String) As Variant
     Dim x As Variant
     x = Split(s, Chr(32))
     Dim v(2) As Double
     Dim i As Integer
     For i = 0 To 2
          v(i) = CDbl(x(i))
     Next
     ParsePoint = v
End Function
Public Function Get_Distance(fPoint As Variant, sPoint As Variant) As Double
     Dim x1 As Double, x2 As Double
     Dim y1 As Double, y2 As Double
     Dim z1 As Double, z2 As Double
     Dim cDist As Double
     x1 = fPoint(0): y1 = fPoint(1): z1 = fPoint(2)
     x2 = sPoint(0): y2 = sPoint(1): z2 = sPoint(2)
     cDist = Sqr(((x2 - x1) ^ 2) + ((y2 - y1) ^ 2) + ((z2 - z1) ^ 2))
     Get_Distance = cDist
End Function

~'J'~

Re: Кто-нибудь вычислял длину-ширину-высоту солида в форме параллелипипеда?

LeonidSN, спасибо, к сожалению встречаются солиды повернутые в пространстве, поэтому  GetBoundingBox не работает.
Fatty, спасибо, решение просто супер!!!
У меня взял почти все, кроме солидов типа экструзии, и еще какого-то прямоугольного солида (не знаю как он сделан, не я делал).
Мне пришлось заменить в функции ParsePoint строчку

v(i) = CDbl(x(i))

на

v(i) = CDbl(Replace(x(i), ".", ","))

иначе выдавалась ошибка при дробных координатах.
Еще раз спасибо.

Re: Кто-нибудь вычислял длину-ширину-высоту солида в форме параллелипипеда?

> Anatoly
Хм, надо бы переписать эту функции под все
случаи (я имею ввиду чтоб читала и точку и запятую)
Пока мыслей насчет этого никаких нет...
почти сплю уже... :)
Может у Leonid'a есть идеи?
~'J'~

Re: Кто-нибудь вычислял длину-ширину-высоту солида в форме параллелипипеда?

Еще вопрос:
в 2007-м для объекта Acad3DSolid есть свойство SolidType, а в 2005-м нет.
Как-то можно узнать тип солида в автокаде младших версий?

Re: Кто-нибудь вычислял длину-ширину-высоту солида в форме параллелипипеда?

> Anatoly
Я не знаю...
~'J'~

Re: Кто-нибудь вычислял длину-ширину-высоту солида в форме параллелипипеда?

> Anatoly

Fatty, спасибо, решение просто супер!!!

Присоединяюсь, красивое решение.

> Fatty
Может у Leonid'a есть идеи?
Идей особых нет, но может быть попробовать вот так:

Sub FunctionTest()
    Dim strSource As String
    Dim MyNumber As Double
    strSource = "1347,01254987025"
    If IsNumeric(strSource) Then
        MyNumber = StringToNumber(strSource)
        MsgBox MyNumber
    Else
        MsgBox "This string does not contain number"
    End If
End Sub
Private Function StringToNumber(strSource As String) As Double
  Dim arrByte() As Byte
  Dim i As Integer
  arrByte = strSource
  For i = 0 To UBound(arrByte)
    If (arrByte(i) = 44) Then
        If (arrByte(i + 2) > 47 And arrByte(i + 2) < 58) Then
           arrByte(i) = 46
           Exit For
        Else
            Exit Function
        End If
    End If
  Next
  strSource = arrByte
  StringToNumber = CDbl(strSource)
End Function

Re: Кто-нибудь вычислял длину-ширину-высоту солида в форме параллелипипеда?

> LeonidSN
Как-то не пойму как собрать все в одно,
по-отдельности твоя функция StringToNumber
работает прекрасно, а вставить в общую программу
не получается, в чем дело не пойму???
~'J'~

Re: Кто-нибудь вычислял длину-ширину-высоту солида в форме параллелипипеда?

> Fatty
Я тоже не пойму. Ведь дал пример вызова функции...
Вообще-то, я городил все это под себя, мне надо было обработать набор примитивов типа AcadText и пересчитать числа, если этот AcadText содержит число.

Re: Кто-нибудь вычислял длину-ширину-высоту солида в форме параллелипипеда?

> LeonidSN
А, кому надо пусть голову ломает :)
Забудем об этом
Regards,
~'J'~