Source code for viiapackage.strengthening.helper_functions.find_max_min_z

### ===================================================================================================================
###   viia_find_min_max_z
### ===================================================================================================================
# Copyright ©VIIA 2024

### ===================================================================================================================
###   1. Import modules
### ===================================================================================================================

# General imports
import math
from typing import List

# References for functions and classes in the rhdhv_fem package
from rhdhv_fem.fem_math import fem_unit_vector, fem_greater, fem_smaller


### ===================================================================================================================
###   2. Function to find the minimum and maxium z coordinates of the intersections
### ===================================================================================================================

[docs]def viia_find_min_max_z(plane_points: List[List[float]], point: List[float]): """ This function returns the intersections of a vertical line through a vertical plane. The plane (wall) may be angled in x- and y- direction. The shape of the plane is free to chose, as long as it is vertical. Input: - plane_points (list with lists of 3 floats): The sorted points of a given plane. Coordinates in x-, y- and z- directionm e.g. [[0,1,2],[2,3,4],[3,6,4], etc. - point (list with 3 floats): The coordinates (x,y,z) of the requested point where vertical section is made. The z-coordinate is not used. For example: [0.1, 0.3, 2.3] Output: The z-coordinates of intersections are returned as list. Should always be an even number. For example: >>> viia_find_min_max_z([[0.0, 0.0, -0.175], [0.0, 0.0, 2.325], [0.0, 5.0, 4.325], [0.0, 5.0, 1.825]], [0, 5]) Returns the list: [[4.325], [1.8250000000000002]] """ # The first found vector in x- and y- directions from the first point of the plane, determines the direction of the # line in x- and y- projection of the plane. If the second point is vertically above the first point, the next point # will be evaluated, etc. for i in range(1, len(plane_points)): deltaX0 = plane_points[i][0] - plane_points[i - 1][0] deltaY0 = plane_points[i][1] - plane_points[i - 1][1] r = math.sqrt(deltaX0*deltaX0 + deltaY0*deltaY0) if r != 0: break # Following the contour of the plane, the delta-functions are saved in a list Zfunctions = [] for i in range(0, len(plane_points)): if i == len(plane_points)-1: deltaX = plane_points[0][0] - plane_points[i][0] deltaY = plane_points[0][1] - plane_points[i][1] deltaZ = plane_points[0][2] - plane_points[i][2] else: deltaX = plane_points[i + 1][0] - plane_points[i][0] deltaY = plane_points[i + 1][1] - plane_points[i][1] deltaZ = plane_points[i + 1][2] - plane_points[i][2] if deltaX0 == 0: Zfunctions.append([deltaY/deltaY0 * r, deltaZ]) else: Zfunctions.append([deltaX/deltaX0 * r, deltaZ]) ### ADDED BY ROB, CHECK WORKING ### # Check if Zfunctions contains consecutive functions with the same direction # Add these up, otherwise one intersection can be found twice, when it is exactly at the point where two functions # coincide # Initiate counter to count number of merged functions mergecounter = 0 for i in range(len(Zfunctions)): if i-mergecounter == len(Zfunctions) - 1: # Compute unit vectors of consecutive functions uv1 = fem_unit_vector(Zfunctions[i-mergecounter]) uv2 = fem_unit_vector(Zfunctions[0]) # If equal, functions can be merged if uv1 == uv2: # Add both functions up in Zfunction Zfunction = [] Zfunction.append(Zfunctions[i-mergecounter][0] + Zfunctions[0][0]) Zfunction.append(Zfunctions[i-mergecounter][1] + Zfunctions[0][1]) # Replace first function Zfunctions[i-mergecounter] = Zfunction # Delete second function del Zfunctions[0] # Update counter mergecounter += 1 else: uv1 = fem_unit_vector(Zfunctions[i-mergecounter]) uv2 = fem_unit_vector(Zfunctions[i-mergecounter+1]) if uv1 == uv2: Zfunction = [] Zfunction.append(Zfunctions[i-mergecounter][0] + Zfunctions[i-mergecounter+1][0]) Zfunction.append(Zfunctions[i-mergecounter][1] + Zfunctions[i-mergecounter+1][1]) Zfunctions[i-mergecounter] = Zfunction del Zfunctions[i-mergecounter+1] mergecounter += 1 ### ADDED BY ROB, CHECK WORKING ### # Determine the requested coordinate on the line of the projection of the wall in x- and y-direction. # This direction is called r in this function. deltaX = point[0] - plane_points[0][0] deltaY = point[1] - plane_points[0][1] if deltaX0 == 0: rc = deltaY/deltaY0 * r else: rc = deltaX/deltaX0 * r # Following the contour of the plane, it is checked if the r-coordinate is defined in the delta-functions. Intersections = [] r = 0 z = plane_points[0][2] for i in range(len(Zfunctions)): if fem_smaller(r, rc) and fem_smaller(rc, r + Zfunctions[i][0]): if Zfunctions[i][0] != 0: zc = z + Zfunctions[i][1]*(rc - r)/Zfunctions[i][0] Intersections.append(zc) if fem_greater(r, rc) and fem_greater(rc, r + Zfunctions[i][0]): if Zfunctions[i][0] != 0: zc = z + Zfunctions[i][1]*(r - rc)/-Zfunctions[i][0] Intersections.append(zc) r = r + Zfunctions[i][0] z = z + Zfunctions[i][1] # The intersections are returned as list (should be even number) return Intersections
### =================================================================================================================== ### 3. End of script ### ===================================================================================================================