在 AutoCAD 图表中缩放长度 [英] Scaling lengths in an AutoCAD diagram

查看:31
本文介绍了在 AutoCAD 图表中缩放长度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我上一篇文章的后续

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

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

解决方案

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

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

(图 '(1) '(2) '(10.0))

固定其中一个节点的位置意味着第二个节点可以位于以第一个节点为中心、半径为 10.0 的圆上的无穷多个点之一.

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

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

<小时>

当然有作弊的解决方案:

(defun 图 ( pts sls tls )( (λ ( l )(foreach x l (text (cdr x) (itoa (car x)) 0.0 1))(地图车'(lambda ( a b/p q r )(setq p (cdr (assoc a l))q (cdr (assoc b l))r(角度 p q))(entmake (list '(0 . "LINE") (cons 10 p) (cons 11 q) '(62 . 8)))(文本(mapcar '(lambda ( x y ) (/(+ x y) 2.0)) p q)(rtos (* 10.0 (atof (rtos (/(距离 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 文本 ( p s a c )(entmake(列表'(0.文本")(缺点 10 页)(缺点 11 页)(缺点 50 a)(缺点 01 秒)(缺点 62 c)'(40 . 2)'(72 . 1)'(73 . 2))))

这里是一行:

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

将距离四舍五入到最接近的 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)

与:

(roundto (距离 p q) 10.0)

其中10.0代表四舍五入的倍数.

<小时>

按照评论中的问题,您可以使用以下函数将向上四舍五入到下一个倍数(精度为 1e-8):

(defun roundupto ( x m/d r )(setq d (getvar 'dimzin))(setvar 'dimzin 8)(setq r (rtos (* m (fix (+ 1 -1e-8 (/x (float m))))) 2 8))(setvar 'dimzin d)r)

例如:

_$ (roundupto 12.4 12.4)12.4"_$(四舍五入到 12.41 12.4)24.8"_$(四舍五入到 29.15 12.4)37.2"

This is a followup to my previous post here

I've a 2D geometry created using the following code, ref.

(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 (distance p q) 2)
                        (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)
        )
    )
)

Input:

(graph
   '((75 25) (115 45) (90 60) (10 5) (45 0) (45 55) (0 25))
   '(1 1 1 1 2 2 3 4 4 5 6)
   '(2 3 4 5 3 6 6 5 7 7 7)
)

The resulting image

From the coordinates that are given as inputs, the above 2D diagram is created. I want to scale the lengths in the image i.e The lengths have to be multiple of a scalar x (x can be any value). let's say x =10, the lengths have to be scaled to 20.0, 30.0, 50.0, 70.0 and so on. This will result in a shift in coordinates of points at the junctions.

Any suggestions on how to implement the scaling in AutoLisp will be really helpful.

解决方案

In general, there are simply not enough constraints on this problem: for an arbitrary given set of connected nodes and weights, there could be infinitely many configurations which would satisfy the input, or none at all depending on the weights (distances) supplied.

For example, if you were to reduce the problem to 2 connected nodes with a given weight:

(graph '(1) '(2) '(10.0))

Fixing the position of one of the nodes would mean that the second node could be positioned at one of the infinitely many points on a circle of radius 10.0 centered at the first node.

Assuming that you choose an arbitrary position on this circle for the second note, adding a third node connected to the first two then involves solving the intersection between two circles whose radii are equal to the weights between the nodes (that is, if they even intersect).

For every successive node added, you would need to find a common intersection in a set of circles centered at every node to which the new node is connected, whose radii are equal to the weight between the nodes.


There is of course a cheat's solution:

(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)
        )
    )
)

Here, the line:

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

Is rounding the distance to the nearest multiple of 10 and then converting the result to a string with zero decimal place precision.

If you wanted to proceed using this method in general, you might want to define a general rounding function such as the following, which will round to any supplied multiple:

(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
)

And you would then replace:

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

With:

(roundto (distance p q) 10.0)

Where 10.0 represents the rounding multiple.


Following your question in the comments, you could use the following function to round up to the next multiple (to a precision of 1e-8):

(defun roundupto ( x m / d r )
    (setq d (getvar 'dimzin))
    (setvar 'dimzin 8)
    (setq r (rtos (* m (fix (+ 1 -1e-8 (/ x (float m))))) 2 8))
    (setvar 'dimzin d)
    r
)

For example:

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

这篇关于在 AutoCAD 图表中缩放长度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆