캐드에서 VBA를 이용한 세점 현수선 그리기(Drawing 3 points catenary in Autocad using VBA)

캐드에서 VBA를 이용한 세점 현수선 그리기(Drawing 3 points catenary in Autocad using VBA)

오토캐드에서 VBA로 세 점 현수선 그리는 법입니다.
먼저 아래의 코드를 긁으시고
Private Function COSH(p As Double)
    COSH = (Exp(p) + Exp(-p)) / 2
End Function

Private Function SINH(p As Double)
    SINH = (Exp(p) - Exp(-p)) / 2
End Function

Private Function ASINH(p As Double)
    ASINH = Log(p + Sqr(p * p + 1))
End Function

Sub catenary()

Dim Pnt1, Pnt2, Pnt3 As Variant  '3points for catenary
    Pnt1 = ThisDrawing.Utility.GetPoint(, "1st Point")
    Pnt2 = ThisDrawing.Utility.GetPoint(, "2nd Point")
    Pnt3 = ThisDrawing.Utility.GetPoint(, "3rd Point")

    Dim a, b, c As Double
    Dim M11, M12, M13, M21, M22, M23, M31, M32, M33 As Double 
    Dim x1, x2, x3, y1, y2, y3, plusx, plusy As Double 

    plusx = Pnt1(0) + Pnt3(0)
    plusy = Pnt1(1) + Pnt3(1)
    
    x1 = Pnt1(0) + plusx: x2 = Pnt2(0) + plusx: x3 = Pnt3(0) + plusx
    y1 = Pnt1(1) + plusy: y2 = Pnt2(1) + plusy: y3 = Pnt3(1) + plusy

    M11 = 1 / (x1 ^ 2 - x1 * x2 - x1 * x3 + x2 * x3)
    M12 = 1 / (x2 ^ 2 - x1 * x2 + x1 * x3 - x2 * x3)
    M13 = 1 / (x3 ^ 2 + x1 * x2 - x1 * x3 - x2 * x3)

    M21 = -(x2 + x3) / (x1 ^ 2 - x1 * x2 - x1 * x3 + x2 * x3)
    M22 = -(x1 + x3) / (x2 ^ 2 - x1 * x2 + x1 * x3 - x2 * x3)
    M23 = -(x1 + x2) / (x3 ^ 2 + x1 * x2 - x1 * x3 - x2 * x3)
    
    M31 = -(x1 * x3) * (x2 ^ 2 - x2 * x3) / (x1 ^ 2 - x1 * x3) / (x2 ^ 2 - x1 * x2 + x1 * x3 - x2 * x3)
    M32 = (x1 * x3) / (x2 ^ 2 - x1 * x2 + x1 * x3 - x2 * x3)
    M33 = -(x1 * x3) * (x2 ^ 2 - x1 * x2) / (x3 ^ 2 - x1 * x3) / (x2 ^ 2 - x1 * x2 + x1 * x3 - x2 * x3)
    
    a = M11 * y1 + M12 * y2 + M13 * y3
    b = M21 * y1 + M22 * y2 + M23 * y3
    c = M31 * y1 + M32 * y2 + M33 * y3

    Dim f1, f2, f As Double

    f1 = (y3 - y1) / (x3 - x1) * ((x1 + x3) / 2 - x1) + y1
    f2 = a * ((x1 + x3) / 2) ^ 2 + b * (x1 + x3) / 2 + c
    f = f1 - f2
    
    Dim forH As Double
    Dim w As Double

    w = InputBox("Uniform load (N/mm)")
    forH = w * (x3 - x1) ^ 2 / 8 / f

    x1 = Pnt1(0) - Pnt1(0): x2 = Pnt2(0) - Pnt1(0): x3 = Pnt3(0) - Pnt1(0)
    y1 = Pnt1(1) - Pnt1(1): y2 = Pnt2(1) - Pnt1(1): y3 = Pnt3(1) - Pnt1(1)

    Dim aa, bb, cc As Double
    Dim L, hh As Double 

        L = x3 - x1
        hh = y3 - y1

    Dim H As Double
    H = forH

    Dim cnt As Double
    cnt = 1

    Dim aa_d, bb_d As Double
    Dim fx, fx2, fx_d As Double

    Do
        aa = H / w
        bb = L / 2 - aa * ASINH(hh / (2 * aa * SINH(L / 2 / aa)))
        fx = aa * (COSH((x2 - bb) / aa) - COSH(bb / aa)) - y2
        aa_d = (H + 0.000001) / w
        bb_d = L / 2 - aa_d * ASINH(hh / (2 * aa_d * SINH(L / 2 / aa_d)))
        fx2 = aa_d * (COSH((x2 - bb_d) / aa_d) - COSH(bb_d / aa_d)) - y2
        fx_d = (fx2 - fx) / 0.000001
        H = H - fx / fx_d

        If cnt > 100 Then Exit Do
        cnt = cnt + 1

    Loop Until Abs(fx) < 0.000001

MsgBox "Horizontal Force : " & H 

        Dim Ti, Tj As Double
        Dim Ti_sita, Tj_sita As Double

        Ti_sita = Atn(SINH((x1 - bb) / aa))
        Tj_sita = Atn(SINH((x3 - bb) / aa))

        Ti = H / Cos(Ti_sita)
        Tj = H / Cos(Tj_sita)

MsgBox "Start Tension (N) : " & Ti 'start point tension
MsgBox "End Tension (N) : " & Tj 'end point tension

    Dim n As Integer 
    n = InputBox("What is the number of divided catenary?")

    Dim interval As Double
        interval = (Pnt3(0) - Pnt1(0)) / n

    Dim polyPnt() As Double

    ReDim polyPnt(2 * n + 1) As Double

    Dim i As Integer

    For i = 0 To n
        polyPnt(i * 2) = x1 + interval * i
        polyPnt(i * 2 + 1) = aa * (COSH((polyPnt(i * 2) - bb) / aa) - COSH(bb / aa))
    Next i

    Dim Opnt1(2) As Double
    Dim Opnt2(2) As Double
        Opnt1(0) = 0: Opnt1(1) = 0: Opnt1(2) = 0
        Opnt2(0) = Pnt1(0): Opnt2(1) = Pnt1(1): Opnt2(2) = 0

      Dim polyObj As AcadLWPolyline

        Set polyObj = ThisDrawing.ModelSpace.AddLightWeightPolyline(polyPnt)
        polyObj.Move Opnt1, Opnt2
        Set text_Ti = ThisDrawing.ModelSpace.AddText("Ti=" & Round(Ti, 3), Pnt1, 30)
        Set text_Tj = ThisDrawing.ModelSpace.AddText("Tj=" & Round(Tj, 3), Pnt3, 30)
End Sub
Tools(도구)의 Macro - Visual Basic Editor 로 들어갑니다. Modules에서 오른쪽 마우스 누르고 Insert - Module 를 선택합니다. 빈 칸에 코드를 붙여넣습니다.

 

이제 실행만 시키면 됩니다. F5 를 누르거나 Visual Basic Editor의 초록색 화살표를 누르면 실행이 됩니다. 캐드창에서 아무 곳이나 세점을 찍으면 아래와 같이 현수선의 단위당 중량을 치면 차례대로 계산된 수평력, 시점장력, 종점장력이 보여집니다.
다음으로 분할 개수를 적으면 세점에 대한 현수선이 그려집니다.
 
* VBA(Visual Basic for Aplication)를 지원하는 캐드버전이어야 합니다.

댓글

Designed by JB FACTORY