1478425559.webp

github 源码分享 https://github.com/hongwenjun/corelvba

物件排列拼版简单代码 和 自动添加裁切线功能 是两个独立的功能,可能各自单独使用。

自动裁切线演示视频

cut_lines.gif

  • 记事本输入参数 50 50 5 5 3 复制一下,物件排列拼版程序完成简单的拼版
  • 选择好排列整齐的物件,使用 自动添加裁切线 就能马上添加合适的裁切线。

完成裁切线功能算法主要是找到边界的物件,然后再剔除用不到的顶点,下图是查找边界物件的代码

Border.png

上图查找边界代码,可以简写成这样,取物件左右下上坐标轴 和 范围边界比较,只取距离近的选择,然后填充绿色

Sub Shapes_Border()
    ActiveDocument.Unit = cdrMillimeter
    Dim ost As ShapeRange
    Set ost = ActiveSelectionRange

    radius = 20       '// 当前选择物件的范围边界, radius 是控制距离范围
    Dim s1 As Shape
    For Each Target In ost
        Set s1 = Target   '// s1 遍历物件,取物件左右下上坐标轴
        lx = s1.LeftX:    rx = s1.RightX
        by = s1.BottomY:  ty = s1.TopY

        If Abs(ost.LeftX - lx) < radius Or Abs(ost.RightX - rx) < radius Or Abs(ost.BottomY - by) _
            < radius Or Abs(ost.TopY - ty) < radius Then
            '// 选择边界的物件,填充绿色
            s1.Fill.UniformColor.CMYKAssign 60, 0, 100, 0
        End If
    Next Target
End Sub

cut_lines.bas 完整源码

Type Coordinate
    x As Double
    y As Double
End Type

Sub cut_lines()
    '// 代码运行时关闭窗口刷新
    Application.Optimization = True
    ActiveDocument.Unit = cdrMillimeter
    Dim OrigSelection As ShapeRange
    Set OrigSelection = ActiveSelectionRange

    Dim s1 As Shape
    Dim dot As Coordinate
    Dim arr As Variant, border As Variant

    ' 当前选择物件的范围边界
    set_lx = OrigSelection.LeftX:   set_rx = OrigSelection.RightX
    set_by = OrigSelection.BottomY: set_ty = OrigSelection.TopY
    set_cx = OrigSelection.CenterX: set_cy = OrigSelection.CenterY
    radius = 8:  border = Array(set_lx, set_rx, set_by, set_ty, set_cx, set_cy, radius)

    For Each Target In OrigSelection
        Set s1 = Target
        lx = s1.LeftX:   rx = s1.RightX
        by = s1.BottomY: ty = s1.TopY
        cx = s1.CenterX: cy = s1.CenterY

        '// 范围边界物件判断
        If Abs(set_lx - lx) < radius Or Abs(set_rx - rx) < radius Or Abs(set_by - by) _
            < radius Or Abs(set_ty - ty) < radius Then

            arr = Array(lx, by, rx, by, lx, ty, rx, ty)  '// 物件左下-右下-左上-右上 四个顶点坐标数组
            For i = 0 To 3
                dot.x = arr(2 * i)
                dot.y = arr(2 * i + 1)

                '// 范围边界坐标点判断
                If Abs(set_lx - dot.x) < radius Or Abs(set_rx - dot.x) < radius _
                      Or Abs(set_by - dot.y) < radius Or Abs(set_ty - dot.y) < radius Then

                    draw_line dot, border  '// 以坐标点和范围边界画裁切线
                End If
            Next i
        End If
    Next Target

    Dim s As Shape   '// 使用 ObjectData 搜索裁切线,群组裁切线
    For Each s In ActivePage.Shapes
        If "cut_line" = s.ObjectData("name").Value Then
            ActiveDocument.AddToSelection s
        End If
    Next s
    ActiveSelection.Group

    '// 代码操作结束恢复窗口刷新
    Application.Optimization = False
    ActiveWindow.Refresh
    Application.Refresh
End Sub

'范围边界 border = Array(set_lx, set_rx, set_by, set_ty, set_cx, set_cy, radius)
Private Function draw_line(dot As Coordinate, border As Variant)
    Bleed = 2:  line_len = 3:  radius = border(6)
    Dim line As Shape

    If Abs(dot.y - border(3)) < radius Then
        Set line = ActiveLayer.CreateLineSegment(dot.x, dot.y + Bleed, dot.x, dot.y + (line_len + Bleed))
        set_line_color line
    ElseIf Abs(dot.y - border(2)) < radius Then
        Set line = ActiveLayer.CreateLineSegment(dot.x, dot.y - Bleed, dot.x, dot.y - (line_len + Bleed))
        set_line_color line
    End If

    If Abs(dot.x - border(1)) < radius Then
        Set line = ActiveLayer.CreateLineSegment(dot.x + Bleed, dot.y, dot.x + (line_len + Bleed), dot.y)
        set_line_color line
    ElseIf Abs(dot.x - border(0)) < radius Then
        Set line = ActiveLayer.CreateLineSegment(dot.x - Bleed, dot.y, dot.x - (line_len + Bleed), dot.y)
        set_line_color line
    End If

End Function

Private Function set_line_color(line As Shape)
    '// 设置线宽和注册色,添加物件名为最后群组使用
    line.Outline.SetProperties 0.1
    line.Outline.SetProperties Color:=CreateRegistrationColor
    line.ObjectData("Name").Value = "cut_line"
End Function

0 条评论

发表回复

Avatar placeholder

您的邮箱地址不会被公开。 必填项已用 * 标注