Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
.. [1] Math Stack Exchange. *Project a point in 3D on a given plane*.
Available at: https://math.stackexchange.com/questions/444968/project-a-point-in-3d-on-a-given-plane.
Examples:
>>> from compas.geometry import project_point_plane
>>> point = [3.0, 3.0, 3.0]
>>> plane = ([0.0, 0.0, 0.0], [0.0, 0.0, 1.0]) # the XY plane
>>> project_point_plane(point, plane)
[3.0, 3.0, 3.0]
"""
base, normal = plane
normal = normalize_vector(normal)
vector = subtract_vectors(point, base)
snormal = scale_vector(normal, dot_vectors(vector, normal))
return subtract_vectors(point, snormal)
Example:
>>> point = [0, 0, 0]
>>> normal = [0, 0, 1]
>>> direction = [1, 1, 1]
>>> P = matrix_from_parallel_projection(point, normal, direction)
"""
T = identity_matrix(4)
normal = normalize_vector(normal)
scale = dot_vectors(direction, normal)
for j in range(3):
for i in range(3):
T[i][j] -= direction[i] * normal[j] / scale
T[0][3], T[1][3], T[2][3] = scale_vector(
direction, dot_vectors(point, normal) / scale)
return T
compare with the original normal. If their cross product is not zero, they
are not parallel, which means the point are not in the same plane.
Four points are coplanar if the volume of the tetrahedron defined by them is
0. Coplanarity is equivalent to the statement that the pair of lines
determined by the four points are not skew, and can be equivalently stated
in vector form as (x2 - x0).[(x1 - x0) x (x3 - x2)] = 0.
"""
tol2 = tol ** 2
if len(points) == 4:
v01 = subtract_vectors(points[1], points[0])
v02 = subtract_vectors(points[2], points[0])
v23 = subtract_vectors(points[3], points[0])
res = dot_vectors(v02, cross_vectors(v01, v23))
return res**2 < tol2
# len(points) > 4
# compare length of cross product vector to tolerance
a, b, c = sample(points, 3)
u = subtract_vectors(b, a)
v = subtract_vectors(c, a)
w = cross_vectors(u, v)
for i in range(0, len(points) - 2):
u = v
v = subtract_vectors(points[i + 2], points[i + 1])
wuv = cross_vectors(w, cross_vectors(u, v))
.. [1] Math Stack Exchange. *Project a point in 3D on a given plane*.
Available at: https://math.stackexchange.com/questions/444968/project-a-point-in-3d-on-a-given-plane.
Examples
--------
>>> from compas.geometry import project_point_plane
>>> point = [3.0, 3.0, 3.0]
>>> plane = ([0.0, 0.0, 0.0], [0.0, 0.0, 1.0]) # the XY plane
>>> project_point_plane(point, plane)
[3.0, 3.0, 0.0]
"""
base, normal = plane
normal = normalize_vector(normal)
vector = subtract_vectors(point, base)
snormal = scale_vector(normal, dot_vectors(vector, normal))
return subtract_vectors(point, snormal)
b = vertices[triangle[1]]
c = vertices[triangle[2]]
ab = subtract_vectors(b, a)
ac = subtract_vectors(c, a)
n = cross_vectors(ab, ac)
V += dot_vectors(a, n)
nx = dot_vectors(n, ex)
ny = dot_vectors(n, ey)
nz = dot_vectors(n, ez)
ab = add_vectors(a, b)
bc = add_vectors(b, c)
ca = add_vectors(c, a)
ab_x2 = dot_vectors(ab, ex) ** 2
bc_x2 = dot_vectors(bc, ex) ** 2
ca_x2 = dot_vectors(ca, ex) ** 2
x += nx * (ab_x2 + bc_x2 + ca_x2)
ab_y2 = dot_vectors(ab, ey) ** 2
bc_y2 = dot_vectors(bc, ey) ** 2
ca_y2 = dot_vectors(ca, ey) ** 2
y += ny * (ab_y2 + bc_y2 + ca_y2)
ab_z2 = dot_vectors(ab, ez) ** 2
bc_z2 = dot_vectors(bc, ez) ** 2
ca_z2 = dot_vectors(ca, ez) ** 2
z += nz * (ab_z2 + bc_z2 + ca_z2)
c = vertices[triangle[2]]
ab = subtract_vectors(b, a)
ac = subtract_vectors(c, a)
n = cross_vectors(ab, ac)
V += dot_vectors(a, n)
nx = dot_vectors(n, ex)
ny = dot_vectors(n, ey)
nz = dot_vectors(n, ez)
ab = add_vectors(a, b)
bc = add_vectors(b, c)
ca = add_vectors(c, a)
ab_x2 = dot_vectors(ab, ex) ** 2
bc_x2 = dot_vectors(bc, ex) ** 2
ca_x2 = dot_vectors(ca, ex) ** 2
x += nx * (ab_x2 + bc_x2 + ca_x2)
ab_y2 = dot_vectors(ab, ey) ** 2
bc_y2 = dot_vectors(bc, ey) ** 2
ca_y2 = dot_vectors(ca, ey) ** 2
y += ny * (ab_y2 + bc_y2 + ca_y2)
ab_z2 = dot_vectors(ab, ez) ** 2
bc_z2 = dot_vectors(bc, ez) ** 2
ca_z2 = dot_vectors(ca, ez) ** 2
z += nz * (ab_z2 + bc_z2 + ca_z2)
w = len(vertices)
vertices.append(centroid)
triangles = [[w, u, v] for u, v in pairwise(face + face[0:1])]
for triangle in triangles:
a = vertices[triangle[0]]
b = vertices[triangle[1]]
c = vertices[triangle[2]]
ab = subtract_vectors(b, a)
ac = subtract_vectors(c, a)
n = cross_vectors(ab, ac)
V += dot_vectors(a, n)
nx = dot_vectors(n, ex)
ny = dot_vectors(n, ey)
nz = dot_vectors(n, ez)
ab = add_vectors(a, b)
bc = add_vectors(b, c)
ca = add_vectors(c, a)
ab_x2 = dot_vectors(ab, ex) ** 2
bc_x2 = dot_vectors(bc, ex) ** 2
ca_x2 = dot_vectors(ca, ex) ** 2
x += nx * (ab_x2 + bc_x2 + ca_x2)
ab_y2 = dot_vectors(ab, ey) ** 2
bc_y2 = dot_vectors(bc, ey) ** 2
ca_y2 = dot_vectors(ca, ey) ** 2
y += ny * (ab_y2 + bc_y2 + ca_y2)
ab_x2 = dot_vectors(ab, ex) ** 2
bc_x2 = dot_vectors(bc, ex) ** 2
ca_x2 = dot_vectors(ca, ex) ** 2
x += nx * (ab_x2 + bc_x2 + ca_x2)
ab_y2 = dot_vectors(ab, ey) ** 2
bc_y2 = dot_vectors(bc, ey) ** 2
ca_y2 = dot_vectors(ca, ey) ** 2
y += ny * (ab_y2 + bc_y2 + ca_y2)
ab_z2 = dot_vectors(ab, ez) ** 2
bc_z2 = dot_vectors(bc, ez) ** 2
ca_z2 = dot_vectors(ca, ez) ** 2
z += nz * (ab_z2 + bc_z2 + ca_z2)
# for j in (-1, 0, 1):
# ab = add_vectors(vertices[triangle[j]], vertices[triangle[j + 1]])
# x += nx * dot_vectors(ab, ex) ** 2
# y += ny * dot_vectors(ab, ey) ** 2
# z += nz * dot_vectors(ab, ez) ** 2
V = V / 6.0
if V < 1e-9:
d = 1.0 / (2 * 24)
else:
d = 1.0 / (2 * 24 * V)
normal = normalize_vector(normal)
direction = normalize_vector(direction)
if math.fabs(dot_vectors(normal, direction)) > _EPS:
raise ValueError('Direction and normal vectors are not orthogonal')
angle = math.tan(angle)
M = [[1. if i == j else 0. for i in range(4)] for j in range(4)]
for j in range(3):
for i in range(3):
M[i][j] += angle * direction[i] * normal[j]
M[0][3], M[1][3], M[2][3] = scale_vector(
direction, -angle * dot_vectors(point, normal))
return M
Args:
point(:obj:`list` of :obj:`float`)
normal(:obj:`list` of :obj:`float`)
perspective(:obj:`list` of :obj:`float`)
Example:
>>> point = [0, 0, 0]
>>> normal = [0, 0, 1]
>>> perspective = [1, 1, 0]
>>> P = matrix_from_perspective_projection(point, normal, perspective)
"""
T = identity_matrix(4)
normal = normalize_vector(normal)
T[0][0] = T[1][1] = T[2][2] = dot_vectors(
subtract_vectors(perspective, point), normal)
for j in range(3):
for i in range(3):
T[i][j] -= perspective[i] * normal[j]
T[0][3], T[1][3], T[2][3] = scale_vector(
perspective, dot_vectors(point, normal))
for i in range(3):
T[3][i] -= normal[i]
T[3][3] = dot_vectors(perspective, normal)
return T