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])