将图形转换为二维图 [英] Converting a graph to a 2D diagram

查看:35
本文介绍了将图形转换为二维图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想创建一个如下所示的二维图表,

上图是在 MATLAB 中使用 Graph 创建的 (

<小时>

因此,假设每个节点的位置为任意位置,并将节点坐标作为函数的参数提供,您可以使用如下 AutoLISP 示例之类的函数构建所需的图形:

(defun 图 (pts sls tls wgt)( (λ ( l )(foreach x l (text (cdr x) (itoa (car x)) 0.0 1))(地图车'(lambda ( a b c/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)(itoa c)(if (and (< (* pi 0.5) r) (<= r (* pi 1.5))) (+ r pi) r)2))sls tls wgt))(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))))

当使用以下参数(其中第一个参数表示七个节点的坐标)评估上述函数时:

(图形'(((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)'(50 10 20 80 90 90 30 20 100 40 60))

它将在 AutoCAD 中产生以下结果:

<小时>

但是,如果您希望权重由每个提供的节点坐标之间的 2D 距离确定,则可能需要考虑以下 AutoLISP 函数:

(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 (距离 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 文本 ( p s a c )(entmake(列表'(0.文本")(缺点 10 页)(缺点 11 页)(缺点 50 a)(缺点 01 秒)(缺点 62 c)'(40 . 2)'(72 . 1)'(73 . 2))))

提供了一个节点坐标列表和两个连接节点列表:

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

此函数将产生以下结果:

这里,权重的准确性将由 AutoCAD 中 LUPREC 系统变量的值决定(在上例中设置为 4).您也可以通过在我的代码中为 rtos 函数提供精度参数来覆盖它,例如对于 3 个小数位的精度,表达式为:

(rtos (距离 p q) 2 3)

I want to create a 2D diagram like the following,

The above image has been created using Graph in MATLAB (ref)

s = [1 1 1 1 2 2 3 4 4 5 6];
t = [2 3 4 5 3 6 6 5 7 7 7];
weights = [50 10 20 80 90 90 30 20 100 40 60];
G = graph(s,t,weights)
plot(G,'EdgeLabel',G.Edges.Weight)

The information is stored as nodes, edges, edge weight of a graph. I'd like to create a 2D CAD drawing using this information. The length of lines can be specified using edge weights. However, I am not sure how the angles can be retrieved from the graph. From what I understand, the orientation of the edges vary depending on the layout that is selected for creating a graph object. I want to create a [x,y] coordinate file and import into Autocad.

EDIT: From the answer explained below, I understand it is not straightforward to assign the edge weights as lengths. As an alternative, I want to obtain the coordinates of nodes from the image, compute the distance between nodes and assign the distance as edge weights (ignoring the weights provided above). With the set of coordinates, node-node connection and node-node distance I'd like to generate a 1D CAD digram programmatically.

EDIT2: Since the coordinates of the nodes cannot be directly obtained from the MATLAB output and the edge weights(in the original input) cannot be assigned as edge lengths, I'd like to try an alternate approach. For instance, if these are the coordinates of the nodes ((75 25) (115 45) (90 60) (10 5) (45 0) (45 55) (0 25)), I'd like to compute the euclidean distance between the coordinates and assign the distances as edge weights. From what I understand, the dimension tab in AutoCAD computes the euclidean distance. However, I am not sure how to assign this output as edge weights.

Any suggestions on how to proceed will be really appreciated.

解决方案

Firstly, for your particular example it would not be possible to generate a graph for which the edge weights are the line lengths.

For example, if the distances between nodes 1, 2 and 3 are per your arrays:

  • 1 → 2 = 50
  • 1 → 3 = 10

Then the distance 2 → 3 must be between 40 & 60, else the triangle does not exist. Whereas your array specifies this distance as 90.

To demonstrate this visually, if you were to picture a line of length 50 spanning nodes 1 & 2, if you construct circles at either end of this line with radii equal to the distances between nodes 1 → 3 and 2 → 3, then such circles must intersect for the triangle to exist.

Currently, with the weights you have specified, there is no such intersection:


As such, assuming arbitrary positions for each of the nodes, with node coordinates supplied as an argument to the function, you could construct the desired graph using a function such as the following AutoLISP example:

(defun graph ( pts sls tls wgt )
    (   (lambda ( l )
            (foreach x l (text (cdr x) (itoa (car x)) 0.0 1))
            (mapcar
               '(lambda ( a b c / 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)
                        (itoa c)
                        (if (and (< (* pi 0.5) r) (<= r (* pi 1.5))) (+ r pi) r)
                        2
                    )
                )
                sls tls wgt
            )
        )
        (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)
        )
    )
)

When the above function is evaluated with the following arguments (where the first argument indicates the coordinates for the seven nodes):

(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)
   '(50 10 20 80 90 90 30 20 100 40 60)
)

It will produce the following result in AutoCAD:


If however, you want the weights to be determined by the 2D distance between each of the supplied node coordinates, could might want to consider the following AutoLISP function:

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

Supplied with a list of node coordinates and two lists of connected nodes:

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

This function will produce the following result:

Here, the accuracy of the weights will be determined by the value of the LUPREC system variable in AutoCAD (which was set to 4 in the above example). You can alternatively override this by supplying the precision argument to the rtos function in my code, e.g. for a precision of 3 decimal places, the expression would be:

(rtos (distance p q) 2 3)

这篇关于将图形转换为二维图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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