将图形转换为二维图
Converting a graph to a 2D diagram
我想创建一个二维图表,如下所示,
上图是在 MATLAB (ref)
中使用 Graph
创建的
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
、2
和 3
之间的距离符合您的数组:
1 → 2 = 50
1 → 3 = 10
那么距离2 → 3
必须在40
& 60
之间,否则三角形不存在。而您的数组将此距离指定为 90
.
为了直观地演示这一点,如果您要描绘一条长度为 50
的线,跨越节点 1
和 2
,如果您在该线的两端用半径构造圆等于节点 1 → 3
和 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 中产生以下结果:
但是,如果您希望权重由每个提供的节点坐标之间的二维距离确定,可能需要考虑以下 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)
我想创建一个二维图表,如下所示,
Graph
创建的
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
、2
和 3
之间的距离符合您的数组:
1 → 2 = 50
1 → 3 = 10
那么距离2 → 3
必须在40
& 60
之间,否则三角形不存在。而您的数组将此距离指定为 90
.
为了直观地演示这一点,如果您要描绘一条长度为 50
的线,跨越节点 1
和 2
,如果您在该线的两端用半径构造圆等于节点 1 → 3
和 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 中产生以下结果:
但是,如果您希望权重由每个提供的节点坐标之间的二维距离确定,可能需要考虑以下 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)