Source code for viiapackage.strengthening.helper_functions.find_max_min_z

### ===================================================================================================================
###  viia_find_min_max_z
### ===================================================================================================================
# Copyright ©2026 Haskoning Nederland B.V.
# For use by VIIA

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

# General imports
import math
from typing import List

# References for functions and classes in the haskoning_datafusr_py_base package
from haskoning_datafusr_py_base.math import unit_vector, greater, smaller


### ===================================================================================================================
###  2. Function to find the minimum and maximum 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 z_functions = [] 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: z_functions.append([deltaY/deltaY0 * r, deltaZ]) else: z_functions.append([deltaX/deltaX0 * r, deltaZ]) ### ADDED BY ROB, CHECK WORKING ### # Check if z-functions 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 merge_counter = 0 for i in range(len(z_functions)): if i-merge_counter == len(z_functions) - 1: # Compute unit vectors of consecutive functions uv1 = unit_vector(a=z_functions[i-merge_counter]) uv2 = unit_vector(a=z_functions[0]) # If equal, functions can be merged if uv1 == uv2: # Add both functions up in z_function z_function = [] z_function.append(z_functions[i-merge_counter][0] + z_functions[0][0]) z_function.append(z_functions[i-merge_counter][1] + z_functions[0][1]) # Replace first function z_functions[i-merge_counter] = z_function # Delete second function del z_functions[0] # Update counter merge_counter += 1 else: uv1 = unit_vector(a=z_functions[i-merge_counter]) uv2 = unit_vector(a=z_functions[i-merge_counter+1]) if uv1 == uv2: z_function = [] z_function.append(z_functions[i-merge_counter][0] + z_functions[i-merge_counter+1][0]) z_function.append(z_functions[i-merge_counter][1] + z_functions[i-merge_counter+1][1]) z_functions[i-merge_counter] = z_function del z_functions[i-merge_counter+1] merge_counter += 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(z_functions)): if smaller(a=r, b=rc) and smaller(a=rc, b=r + z_functions[i][0]): if z_functions[i][0] != 0: zc = z + z_functions[i][1]*(rc - r)/z_functions[i][0] Intersections.append(zc) if greater(a=r, b=rc) and greater(a=rc, b=r + z_functions[i][0]): if z_functions[i][0] != 0: zc = z + z_functions[i][1]*(r - rc)/-z_functions[i][0] Intersections.append(zc) r = r + z_functions[i][0] z = z + z_functions[i][1] # The intersections are returned as list (should be even number) return Intersections
### =================================================================================================================== ### 3. End of script ### ===================================================================================================================