Source code for cam.utilities.geom_utils

"""Fabex 'geom_utils.py' © 2012 Vilem Novak

Main functionality of Fabex.
The functions here are called with operators defined in 'ops.py'
"""

from math import pi

from shapely.geometry import polygon as spolygon

import bpy
from mathutils import Euler, Vector


[docs] def circle(r, np): """Generate a circle defined by a given radius and number of points. This function creates a polygon representing a circle by generating a list of points based on the specified radius and the number of points (np). It uses vector rotation to calculate the coordinates of each point around the circle. The resulting points are then used to create a polygon object. Args: r (float): The radius of the circle. np (int): The number of points to generate around the circle. Returns: spolygon.Polygon: A polygon object representing the circle. """ c = [] v = Vector((r, 0, 0)) e = Euler((0, 0, 2.0 * pi / np)) for a in range(0, np): c.append((v.x, v.y)) v.rotate(e) p = spolygon.Polygon(c) return p
[docs] def helix(r, np, zstart, pend, rev): """Generate a helix of points in 3D space. This function calculates a series of points that form a helix based on the specified parameters. It starts from a given radius and z-coordinate, and generates points by rotating around the z-axis while moving linearly along the z-axis. The number of points generated is determined by the number of turns (revolutions) and the number of points per revolution. Args: r (float): The radius of the helix. np (int): The number of points per revolution. zstart (float): The starting z-coordinate for the helix. pend (tuple): A tuple containing the x, y, and z coordinates of the endpoint. rev (int): The number of revolutions to complete. Returns: list: A list of tuples representing the coordinates of the points in the helix. """ c = [] v = Vector((r, 0, zstart)) e = Euler((0, 0, 2.0 * pi / np)) zstep = (zstart - pend[2]) / (np * rev) for a in range(0, int(np * rev)): c.append((v.x + pend[0], v.y + pend[1], zstart - (a * zstep))) v.rotate(e) c.append((v.x + pend[0], v.y + pend[1], pend[2])) return c
[docs] def get_container(): """Get or create a container object for camera objects. This function checks if a container object named 'CAM_OBJECTS' exists in the current Blender scene. If it does not exist, the function creates a new empty object of type 'PLAIN_AXES', names it 'CAM_OBJECTS', and sets its location to the origin (0, 0, 0). The newly created container is also hidden. If the container already exists, it simply retrieves and returns that object. Returns: bpy.types.Object: The container object for camera objects, either newly created or existing. """ s = bpy.context.scene if s.objects.get("CAM_OBJECTS") is None: bpy.ops.object.empty_add(type="PLAIN_AXES", align="WORLD") container = bpy.context.active_object container.name = "CAM_OBJECTS" container.location = [0, 0, 0] container.hide = True else: container = s.objects["CAM_OBJECTS"] return container
# tools for voroni graphs all copied from the delaunayVoronoi addon:
[docs] class Point: def __init__(self, x, y, z): self.x, self.y, self.z = x, y, z
[docs] def triangle(i, T, A): s = f"{A * 8 / (pi**2)} * (" for n in range(i): if n % 2 != 0: e = (n - 1) / 2 a = round(((-1) ** e) / (n**2), 8) b = round(n * pi / (T / 2), 8) if n > 1: s += "+" s += f"{a} * sin({b} * t)" s += ")" return s
[docs] def s_sine(A, T, dc_offset=0, phase_shift=0): args = [dc_offset, phase_shift, A, T] for arg in args: arg = round(arg, 6) return f"{dc_offset} + {A} * sin((2 * pi / {T}) * (t + {phase_shift}))"