将图形转换为 2D 图表

Posted

技术标签:

【中文标题】将图形转换为 2D 图表【英文标题】:Converting a graph to a 2D diagram 【发布时间】:2020-05-02 06:52:06 【问题描述】:

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

上图是在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)

信息存储为graph 的节点、边、边权重。 我想使用此信息创建 2D CAD 绘图。可以使用边权重指定线的长度。但是,我不确定如何从图中检索角度。据我了解,边缘的方向因选择用于创建图形对象的布局而异。 我想创建一个 [x,y] 坐标文件并导入 Autocad。

编辑: 从下面解释的答案中,我知道将边缘权重分配为长度并不简单。作为替代方案,我想从图像中获取节点的坐标,计算节点之间的距离并将距离分配为边缘权重(忽略上面提供的权重)。 使用一组坐标、节点-节点连接和节点-节点距离,我想以编程方式生成一维 CAD 图。

编辑2: 由于无法直接从 MATLAB 输出中获取节点坐标,并且无法将边权重(在原始输入中)指定为边长,因此我想尝试另一种方法。 例如,如果这些是节点((75 25) (115 45) (90 60) (10 5) (45 0) (45 55) (0 25)) 的坐标,我想计算它们之间的欧几里得距离 坐标并将距离分配为边缘权重。 据我了解,AutoCAD 中的dimension 选项卡计算欧几里得距离。但是,我不确定如何将此输出分配为边权重。

任何关于如何进行的建议将不胜感激。

【问题讨论】:

【参考方案1】:

首先,对于您的特定示例,无法生成边缘权重为线长的图形。

例如,如果节点 123 之间的距离根据您的数组:

1 → 2 = 50 1 → 3 = 10

那么2 → 3的距离必须在4060之间,否则三角形不存在。而您的数组将此距离指定为90

为了直观地展示这一点,如果您要描绘一条长度为 50 跨越节点 12 的线,如果您在这条线的任一端构造圆,半径等于节点之间的距离 @987654339 @ 和2 → 3,那么这些圆必须相交才能使三角形存在。

目前,在您指定的权重下,没有这样的交集:


因此,假设每个节点具有任意位置,并将节点坐标作为参数提供给函数,您可以使用如下 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 中产生以下结果:


但是,如果您希望权重由每个提供的节点坐标之间的 2D 距离确定,则可能需要考虑以下 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)
)

这个函数会产生如下结果:

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

(rtos (distance p q) 2 3)

【讨论】:

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

以上是关于将图形转换为 2D 图表的主要内容,如果未能解决你的问题,请参考以下文章

将基于flash的图形转换为基于fusioncharts的javaScript

在 TKinter 窗口中创建图形?

如何将 csv 转换为 json 并编写特定函数以使用 javascript 生成图形?

以2D矢量格式转换/导出Pov-Ray的图形

有没有办法将图形网络转换为R中的关系数据集?

基于QuickJS扩展2D canvas图形接口