Skip to content

Commit 5d11d0e

Browse files
add template diagrams to FormDiagram
1 parent 03975a5 commit 5d11d0e

File tree

5 files changed

+1436
-0
lines changed

5 files changed

+1436
-0
lines changed

src/compas_tna/diagrams/diagram.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,39 @@
11
from compas.datastructures import Mesh
2+
from compas.geometry import angle_vectors
23

34

45
class Diagram(Mesh):
56
"""Base diagram implementing attributes shared between the form and force diagram."""
7+
8+
def corner_vertices(self, tol=160):
9+
"""
10+
Identify the corner vertices.
11+
12+
Parameters
13+
----------
14+
mesh : Mesh
15+
The mesh to analyze
16+
tol : float, optional
17+
The threshold value for the angle formed between two edges at a vertex
18+
for it to be considered a corner.
19+
Vertices with smaller angles are considered a corner.
20+
21+
Returns
22+
-------
23+
list[int]
24+
25+
"""
26+
vkeys = []
27+
for key in self.vertices_on_boundary():
28+
if self.vertex_degree(key) == 2:
29+
vkeys.append(key)
30+
else:
31+
nbrs = []
32+
for nkey in self.vertex_neighbors(key):
33+
if self.is_edge_on_boundary((key, nkey)):
34+
nbrs.append(nkey)
35+
u = self.edge_vector((key, nbrs[0]))
36+
v = self.edge_vector((key, nbrs[1]))
37+
if angle_vectors(u, v, deg=True) < tol:
38+
vkeys.append(key)
39+
return vkeys
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
import math
2+
3+
from numpy import linspace
4+
5+
from compas.geometry import Point
6+
from compas.tolerance import TOL
7+
from compas.datastructures import Mesh
8+
9+
10+
def create_arch_form_diagram(
11+
H: float = 1.0,
12+
L: float = 2.0,
13+
x0: float = 0.0,
14+
discretisation: int = 100,
15+
) -> Mesh:
16+
"""Construct a FormDiagram based on an arch linear discretisation.
17+
Note: The nodes of the form diagram are spaced following a projection in a semicircular arch.
18+
19+
Parameters
20+
----------
21+
H : float, optional
22+
Height of the arch, by default 1.00
23+
L : float, optional
24+
Span of the arch, by default 2.00
25+
x0 : float, optional
26+
Initial coordiante of the arch, by default 0.0
27+
discretisation : int, optional
28+
Numbers of nodes to be considered in the form diagram, by default 100
29+
30+
Returns
31+
-------
32+
:class:`~compas_tno.diagrams.FormDiagram`
33+
The FormDiagram created.
34+
35+
"""
36+
# Add option for starting from Hi and Li for a given thk.
37+
radius = H / 2 + (L**2 / (8 * H))
38+
spr = math.atan2((L / 2), (radius - H))
39+
tot_angle = 2 * spr
40+
angle_init = (math.pi - tot_angle) / 2
41+
an = tot_angle / (discretisation - 1)
42+
43+
lines = []
44+
45+
for i in range(discretisation - 1):
46+
angle_i = angle_init + i * an
47+
angle_f = angle_init + (i + 1) * an
48+
xi = L / 2 - radius * math.cos(angle_i) + x0
49+
xf = L / 2 - radius * math.cos(angle_f) + x0
50+
51+
lines.append([[xi, 0.0, 0.0], [xf, 0.0, 0.0]])
52+
53+
form = Mesh.from_lines(lines)
54+
55+
return form
56+
57+
58+
def create_linear_form_diagram(
59+
L: float = 2.0,
60+
x0: float = 0.0,
61+
discretisation: int = 100,
62+
) -> Mesh:
63+
"""Helper to create a arch linear form-diagram with equaly spaced (in 2D) nodes.
64+
65+
Parameters
66+
----------
67+
L : float, optional
68+
Span of the arch, by default 2.00
69+
x0 : float, optional
70+
Initial coordiante of the arch, by default 0.0
71+
discretisation : int, optional
72+
Numbers of nodes to be considered in the form diagram, by default 100
73+
74+
Returns
75+
-------
76+
:class:`~compas_tno.diagrams.FormDiagram`
77+
FormDiagram generated according to the parameters.
78+
79+
"""
80+
x = linspace(x0, x0 + L, discretisation) # Continue this remove need of numpy in the future
81+
lines = []
82+
83+
for i in range(discretisation - 1):
84+
xi = x[i]
85+
xf = x[i + 1]
86+
87+
lines.append([[xi, 0.0, 0.0], [xf, 0.0, 0.0]])
88+
89+
form = Mesh.from_lines(lines)
90+
91+
return form
92+

0 commit comments

Comments
 (0)