Module mola.utils_vertex
Expand source code
from __future__ import division
#!/usr/bin/env python
# -*- coding: utf-8 -*-
__author__     = ['Benjamin Dillenburger','Demetris Shammas','Mathias Bernhard']
__copyright__  = 'Copyright 2019 / Digital Building Technologies DBT / ETH Zurich'
__license__    = 'MIT License'
__email__      = ['<dbt@arch.ethz.ch>']
import math
from mola.core_vertex import Vertex
from mola import utils_math
def vertex_add(v1,v2):
    """
    adds the position vector of v2 to the position vector of v1
    and returns the result as a new Vertex.
    """
    return Vertex(v1.x + v2.x, v1.y + v2.y, v1.z + v2.z)
def vertex_subtract(v1,v2):
    """
    subtracts the position vector of v2 from the position vector of v1
    and returns the result as a new Vertex.
    """
    return Vertex(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z)
def vertex_scale(v,factor):
    """
    scales the position vector of a Vertex by a factor (multiplication)
    and returns the result as a new Vertex.
    """
    return Vertex(v.x * factor, v.y * factor, v.z * factor)
def vertex_divide(v,factor):
    """
    scales the position vector of a Vertex by a factor (division)
    and returns the result as a new Vertex.
    """
    return Vertex(v.x / factor, v.y / factor, v.z / factor)
def vertex_center(v1,v2):
    """
    Returns the center of a line defined by two vertices.
    Arguments:
    ----------
    v1, v2 : mola.Vertex
        start and end points of the line
    Returns:
    --------
    mola.Vertex
        the center point of the line
    """
    return Vertex((v1.x+v2.x)/2,(v1.y+v2.y)/2,(v1.z+v2.z)/2)
def vertex_unitize(v):
    """
    returns a Vertex of the same direction
    and of unit length 1
    """
    l = vertex_length(v)
    if l == 0:
        return v
    return vertex_scale(v,1/l)
def vertex_angle(v1,v2):
    a = vertex_unitize(v1)
    b = vertex_unitize(v2)
    f = vertex_dot(a, b)
    f = min(1, max(-1, f))
    return math.acos(f)
def vertex_angle_triangle(vPrevious,v,vNext):
    #law of cosines
    vvn = vertex_distance(v, vNext)
    vvp = vertex_distance(vPrevious, v)
    vnvp = vertex_distance(vNext, vPrevious)
    return math.acos((vvn * vvn + vvp * vvp - vnvp * vnvp) / (2 * vvn * vvp))
def vertex_length(v):
    """
    returns the length of the position vector of a Vertex,
    the distance from the origin (0,0,0).
    """
    return math.sqrt(v.x * v.x + v.y * v.y + v.z * v.z)
def vertex_dot(v1,v2):
    """
    returns the dot product of v1 and v2.
    """
    return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z
def vertex_cross(v1,v2):
    """
    returns the cross product of v1 and v2 as a new Vertex.
    """
    return Vertex(v1.y * v2.z - v2.y * v1.z, v1.z * v2.x - v2.z * v1.x, v1.x * v2.y - v2.x * v1.y)
def vertex_distance(v1,v2):
    """
    returns the distance between v1 and v2.
    """
    dX = v2.x - v1.x
    dY = v2.y - v1.y
    dZ = v2.z - v1.z
    return math.sqrt(dX*dX+dY*dY+dZ*dZ)
def vertex_between_rel(v1, v2, factor):
    """
    finds a position vector between v1 and v2 by a factor (0.0 to 1.0 corresponds to v1 to v2)
    and returns the result as a new Vertex.
    """
    return Vertex((v2.x - v1.x) * factor + v1.x, (v2.y - v1.y) * factor + v1.y, (v2.z - v1.z) * factor + v1.z)
def vertex_between_abs(v1, v2, dis):
    """
    finds a position vector between v1 and v2 by an absolute distance value from v1
    and returns the result as a new Vertex.
    """
    d = vertex_distance(v1,v2)
    return vertex_between_rel(v1, v2, dis / d)
def vertex_rotate_2D_90(vertex):
    return Vertex(-vertex.y, vertex.x, vertex.z)
def vertex_offset_line(v1, v2, offset):
    v = vertex_subtract(v2, v1)
    v = vertex_unitize(v)
    v = vertex_scale(v,offset)
    t = v.x
    v.x = -v.y
    v.y = t
    v.z = 0
    return Vertex(vertex_add(v1, v), vertex_add(v2, v))
def vertex_offset_point(v1, v2, v3, offset1, offset2):
    line1 = vertex_offset_line(v1, v2, offset1)
    line2 = vertex_offset_line(v2, v3, offset2)
    return vertex_line_line_intersection(line1.x,line1.y,line2.x,line2.y)
def vertex_line_line_intersection(a,b,c,d):
    """
    Returns the intersection of two lines in 2D as a new Vertex.
    Arguments:
    ----------
    a,b,c,d: mola.Vertex
             a,b are the endpoints of line1
             c,d are the endpoints of line2
    """
    deltaABX = b.x - a.x
    deltaABY = b.y - a.y
    deltaDCX = d.x - c.x
    deltaDCY = d.y - c.y
    denominator = deltaABX * deltaDCY - deltaABY * deltaDCX
    if denominator == 0:
        return None
    numerator = (a.y - c.y) * deltaDCX - (a.x - c.x) * deltaDCY
    r = numerator / denominator
    x = a.x + r * deltaABX
    y = a.y + r * deltaABY
    return Vertex(x,y,0)
"""// VERTICES LIST //"""
def vertices_list_normal(vertices):
    """
    Returns the normal of a triangle defined by 3 vertices.
    The normal is a vector of length 1 perpendicular to the plane of the triangle.
    Arguments:
    ----------
    vertices : list
        the list of vertices get the normal from (first 3 will be used)
    """
    return normalFromTriangle(vertices[0], vertices[1], vertices[2])
def vertices_list_area(vertices):
    """
    Returns the area of a face from a list of 3 or 4 vertices
    """
    if len(vertices) == 3:
        return triangle_area(vertices[0],vertices[1],vertices[2])
    # could be made generic for n-gons, triangle fan?
    elif len(vertices) == 4:
        a1 = triangle_area(vertices[0], vertices[1], vertices[2])
        a2 = triangle_area(vertices[2], vertices[3], vertices[0])
        return a1 + a2
def vertices_list_center(vertices):
    """
    Returns the center point (type Vertex) of a list of vertices.
    Note: not the center of gravity, just the average of the vertices.
    Arguments:
    ----------
    vertices : list of mola.Vertex
            The list of vertices to be measured
    """
    n = len(vertices)
    cx = sum([v.x for v in vertices]) / n
    cy = sum([v.y for v in vertices]) / n
    cz = sum([v.z for v in vertices]) / n
    return Vertex(cx,cy,cz)
"""// TRIANGLE //"""
def triangle_area(v1,v2,v3):
    """
    Returns the area of the triangle from 3 vertices
    Arguments:
    ----------
    v1, v2, v3 : mola.Vertex
        vertices of the triangle
    """
    return triangle_coords_area(v1.x, v1.y, v1.z, v2.x, v2.y, v2.z, v3.x, v3.y, v3.z)
def triangle_normal(v1,v2,v3):
    """
    Returns the normal of a triangle defined by 3 vertices.
    The normal is a vector of length 1 perpendicular to the plane of the triangle.
    Arguments:
    ----------
    v1, v2, v3 : mola.Vertex
        the vertices get the normal from
    """
    v = v2-v1
    u = v3-v1
    crossProduct=vertex_cross(v, u)
    return vertex_unitize(crossProduct)
def triangle_coords_area(xa, ya, za, xb, yb, zb, xc, yc, zc):
    """
    Returns the area of the triangle from 9 coordinates
    Arguments:
    ----------
    xa, ya, za : float
        coordinates of vertex a
    xb, yb, zb : float
        coordinates of vertex b
    xc, yc, zc : float
        coordinates of vertex c
    """
    return 0.5 * math.sqrt(math.pow(utils_math.math_determinant(xa, xb, xc, ya, yb, yc, 1, 1, 1), 2) + math.pow(utils_math.math_determinant(ya, yb, yc, za, zb, zc, 1, 1, 1), 2) + math.pow(utils_math.math_determinant(za, zb, zc, xa, xb, xc, 1, 1, 1), 2))
Functions
def triangle_area(v1, v2, v3)- 
Returns the area of the triangle from 3 vertices
Arguments:
v1, v2, v3 : mola.Vertex vertices of the triangle
Expand source code
def triangle_area(v1,v2,v3): """ Returns the area of the triangle from 3 vertices Arguments: ---------- v1, v2, v3 : mola.Vertex vertices of the triangle """ return triangle_coords_area(v1.x, v1.y, v1.z, v2.x, v2.y, v2.z, v3.x, v3.y, v3.z) def triangle_coords_area(xa, ya, za, xb, yb, zb, xc, yc, zc)- 
Returns the area of the triangle from 9 coordinates
Arguments:
xa, ya, za : float coordinates of vertex a xb, yb, zb : float coordinates of vertex b xc, yc, zc : float coordinates of vertex c
Expand source code
def triangle_coords_area(xa, ya, za, xb, yb, zb, xc, yc, zc): """ Returns the area of the triangle from 9 coordinates Arguments: ---------- xa, ya, za : float coordinates of vertex a xb, yb, zb : float coordinates of vertex b xc, yc, zc : float coordinates of vertex c """ return 0.5 * math.sqrt(math.pow(utils_math.math_determinant(xa, xb, xc, ya, yb, yc, 1, 1, 1), 2) + math.pow(utils_math.math_determinant(ya, yb, yc, za, zb, zc, 1, 1, 1), 2) + math.pow(utils_math.math_determinant(za, zb, zc, xa, xb, xc, 1, 1, 1), 2)) def triangle_normal(v1, v2, v3)- 
Returns the normal of a triangle defined by 3 vertices. The normal is a vector of length 1 perpendicular to the plane of the triangle.
Arguments:
v1, v2, v3 : mola.Vertex the vertices get the normal from
Expand source code
def triangle_normal(v1,v2,v3): """ Returns the normal of a triangle defined by 3 vertices. The normal is a vector of length 1 perpendicular to the plane of the triangle. Arguments: ---------- v1, v2, v3 : mola.Vertex the vertices get the normal from """ v = v2-v1 u = v3-v1 crossProduct=vertex_cross(v, u) return vertex_unitize(crossProduct) def vertex_add(v1, v2)- 
adds the position vector of v2 to the position vector of v1 and returns the result as a new Vertex.
Expand source code
def vertex_add(v1,v2): """ adds the position vector of v2 to the position vector of v1 and returns the result as a new Vertex. """ return Vertex(v1.x + v2.x, v1.y + v2.y, v1.z + v2.z) def vertex_angle(v1, v2)- 
Expand source code
def vertex_angle(v1,v2): a = vertex_unitize(v1) b = vertex_unitize(v2) f = vertex_dot(a, b) f = min(1, max(-1, f)) return math.acos(f) def vertex_angle_triangle(vPrevious, v, vNext)- 
Expand source code
def vertex_angle_triangle(vPrevious,v,vNext): #law of cosines vvn = vertex_distance(v, vNext) vvp = vertex_distance(vPrevious, v) vnvp = vertex_distance(vNext, vPrevious) return math.acos((vvn * vvn + vvp * vvp - vnvp * vnvp) / (2 * vvn * vvp)) def vertex_between_abs(v1, v2, dis)- 
finds a position vector between v1 and v2 by an absolute distance value from v1 and returns the result as a new Vertex.
Expand source code
def vertex_between_abs(v1, v2, dis): """ finds a position vector between v1 and v2 by an absolute distance value from v1 and returns the result as a new Vertex. """ d = vertex_distance(v1,v2) return vertex_between_rel(v1, v2, dis / d) def vertex_between_rel(v1, v2, factor)- 
finds a position vector between v1 and v2 by a factor (0.0 to 1.0 corresponds to v1 to v2) and returns the result as a new Vertex.
Expand source code
def vertex_between_rel(v1, v2, factor): """ finds a position vector between v1 and v2 by a factor (0.0 to 1.0 corresponds to v1 to v2) and returns the result as a new Vertex. """ return Vertex((v2.x - v1.x) * factor + v1.x, (v2.y - v1.y) * factor + v1.y, (v2.z - v1.z) * factor + v1.z) def vertex_center(v1, v2)- 
Returns the center of a line defined by two vertices.
Arguments:
v1, v2 : mola.Vertex start and end points of the line
Returns:
mola.Vertex the center point of the line
Expand source code
def vertex_center(v1,v2): """ Returns the center of a line defined by two vertices. Arguments: ---------- v1, v2 : mola.Vertex start and end points of the line Returns: -------- mola.Vertex the center point of the line """ return Vertex((v1.x+v2.x)/2,(v1.y+v2.y)/2,(v1.z+v2.z)/2) def vertex_cross(v1, v2)- 
returns the cross product of v1 and v2 as a new Vertex.
Expand source code
def vertex_cross(v1,v2): """ returns the cross product of v1 and v2 as a new Vertex. """ return Vertex(v1.y * v2.z - v2.y * v1.z, v1.z * v2.x - v2.z * v1.x, v1.x * v2.y - v2.x * v1.y) def vertex_distance(v1, v2)- 
returns the distance between v1 and v2.
Expand source code
def vertex_distance(v1,v2): """ returns the distance between v1 and v2. """ dX = v2.x - v1.x dY = v2.y - v1.y dZ = v2.z - v1.z return math.sqrt(dX*dX+dY*dY+dZ*dZ) def vertex_divide(v, factor)- 
scales the position vector of a Vertex by a factor (division) and returns the result as a new Vertex.
Expand source code
def vertex_divide(v,factor): """ scales the position vector of a Vertex by a factor (division) and returns the result as a new Vertex. """ return Vertex(v.x / factor, v.y / factor, v.z / factor) def vertex_dot(v1, v2)- 
returns the dot product of v1 and v2.
Expand source code
def vertex_dot(v1,v2): """ returns the dot product of v1 and v2. """ return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z def vertex_length(v)- 
returns the length of the position vector of a Vertex, the distance from the origin (0,0,0).
Expand source code
def vertex_length(v): """ returns the length of the position vector of a Vertex, the distance from the origin (0,0,0). """ return math.sqrt(v.x * v.x + v.y * v.y + v.z * v.z) def vertex_line_line_intersection(a, b, c, d)- 
Returns the intersection of two lines in 2D as a new Vertex.
Arguments:
a,b,c,d: mola.Vertex a,b are the endpoints of line1 c,d are the endpoints of line2
Expand source code
def vertex_line_line_intersection(a,b,c,d): """ Returns the intersection of two lines in 2D as a new Vertex. Arguments: ---------- a,b,c,d: mola.Vertex a,b are the endpoints of line1 c,d are the endpoints of line2 """ deltaABX = b.x - a.x deltaABY = b.y - a.y deltaDCX = d.x - c.x deltaDCY = d.y - c.y denominator = deltaABX * deltaDCY - deltaABY * deltaDCX if denominator == 0: return None numerator = (a.y - c.y) * deltaDCX - (a.x - c.x) * deltaDCY r = numerator / denominator x = a.x + r * deltaABX y = a.y + r * deltaABY return Vertex(x,y,0) def vertex_offset_line(v1, v2, offset)- 
Expand source code
def vertex_offset_line(v1, v2, offset): v = vertex_subtract(v2, v1) v = vertex_unitize(v) v = vertex_scale(v,offset) t = v.x v.x = -v.y v.y = t v.z = 0 return Vertex(vertex_add(v1, v), vertex_add(v2, v)) def vertex_offset_point(v1, v2, v3, offset1, offset2)- 
Expand source code
def vertex_offset_point(v1, v2, v3, offset1, offset2): line1 = vertex_offset_line(v1, v2, offset1) line2 = vertex_offset_line(v2, v3, offset2) return vertex_line_line_intersection(line1.x,line1.y,line2.x,line2.y) def vertex_rotate_2D_90(vertex)- 
Expand source code
def vertex_rotate_2D_90(vertex): return Vertex(-vertex.y, vertex.x, vertex.z) def vertex_scale(v, factor)- 
scales the position vector of a Vertex by a factor (multiplication) and returns the result as a new Vertex.
Expand source code
def vertex_scale(v,factor): """ scales the position vector of a Vertex by a factor (multiplication) and returns the result as a new Vertex. """ return Vertex(v.x * factor, v.y * factor, v.z * factor) def vertex_subtract(v1, v2)- 
subtracts the position vector of v2 from the position vector of v1 and returns the result as a new Vertex.
Expand source code
def vertex_subtract(v1,v2): """ subtracts the position vector of v2 from the position vector of v1 and returns the result as a new Vertex. """ return Vertex(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z) def vertex_unitize(v)- 
returns a Vertex of the same direction and of unit length 1
Expand source code
def vertex_unitize(v): """ returns a Vertex of the same direction and of unit length 1 """ l = vertex_length(v) if l == 0: return v return vertex_scale(v,1/l) def vertices_list_area(vertices)- 
Returns the area of a face from a list of 3 or 4 vertices
Expand source code
def vertices_list_area(vertices): """ Returns the area of a face from a list of 3 or 4 vertices """ if len(vertices) == 3: return triangle_area(vertices[0],vertices[1],vertices[2]) # could be made generic for n-gons, triangle fan? elif len(vertices) == 4: a1 = triangle_area(vertices[0], vertices[1], vertices[2]) a2 = triangle_area(vertices[2], vertices[3], vertices[0]) return a1 + a2 def vertices_list_center(vertices)- 
Returns the center point (type Vertex) of a list of vertices. Note: not the center of gravity, just the average of the vertices.
Arguments:
vertices : list of mola.Vertex The list of vertices to be measured
Expand source code
def vertices_list_center(vertices): """ Returns the center point (type Vertex) of a list of vertices. Note: not the center of gravity, just the average of the vertices. Arguments: ---------- vertices : list of mola.Vertex The list of vertices to be measured """ n = len(vertices) cx = sum([v.x for v in vertices]) / n cy = sum([v.y for v in vertices]) / n cz = sum([v.z for v in vertices]) / n return Vertex(cx,cy,cz) def vertices_list_normal(vertices)- 
Returns the normal of a triangle defined by 3 vertices. The normal is a vector of length 1 perpendicular to the plane of the triangle.
Arguments:
vertices : list the list of vertices get the normal from (first 3 will be used)
Expand source code
def vertices_list_normal(vertices): """ Returns the normal of a triangle defined by 3 vertices. The normal is a vector of length 1 perpendicular to the plane of the triangle. Arguments: ---------- vertices : list the list of vertices get the normal from (first 3 will be used) """ return normalFromTriangle(vertices[0], vertices[1], vertices[2])