Now you have learned the compas geometries and how to draw them in the plotter. In this session, we will use what we have learned to visualize a simple flat cable-net.
1. Ex 1: Visualize Cablenet
Question:
You want to visualize your 2D cablenet with plotter. It's a 6 by 6 grid, and the orthogonal distance between each node is 10. All cables are represented by lines, and nodes are by points.
Answer:
1.a. draw nodes
Firstly, use Point objects to visualize all the nodes.
# ==============================================================================# Import# ==============================================================================from compas.geometry import Pointfrom compas_plotters import GeometryPlotter# ==============================================================================# Parameters# ==============================================================================row =5col =5unit_len =10# ==============================================================================# Generating the grid nodes and Visualization# ==============================================================================# initiate the plotterplotter =GeometryPlotter(show_axes=True)# use a nested for loop to generate the gridfor i inrange(row +1):for j inrange(col +1): my_point =Point(i * unit_len, j * unit_len, 0) plotter.add(my_point)# show in plotterplotter.zoom_extents()plotter.show()
1.b. draw cables
Then draw Line objects.
# create a 5 by 5 grid# distance between points in x and y directions are both 10# ==============================================================================# Import# ==============================================================================from compas.geometry import Linefrom compas_plotters import GeometryPlotter# ==============================================================================# Parameters# ==============================================================================row =5col =5unit_len =10# ==============================================================================# Generating the grid lines and Visualization# ==============================================================================# initiate the plotterplotter =GeometryPlotter(show_axes=True)# use a nested for loop to generate the gridfor i inrange(row +1):for j inrange(col +1):# draw horizontal linesif i != row: start_x = i * unit_len start_y = j * unit_len end_x = (i +1) * unit_len end_y = j * unit_len line_horizontal =Line([start_x, start_y, 0], [end_x, end_y, 0]) plotter.add(line_horizontal, draw_points=False, draw_as_segment=True, color=(1, 0, 0))# draw vertical linesif j != col: start_x = i * unit_len start_y = j * unit_len end_x = i * unit_len end_y = (j +1) * unit_len line_vertical =Line([start_x, start_y, 0], [end_x, end_y, 0]) plotter.add(line_vertical, draw_points=False, draw_as_segment=True, color=(0, 1, 0))# show in plotterplotter.zoom_extents()plotter.show()
1.c: draw nodes and lines
Now draw both nodes and cables.
2. Connectivity
In the last part drawing the cable-net, all lines use two points composed of xyz values as input. Thus, when a line is created, two points are created at the same time. How many times a point is created depends on how many lines connect this point. This is in-efficient and hard to organize the information when the cable-net becomes bigger and more complex.
A simple improvement is to use the index of the point when creating lines to avoid repetition. Every time a line is created, an index pair of the start-point and end-point would be used to find the corresponding xyz coordinates of the points.
The index pair is called the connectivity. Here points are called nodes, and lines are called edges. In the following example, node 2 and node 4 are connected, node 4 and node 3 are disconnected.
nodes
xyz coordinates
0
[1, 0, 0]
1
[0, 1, 0]
2
[1, 1, 0]
3
[2, 1, 0]
4
[1, 2, 0]
edges
xyz coordinates
edge connectivity
0
[1, 0, 0], [1, 1, 0]
(0, 2)
1
[0, 1, 0], [1, 1, 0]
(1, 2)
2
[2, 1, 0], [1, 1, 0]
(3, 2)
3
[1, 2, 0], [1, 1, 0]
(4, 2)
The connectivity represents the abstract topology of the cable-net. One significant advantage of the connectivity is that when the xyz coordinate of a node is updated, There's no need to find the lines that contain this point and update the line.
Now, try modifying the cable-net using the connectivity data-structure. List nodes contains all the xyz coordinates of the nodes. List edges contains the connectivity index pairs of the edges.
2.a: Connectivity and Cable-net
# ==============================================================================# Import# ==============================================================================from compas.geometry import Point, Linefrom compas_plotters import GeometryPlotter# ==============================================================================# Parameters# ==============================================================================row =5col =5unit_len =10nodes = [] # list containing the xyz coordinates of the nodesedges = [] # list containing connectivity of the edges# ==============================================================================# Generating the grid# ==============================================================================# use a nested for loop to generate the gridfor i inrange(row +1):for j inrange(col +1):# add the xyz coordinates to nodes nodes.append([i * unit_len, j * unit_len, 0])# index of the node index = i * (row +1) + j# add horizontal edgesif i != row: edges.append([index, index + row +1])# add vertical edgesif j != col: edges.append([index, index +1])# ==============================================================================# Visualize Plottor# ==============================================================================plotter =GeometryPlotter(show_axes=True)for node in nodes: plotter.add(Point(*node))for u, v in edges: line =Line(nodes[u], nodes[v]) plotter.add(line, draw_points=False, draw_as_segment=True)# show in plotterplotter.zoom_extents()plotter.show()
2.b: Update the Cable-net
Question:
Move node 20 along positive x-axis 1 unit and along positive y-axis 2 unit. Update the cable-net.
Answer:
nodes[20][0] +=1nodes[20][1] +=2
3. Ex 2: Assemble your Cable-net
Question:
You have received all your cables cut correctly in length and nodes. (You could use the cable-net created in the last session) Now you pick one node, node 20, and try to find the nodes connected to it and the cables that connect two nodes. How would you do it?
Answer:
Edges contain all the index pairs of two nodes that are connected. If one of the nodes is node 20, then the other node is the one connected with node 20.
my_node_index =20neighbors = []for u, v in edges:if u == my_node_index: neighbors.append(v)elif v == my_node_index: neighbors.append(u)print("The nodes connect node", my_node_index, "are nodes:", *neighbors)
The nodes connect node 12 are nodes: 14 19 26 21
my_node = nodes[my_node_index]for nbr_index in neighbors: neighbor_node = nodes[nbr_index] distance =distance_point_point(my_node, neighbor_node)print("distance to node", nbr_index, "is", round(distance, 2))
distance to node 14 is 11.18
distance to node 19 is 12.04
distance to node 26 is 9.22
distance to node 21 is 8.06
Question: What if you want to keep searching more nodes?
Answer:
A simple solution is to change the last part to a function. But this function always loop through all the edges to find the correct index, which is not efficient. Another solution could be creating an index pair dictionary to store the connectivity information, where the key is the index of the node and the item is a list that contains all the neighbor index of the node.
node_neighbors ={i: [] for i inrange(len(nodes))}for u, v in edges: node_neighbors[u].append(v) node_neighbors[v].append(u)print(node_neighbors[20])
The number of neighbors of a node isis called the degree or valence of a node.