将图形转换为2D图表

7

我希望创建一个类似下面这个的2D图表,

enter image description here 上述图片使用MATLAB中的Graph创建 (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)

信息以节点、边、图的边权形式存储。 我想使用这些信息创建一个二维CAD图纸。线的长度可以使用边权来指定。然而,我不确定如何从图中检索角度。据我所知,边的方向取决于为创建图对象选择的布局。 我想创建一个[x,y]坐标文件并导入到Autocad中。
编辑: 从下面解释的答案中,我明白了将边权分配为长度并不是一件简单的事情。作为替代方案,我想从图像中获取节点的坐标,计算节点之间的距离,并将距离分配为边权(忽略上面提供的权重)。 有了一组坐标、节点-节点连接和节点-节点距离,我想通过编程生成一个一维CAD图纸。
EDIT2:由于无法直接从MATLAB输出获取节点的坐标,并且(在原始输入中)无法将边权重分配为边长,因此我想尝试另一种方法。例如,如果这些是节点的坐标((75 25) (115 45) (90 60) (10 5) (45 0) (45 55) (0 25)),我想计算坐标之间的欧几里得距离,并将距离分配为边的权重。据我所知,AutoCAD中的dimension选项卡计算欧几里得距离。但是,我不确定如何将此输出分配为边权重。非常感谢您对如何继续的任何建议。
1个回答

7
首先,针对您的特定示例,不可能生成一个图形,使得边的权重是线的长度。
例如,如果节点1、2和3之间的距离与您的数组相符,则2 → 3的距离必须介于40和60之间,否则三角形不存在。而您的数组指定这个距离为90。
为了直观地演示这一点,如果您在长度为50的线上跨越节点1和2,如果在该线的两端构造半径等于节点1→3和2→3之间距离的圆,则这些圆必须相交才能存在三角形。
目前,根据您指定的权重,不存在这样的交点:

enter image description here


因此,假设每个节点的任意位置,并将节点坐标作为函数参数提供,您可以使用以下AutoLISP示例函数构建所需的图形:
(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)
        )
    )
)

当使用以下参数(其中第一个参数表示七个节点的坐标)评估上述函数时:
(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)
)

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

enter image description here


如果您希望权重由提供的节点坐标之间的二维距离确定,则可以考虑以下AutoLISP函数:
(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)
        )
    )
)

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

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

这个函数将产生以下结果:

enter image description here

这里,权重的精度将由AutoCAD中的LUPREC系统变量的值确定(在上面的示例中设置为4)。您还可以通过向我的代码中的rtos函数提供精度参数来覆盖它,例如,对于3位小数的精度,表达式将是:
(rtos (distance p q) 2 3)

非常感谢您详细的说明。您能否看一下原帖中所做的编辑? - Natasha
1
我已经调整了我的帖子中的代码,以便标记节点编号,并更新了图像。在阅读您编辑后的问题时,我认为从matlab输出中获取所需信息是不可能的。 - Lee Mac
1
非常感谢您的编辑,我已经更新了上面的答案。 - Lee Mac
1
DXF是一种标准格式,我建议您使用这种格式。我只能假设您导入文件的软件会自动将封闭多边形解释为区域。 - Lee Mac
1
是的,AutoCAD中存在“SCALE”命令,但在创建任何对象之前,将缩放矩阵变换应用于提供的坐标可能更容易。您可能希望缩放的唯一其他元素是文本高度,在我的代码中由“(40 . 2)”给出(表示文本高度为2个单位)。 - Lee Mac
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接