Atook 发表于 2007-12-27 14:08:54

Curve.cls 的問題

我用Frank Oquendo的Curve.cls将方块沿折线均匀排列。
我遇到的问题是检索折线的斜率(一阶导数)。
dblParameter = objCurve。GetParameterAtDistance(I * dblSpacing)
dbl rotation = obj curve。GetFirstDerivative(dbl parameter)'
当我运行代码时,Curve.cls的get first derivative方法返回空。我认为错误发生在。EvalLispExpression行或其后的行。
有人给我出主意了吗?
**** Hidden Message *****

Jeff_M 发表于 2007-12-27 19:16:46

GetFirstDerivative以变量数组的形式返回方向向量,而不是双精度角......因此,如果你的数据旋转是双精度的,它将失败。如果这不是问题,你能更详细地定义你的“崩溃”吗?

Bryco 发表于 2007-12-28 09:19:14

当不需要Curve类时,尽量不要使用它。
通过一点错误控制,这应该可以让您到达那里
Option Explicit
Const pi As Double = 3.14159265358979
Sub DividePoly()
   
    Dim Ent As AcadEntity
    Dim oPline As AcadLWPolyline
    Dim cnt As Integer, CCnt As Integer
    Dim Dist As Double, Tan As Double
    Dim dLength As Double
    Dim div As Integer
    Dim unitL As Double
    Dim i As Integer, j As Integer, K As Integer
    Dim C1, C2, p
    Dim C(5) As Variant
    Dim dBulge As Double, Ang As Double
    Dim Total As Double
    Dim CoordCol As New Collection
    Dim Elev As Double
    Dim bBlock As Boolean
    Dim oBref As AcadBlockReference
    Dim sBlock As String
    Dim Util As AcadUtility
   
    Set Util = ThisDrawing.Utility
    'Set Ent = EntSel("Select a pline to divide:")
    Util.GetEntity Ent, p, "Select a pline to divide:"
    If TypeOf Ent Is AcadLWPolyline Then
      Set oPline = Ent
    Else
      MsgBox ("Must be a pline.")
      Exit Sub
    End If
   
    On Error Resume Next
    Dim keywordList As String
    keywordList = "Block"
    Util.InitializeUserInput 128, keywordList
    Dim Answer As String
    div = Util.GetInteger(vbCr & "Enter the number of segments or :   ")
    If Err Then
      If StrComp(Err.Description, "User input is a keyword", 1) = 0 Then
            Err.Clear
            Answer = ThisDrawing.Utility.GetInput
            If Answer = "Block" Then
                bBlock = True
                sBlock = Util.GetString(False, "Enter name of block to insert:")
                If sBlock = "" Then Exit Sub
                Dim oBlock As AcadBlock
                Set oBlock = ThisDrawing.Blocks(sBlock)
                If Err.Description = "Key not found" Then
                  Exit Sub
                Else
                  div = Util.GetInteger(vbCr & "Enter the number of segments :")
                  
                End If
            Else: Exit Sub
            End If
      End If
   End If
    On Error GoTo 0
   
   
   
    If Not div > 1 Then Exit Sub
    unitL = oPline.Length / div
    Elev = oPline.Elevation
    cnt = (UBound(oPline.Coordinates) - 1) / 2
    If oPline.Closed = True Then
      CCnt = cnt + 1
    Else
      CCnt = cnt
    End If
   
    For i = 0 To CCnt - 1
      C1 = oPline.Coordinate(i)
      If i = cnt Then
            C2 = oPline.Coordinate(0)
      Else
            C2 = oPline.Coordinate(i + 1)
      End If
      C(0) = C1: C(1) = C2
      dLength = segLength(C1, C2)
      C(5) = dLength
      dBulge = oPline.GetBulge(i)
      C(3) = dBulge
      If dBulge0 Then
         'converting bulge to angle in radiansang=Atn(dBulge) * 4
            Ang = Atn(dBulge) * 2
            dLength = Ang * dLength / Sin(Ang)
            C(4) = dLength
      End If
      Total = Total + dLength
      C(2) = Total
      CoordCol.Add C
    Next i
   
    dLength = 0
    K = 1
    For i = 1 To div - 1
      dLength = dLength + unitL
      For j = K To CCnt
            If CoordCol(j)(2) >= dLength Then
                Exit For
            End If
      Next j
      If j > 1 Then
            K = j - 1
            Dist = dLength - CoordCol(K)(2)
      Else
            K = j
            Dist = dLength
      End If
      dBulge = CoordCol(j)(3)
      If dBulge = 0 Then
            p = PtonLine(CoordCol(j)(0), CoordCol(j)(1), Dist, Tan)
      Else
            p = PtonArc(CoordCol(j), Dist, Tan)
      End If
   
      p(2) = Elev
      p = ThisDrawing.Utility.TranslateCoordinates(p, acOCS, acWorld, 0, oPline.Normal)
      If bBlock Then
            Set oBref = ThisDrawing.ModelSpace.InsertBlock(p, sBlock, 1, 1, 1, Tan)
            Dim Zero(2) As Double
            oBref.Normal = oPline.Normal
            oBref.InsertionPoint = p
      Else
            ThisDrawing.ModelSpace.AddPoint p
      End If
    Next i
End Sub
Function PtonLine(C1 As Variant, C2 As Variant, Dist As Double, Ang As Double) As Variant
    'X = X1 + distance / dLength * DX
    Dim X As Double, Y As Double
    Dim Dx As Double, dY As Double
    Dim dLength As Double
    Dim p(2) As Double
      
    X = C1(0): Y = C1(1)
    Dx = C2(0) - X: dY = C2(1) - Y
    dLength = Dist / Sqr(Dx * Dx + dY * dY)
    p(0) = X + (dLength * Dx)
    p(1) = Y + (dLength * dY)
    PtonLine = p
    Ang = AngFromX(C1, C2)
End Function
Function segLength(C1 As Variant, C2 As Variant) As Double
    Dim Dx As Double, dY As Double
    Dx = C2(0) - C1(0): dY = C2(1) - C1(1)
    segLength = Sqr(Dx * Dx + dY * dY)
End Function
Function ArcLength(C1 As Variant, C2 As Variant, SegmentLength As Double, dBulge As Double) As Double
    Dim Ang As Double
    Ang = Atn(dBulge) * 2 'converting bulge to angle in radiansang=Atn(dBulge) * 4
    ArcLength = Ang * SegmentLength / Sin(Ang)
End Function
Function PtonArc(C As Variant, Dist As Double, Tan As Double) As Variant
    'X = X1 + distance / dLength * DX
    Dim dBulge As Double
    Dim dLength As Double
    Dim p(2) As Double
    Dim Ang As Double, Ang2 As Double
    Dim Seg As Double
    Dim segAng As Double, AngToCen
    Dim Rad As Double
    Dim CenPt(1) As Double
    Dim C1, C2
    Dim PosNeg As Integer
      
    C1 = C(0): C2 = C(1)
    dBulge = C(3)
    Seg = C(5)
    Ang = Atn(dBulge) * 2 'converting bulge to angle in radians= Atn(dBulge) * 4
   
    Rad = Abs(Seg / (2 * Sin(Ang)))
    segAng = AngFromX(C1, C2)
   
    If dBulge > 0 Then
      PosNeg = 1
      AngToCen = segAng + ((0.5 * pi) - Ang)
    Else
      PosNeg = -1
      AngToCen = segAng - ((0.5 * pi) + Ang)
    End If
    CenPt(0) = C1(0) + Cos(AngToCen) * Rad
    CenPt(1) = C1(1) + Sin(AngToCen) * Rad
   
    If AngToCen0
    p(0) = CenPt(0) + (Cos(Ang) * Rad)
    p(1) = CenPt(1) + (Sin(Ang) * Rad)
    PtonArc = p
   
End Function
Public Function AngFromX(P1, P2) As Double
   
    'If Not PointCheck(p1, p2) Then Exit Function
    Dim Dx As Double, dY As Double
    Dim dAng As Double
    dY = P2(1) - P1(1): Dx = P2(0) - P1(0)
    If Rd(dY, 0) Then'Line is horizontal
      If Rd(Dx, 0) Then Exit Function
      If Dx > 0 Then
            dAng = 0
      Else
            dAng = pi '180
      End If
    ElseIf Rd(Dx, 0) Then'Line is vertical
      If dY > 0 Then
            dAng = 0.5 * pi '90
      Else
            dAng = 1.5 * pi '270
      End If
    Else
      dAng = Atn(dY / Dx)
      If dAng 270
            If Dx 270
                dAng = pi + dAng '90->180
            Else '270->360
                dAng = 2 * pi + dAng
            End If
      Else
            If Dx 270
                dAng = pi + dAng
            End If
      End If
    End If
    AngFromX = dAng
End Function
Function Rd(num1 As Variant, num2 As Variant) As Boolean
    If Abs(num1 - num2) < 0.00000001 Then Rd = True
End Function

Bryco 发表于 2007-12-28 09:22:19

在测试时,我发现acad divide命令在一个时髦的UCS(2008版)中是不正确的。我已经添加了一个图来显示它,要插入的块是“b”。我的代码也是这样做的,直到我在0,0,0处添加块,更改法线以匹配样条线,然后将其插入点更改为正确的位置

Atook 发表于 2007-12-28 11:46:07

杰夫,这正是问题所在,谢谢你的提示。
Bryco,我一直在寻找避免Curve.cls,但不太确定该怎么做。感谢您的帮助!这个周末我可能会仔细看看它。
页: [1]
查看完整版本: Curve.cls 的問題