5. Horizontal Equilibrium

5.a: Horizontal Equilibrium

Once the FormDiagram and ForceDiagram have been successfully created, Horizontal Equilibrium can be calculated to parallel the edges.

# ==============================================================================
#  Horizontal Equilibrium
# ==============================================================================
alpha = 100
kmax = 300
proxy = Proxy()
proxy.package = 'compas_tna.equilibrium'
formdata, forcedata = proxy.horizontal_numpy_proxy(form.to_data(), force.to_data(), kmax=kmax, alpha=alpha)
form = FormDiagram.from_data(formdata)
force = ForceDiagram.from_data(forcedata)

Let's visualize the angle deviation. A lot of edges haven't been perpendicular in both diagrams.

Try to increase kmax!

After increasing the kmax, more edges are perpendicular to each other.

Even after several hundred iterations, the angle deviations may still be high and decrease slowly, which are typically due to very short edges in the ForceDiagram.

5.b: length constraint in ForceDiagram

One way to help the algorithm is to increase the minimum length constraint on all of the edges of the ForceDiagram. Set the edge attribute lmin to 0.3. and run horizontal equilibrium again. There should be an immediate improvement.

force.default_edge_attributes.update({'lmin': 0.3})

5.c: relax FormDiagram

If the angle deviations are still high, another way to help the two diagram reach horizontal equilibrium is to relax the FormDiagram. Unlike the Pattern relaxation (where every edge was assigned force density of 1), every edge of the FormDiagram now has different force densities, since the magnitude of the forces (or the edges of the ForceDiagram) are not the same. Relaxing the FormDiagram after iterations of Horizontal Equilibrium will use the current force densities. Then calculate the Horizontal Equilibirum again.

# ==============================================================================
#  Relax Form
# ==============================================================================
anchors = list(form.vertices_where({'is_anchor': True}))
fixed = list(form.vertices_where({'is_fixed': True}))
fixed = list(set(anchors + fixed))

proxy.package = 'compas_tna.utilities'
formdata = proxy.relax_boundary_openings_proxy(form.to_data(), fixed)
form = FormDiagram.from_data(formdata)

Only once all angle deviations are below an acceptable threshold, you can proceed to the vertical equilibrium step. However, resolving all angle devations is not an absolute requirement, for example, in very short edges they can often be ignored.

Last updated