Geometry 在AutoCAD图表中缩放长度

Geometry 在AutoCAD图表中缩放长度,geometry,lisp,scaling,autocad,autolisp,Geometry,Lisp,Scaling,Autocad,Autolisp,这是我上一篇文章的后续文章 我使用以下代码创建了一个二维几何体 生成的图像 根据作为输入的坐标,创建上述二维图。我想缩放图像中的长度,即长度必须是标量x的倍数(x可以是任何值)。假设x=10,长度必须缩放为20.0、30.0、50.0、70.0等等。这将导致交点处点的坐标发生偏移 任何关于如何在AutoLisp中实现缩放的建议都会非常有用。一般来说,这个问题没有足够的约束条件:对于任意给定的连接节点和权重集,可能有无限多个配置可以满足输入,或者根本没有配置,具体取决于权重(距离)供应 例如,如

这是我上一篇文章的后续文章

我使用以下代码创建了一个二维几何体

生成的图像

根据作为输入的坐标,创建上述二维图。我想缩放图像中的长度,即长度必须是标量x的倍数(x可以是任何值)。假设x=10,长度必须缩放为20.0、30.0、50.0、70.0等等。这将导致交点处点的坐标发生偏移


任何关于如何在AutoLisp中实现缩放的建议都会非常有用。

一般来说,这个问题没有足够的约束条件:对于任意给定的连接节点和权重集,可能有无限多个配置可以满足输入,或者根本没有配置,具体取决于权重(距离)供应

例如,如果要将问题减少到具有给定权重的两个连接节点:

(graph '(1) '(2) '(10.0))
固定其中一个节点的位置意味着第二个节点可以定位在以第一个节点为中心的半径为
10.0
的圆上无限多个点中的一个点上

假设为第二个音符选择此圆上的任意位置,则添加连接到前两个音符的第三个节点将涉及求解半径等于节点之间权重的两个圆之间的交点(即,如果它们甚至相交)

对于添加的每个连续节点,需要在以新节点连接到的每个节点为中心的一组圆中找到一个公共交点,其半径等于节点之间的权重


当然有作弊的解决办法:

(defun graph ( pts sls tls )

    (   (lambda ( l )
            (foreach x l (text (cdr x) (itoa (car x)) 0.0 1))
            (mapcar
               '(lambda ( a b / p q r )
                    (setq p (cdr (assoc a l))
                          q (cdr (assoc b l))
                          r (angle p q)
                    )
                    (entmake (list '(0 . "LINE") (cons 10 p) (cons 11 q) '(62 . 8)))
                    (text
                        (mapcar '(lambda ( x y ) (/ (+ x y) 2.0)) p q)
                        (rtos (* 10.0 (atof (rtos (/ (distance p q) 10.0) 2 0))) 2 0)
                        (if (and (< (* pi 0.5) r) (<= r (* pi 1.5))) (+ r pi) r)
                        2
                    )
                )
                sls tls
            )
        )
        (mapcar 'cons (vl-sort (append sls tls) '<) pts)
    )
)
(defun text ( p s a c )
    (entmake
        (list
           '(0 . "TEXT")
            (cons 10 p)
            (cons 11 p)
            (cons 50 a)
            (cons 01 s)
            (cons 62 c)
           '(40 . 2)
           '(72 . 1)
           '(73 . 2)
        )
    )
)
将距离四舍五入到
10
的最近倍数,然后将结果转换为小数点后零位精度的字符串

如果您想继续使用此方法,您可能需要定义一个通用舍入函数,如以下所示,它将舍入到任何提供的倍数:

(defun roundto ( x m / d r )
    (setq d (getvar 'dimzin))
    (setvar 'dimzin 8)
    (setq r (rtos (* m (atof (rtos (/ x (float m)) 2 0))) 2 16))
    (setvar 'dimzin d)
    r
)
然后您将替换:

(rtos (* 10.0 (atof (rtos (/ (distance p q) 10.0) 2 0))) 2 0)
与:

其中
10.0
表示舍入倍数


根据评论中的问题,您可以使用以下函数将向上取整到下一个倍数(精确到
1e-8
):

例如:

_$ (roundupto 12.4 12.4)
"12.4"
_$ (roundupto 12.41 12.4)
"24.8"
_$ (roundupto 29.15 12.4)
"37.2"

一般来说,这个问题没有足够的约束:对于任意给定的一组连接节点和权重,可能有无限多个配置可以满足输入,或者根本没有配置,这取决于提供的权重(距离)

例如,如果要将问题减少到具有给定权重的两个连接节点:

(graph '(1) '(2) '(10.0))
固定其中一个节点的位置意味着第二个节点可以定位在以第一个节点为中心的半径为
10.0
的圆上无限多个点中的一个点上

假设为第二个音符选择此圆上的任意位置,则添加连接到前两个音符的第三个节点将涉及求解半径等于节点之间权重的两个圆之间的交点(即,如果它们甚至相交)

对于添加的每个连续节点,需要在以新节点连接到的每个节点为中心的一组圆中找到一个公共交点,其半径等于节点之间的权重


当然有作弊的解决办法:

(defun graph ( pts sls tls )

    (   (lambda ( l )
            (foreach x l (text (cdr x) (itoa (car x)) 0.0 1))
            (mapcar
               '(lambda ( a b / p q r )
                    (setq p (cdr (assoc a l))
                          q (cdr (assoc b l))
                          r (angle p q)
                    )
                    (entmake (list '(0 . "LINE") (cons 10 p) (cons 11 q) '(62 . 8)))
                    (text
                        (mapcar '(lambda ( x y ) (/ (+ x y) 2.0)) p q)
                        (rtos (* 10.0 (atof (rtos (/ (distance p q) 10.0) 2 0))) 2 0)
                        (if (and (< (* pi 0.5) r) (<= r (* pi 1.5))) (+ r pi) r)
                        2
                    )
                )
                sls tls
            )
        )
        (mapcar 'cons (vl-sort (append sls tls) '<) pts)
    )
)
(defun text ( p s a c )
    (entmake
        (list
           '(0 . "TEXT")
            (cons 10 p)
            (cons 11 p)
            (cons 50 a)
            (cons 01 s)
            (cons 62 c)
           '(40 . 2)
           '(72 . 1)
           '(73 . 2)
        )
    )
)
将距离四舍五入到
10
的最近倍数,然后将结果转换为小数点后零位精度的字符串

如果您想继续使用此方法,您可能需要定义一个通用舍入函数,如以下所示,它将舍入到任何提供的倍数:

(defun roundto ( x m / d r )
    (setq d (getvar 'dimzin))
    (setvar 'dimzin 8)
    (setq r (rtos (* m (atof (rtos (/ x (float m)) 2 0))) 2 16))
    (setvar 'dimzin d)
    r
)
然后您将替换:

(rtos (* 10.0 (atof (rtos (/ (distance p q) 10.0) 2 0))) 2 0)
与:

其中
10.0
表示舍入倍数


根据评论中的问题,您可以使用以下函数将向上取整到下一个倍数(精确到
1e-8
):

例如:

_$ (roundupto 12.4 12.4)
"12.4"
_$ (roundupto 12.41 12.4)
"24.8"
_$ (roundupto 29.15 12.4)
"37.2"

再次非常感谢。你能解释一下这条线是如何工作的吗?
(rtos(*10.0(atof(rtos(/(距离pq)10.0)20))
例如,如果我检查像10.2这样的值,边的长度不是10.2的倍数。长度总是四舍五入到整数。非常感谢您的更新。如果您不介意,我可以问最后一个问题吗?我们可以修改
roundto
函数的实现方式吗?例如,如果原始图像中边缘的长度为
29.15
,则
roundto
函数返回的最终长度为24.8(当舍入倍数为12.4时)。我想返回37.2而不是24.8的值。怎么用?我想这样做——ceil(29.15/12.4)将返回值3。3*12.4的乘积为37.2。我们可以用这个表单来实现吗?谢谢你的更新。作弊解决方案是否仅通过更改标签而不是几何图形中的实际长度来工作?我理解其中的挑战,
“可能有无限多个配置可以满足输入,或者根据权重根本没有配置”
。但我打算创建的是至少一个配置,其长度由roundupto函数给定。重点是获得正确的边缘长度。再次非常感谢。你能解释一下这条线是如何工作的吗?
(rtos(*10.0(atof(rtos(/(距离pq)10.0)20))
例如,如果我检查像10.2这样的值,边的长度不是10.2的倍数。长度总是四舍五入到整数。非常感谢您的更新。如果您不介意,我可以问最后一个问题吗?我们可以修改
roundto
函数的实现方式吗?例如,如果原始图像中的边的长度为