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

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

问题描述

这是我上一篇文章

根据输入的坐标,创建上面的2D图.我想缩放图像中的长度,即长度必须是标量x的倍数(x可以是任何值).假设x = 10,则长度必须缩放为20.0、30.0、50.0、70.0,依此类推.这将导致结点的坐标发生偏移.

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

解决方案

通常,此问题没有足够的约束:对于任意给定的一组连接的节点和权重,可以无限满足许多配置输入,或者完全不输入,具体取决于提供的权重(距离).

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

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

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

假设您在第二个音符的该圆上选择了任意位置,则添加与前两个音符连接的第三个节点,则需要求解半径等于两个节点之间权重的两个圆之间的交点(即,如果他们甚至相交).

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


当然有作弊的解决方案:

 (defun graph(pts sls tls)((lambda(l)(foreach x l(文本(cdr x)(itoa(汽车x))0.0 1))(地图车'(lambda(a b/p q r)(setq p(cdr(关联a l))q(cdr(关联b l))r(角度p q))(entmake(列表'(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)(如果(和(和(<(* pi 0.5)r)(< = r(* pi 1.5)))(+ r pi)r)2个))sls tls))(mapcar'cons(vl-sort(追加sls tls)'<)pts)))(禁用文本(p s a c)(entmake(列表'(0."TEXT")(10便士)(缺点11 p)(缺点50 a)(cons 01 s)(缺点62 c)'(40.2)'(72.1)'(73 2)))) 

在这里,一行:

 (rtos(* 10.0(atof(rtos(/(距离p q)10.0)2 0)))2 0) 

将距离四舍五入为 10 的最接近的倍数,然后将结果转换为零精度的小数字符串.

如果您想总体上继续使用此方法,则可能需要定义如下的通用舍入函数,该函数将舍入为任何提供的倍数:

 (defun四舍五入(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(/(距离p q)10.0)2 0)))2 0) 

使用:

 (舍入(距离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(固定(+1 1 -1e-8(/x(float m)))))2 8))(setvar'dimzin d)[R) 

例如:

  _ $(向上舍入为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天全站免登陆