Source code for pymycar.Cad.geometric_forms

"""
Geometric Forms
===============

This module contains functions to generate and manipulate basic geometric forms using PyVista. These forms can be used for visualization and analysis in various engineering and physics simulations. The functions in this module provide simple representations of common mechanical components such as control arms, tubes, cylinders, spheres, springs, and other structures.

Each function creates geometric shapes by connecting specified points in 3D space, allowing users to model complex systems efficiently. These forms can be used to build assemblies or test various configurations, making them useful for mechanical simulations, 3D modeling, and CAD systems.

The generated shapes are returned as `pv.MultiBlock` objects, which allow for efficient handling and visualization of multiple geometric forms in a single structure.

These functions provide an easy way to generate basic geometric components for more complex 3D models.

"""

import pyvista as pv
import numpy as np

[docs] def control_arm(uca_front, uca_rear, uca_outer_i, radius=10, resolution=100, n_sides=10): """ Generate a control arm. Parameters ---------- uca_front : array-like Coordinates of the front point of the control arm. uca_rear : array-like Coordinates of the rear point of the control arm. uca_outer_i : array-like Coordinates of the outer point of the control arm. radius : float, optional Radius of the Tubes, by default 10. resolution : int, optional Resolution of the Tubes, by default 100. n_sides : int, optional Number of sides of the Tubes, by default 10. Returns ------- pv.MultiBlock MultiBlock containing two Tubes representing the control arm. Notes ----- The control arm is formed by two Tubes connecting the front and rear points to the outer point. """ e1 = pv.Tube(pointa=uca_front, pointb=uca_outer_i, resolution=resolution, radius=radius, n_sides=n_sides) e2 = pv.Tube(pointa=uca_rear, pointb=uca_outer_i, resolution=resolution, radius=radius, n_sides=n_sides) return pv.MultiBlock([e1, e2])
[docs] def simple_tube(tierod_inner, tierod_outer_i, radius=5, resolution=100, n_sides=10): """ Generate a simple tube. Parameters ---------- tierod_inner : array-like Coordinates of the inner point of the tube. tierod_outer_i : array-like Coordinates of the outer point of the tube. radius : float, optional Radius of the Tube, by default 10. resolution : int, optional Resolution of the Tube, by default 100. n_sides : int, optional Number of sides of the Tube, by default 10. Returns ------- pv.MultiBlock MultiBlock containing a Tube representing the simple tube. Notes ----- The simple tube is formed by a single Tube connecting the inner and outer points. """ e5 = pv.Tube(pointa=tierod_inner, pointb=tierod_outer_i, resolution=resolution, radius=radius, n_sides=n_sides) return pv.MultiBlock([e5])
[docs] def simple_cylinder(wheel_center_i, height, radius): """ Generate a simple cylinder. Parameters ---------- wheel_center_i : array-like Coordinates of the center of the cylinder. height : float Height of the cylinder. radius : float Radius of the cylinder. Returns ------- pv.MultiBlock MultiBlock containing a Cylinder representing the simple cylinder. Notes ----- The simple cylinder is a Cylinder centered at the specified point with the given height and radius. """ wheel = pv.Cylinder(center=wheel_center_i, direction=(0, 1, 0), height=height, radius=radius) return pv.MultiBlock([wheel])
[docs] def simple_sphere(wheel_center_i, radius): """ Generate a simple sphere. Parameters ---------- wheel_center_i : array-like Coordinates of the center of the sphere. radius : float Radius of the sphere. Returns ------- pv.MultiBlock MultiBlock containing a Sphere representing the simple sphere. Notes ----- The simple sphere is a Sphere centered at the specified point with the given radius. """ point_wheel_center = pv.Sphere(radius=radius, center=wheel_center_i, theta_resolution=30, phi_resolution=30) return pv.MultiBlock([point_wheel_center])
[docs] def spring(u_spring_mount, l_spring_mount_i, radius=5): """ Generate a spring. Parameters ---------- u_spring_mount : array-like Coordinates of the upper mounting point of the spring. l_spring_mount_i : array-like Coordinates of the lower mounting point of the spring. radius : float, optional Radius of the Spheres and the Tube, by default 10. Returns ------- pv.MultiBlock MultiBlock containing two Spheres and a Tube representing the spring. Notes ----- The spring is formed by two Spheres at the upper and lower mounting points and a Tube connecting them. """ p1 = simple_sphere(u_spring_mount, radius) p2 = simple_sphere(l_spring_mount_i, radius) return pv.MultiBlock([p1, p2, simple_tube(u_spring_mount, l_spring_mount_i)])
[docs] def spring_old(u_spring_mount, l_spring_mount, radius=10, coil_radius=10, n_coils=1, n_points=1000): """ Generate a spring. Parameters ---------- u_spring_mount : array-like Coordinates of the upper mounting point of the spring. l_spring_mount : array-like Coordinates of the lower mounting point of the spring. radius : float, optional Radius of the Spheres, by default 10. coil_radius : float, optional Radius of the spring coil, by default 5. n_coils : int, optional Number of coils in the spring, by default 10. n_points : int, optional Number of points to represent the spring coil, by default 100. Returns ------- pv.MultiBlock MultiBlock containing two Spheres and a Helix representing the spring. Notes ----- The spring is formed by two Spheres at the upper and lower mounting points and a Helix representing the spring coil. """ # Create spheres at the mounting points p1 = pv.Sphere(radius=radius, center=u_spring_mount) p2 = pv.Sphere(radius=radius, center=l_spring_mount) p3 = pv.Sphere(radius=radius, center=[0,0,0]) # Calculate the direction and length of the spring direction = l_spring_mount - u_spring_mount direction = direction[0] length = np.linalg.norm(direction) direction = direction.astype(float) / length # Calculate a perpendicular direction if np.allclose(direction, [0, 0, 1]): perpendicular = np.array([1, 0, 0]) else: reference_vector = np.array([0, 0, 1]) perpendicular = np.cross(direction, reference_vector) perpendicular /= np.linalg.norm(perpendicular) # Create a polygon to represent the cross-section of the spring coil profile = pv.Polygon( center = [0,0,0], radius = coil_radius, normal =perpendicular, n_sides=30, ) # Create the helical shape using extrude_rotate angle = 360 * n_coils extruded = profile.extrude_rotate( resolution=n_points, translation=length, dradius=0.0, angle=angle, capping=True, rotation_axis=direction ) return pv.MultiBlock([p1, p3, extruded])
[docs] def rocked(rocked_pivot, l_spring_mount, push_rod_inner_i): """ Generate a structure with tubes connecting various points. Parameters ---------- rocked_pivot : array-like Coordinates of the rocked pivot point. l_spring_mount : array-like Coordinates of the lower mounting point of the spring. push_rod_inner_i : array-like Coordinates of the inner point of the push rod. Returns ------- pv.MultiBlock MultiBlock containing three Tubes representing the structure. Notes ----- The structure is formed by three Tubes connecting various points. """ e1 = simple_tube(rocked_pivot, l_spring_mount) e2 = simple_tube(rocked_pivot, push_rod_inner_i) e3 = simple_tube(l_spring_mount, push_rod_inner_i) return pv.MultiBlock([e1, e2, e3])