def get_distance(self, point): """ single point distance function Parameters ---------- point: :class:`compas.geometry.Point` The point in R<sup>3</sup> space to query for it's distance. Returns ------- float The distance from the query point to the surface of the object. """ if not isinstance(point, Point): point = Point(*point) point.transform(self.inversetransform) tp = Point(point[0], point[1], 0) cp = closest_point_on_polyline_xy(tp, self.polyline) d = tp.distance_to_point(cp) if is_point_in_polygon_xy(tp, self.polyline): d = -1.*d d = max(d, abs(point.z) - self.height / 2.0) return d
def get_distance(self, point): """ single point distance function """ if not isinstance(point, Point): pt = Point(*point) else: pt = point pt.transform(self.inversetransform) up = [abs((p % self.unitcell) - self.unitcell / 2) for p in pt] dmin = 9999999. for l in self.ltypes[self.ltype]: sp = [self.pointlist[l[0]][i] * self.unitcell for i in range(3)] ep = [self.pointlist[l[1]][i] * self.unitcell for i in range(3)] v = [ep[i] - sp[i] for i in range(3)] d = [up[i] - sp[i] for i in range(3)] # dot products c2 = sum([i * j for (i, j) in zip(v, v)]) c1 = sum([i * j for (i, j) in zip(d, v)]) b = c1 / c2 p = [sp[i] + b * v[i] for i in range(3)] dmin = min(dmin, sum([(up[i] - p[i])**2 for i in range(3)])) return math.sqrt(dmin) - self.thickness / 2.0
def get_distance(self, point): """ single point distance function Parameters ---------- point: :class:`compas.geometry.Point` The point in R<sup>3</sup> space to query for it's distance. Returns ------- float The distance from the query point to the surface of the object. """ if not isinstance(point, Point): p = Point(*point) else: p = point p.transform(self.inversetransform) k0 = Vector(p.x / self.radiusX, p.y / self.radiusY, p.z / self.radiusZ).length k1 = Vector(p.x / self.radiusX**2, p.y / self.radiusY**2, p.z / self.radiusZ**2).length if k1 == 0: return -1 else: return k0 * (k0 - 1.0) / k1
def get_distance(self, point): """ single point distance function """ if not isinstance(point, Point): pt = Point(*point) else: pt = point pt.transform(self.inversetransform) radius = math.sqrt(pt.x * pt.x + pt.y * pt.y) polx = abs(radius % self.unitcell) - self.unitcell/2 angle = (math.atan2(pt.y, pt.x) + math.pi) / (2 * math.pi) poly = (angle * self.polarnumber) % 1 poly = abs((poly - 0.5) * self.unitcell) polz = abs(pt.z % self.unitcell) - self.unitcell/2 up = [polx, poly, polz] dmin = 9999999. for ltype in self.ltypes[self.ltype]: sp = [self.pointlist[ltype[0]][i] * self.unitcell for i in range(3)] ep = [self.pointlist[ltype[1]][i] * self.unitcell for i in range(3)] v = [ep[i]-sp[i] for i in range(3)] d = [up[i]-sp[i] for i in range(3)] # dot products c2 = sum([i*j for (i, j) in zip(v, v)]) c1 = sum([i*j for (i, j) in zip(d, v)]) b = c1/c2 p = [sp[i] + b * v[i] for i in range(3)] dmin = min(dmin, sum([(up[i]-p[i])**2 for i in range(3)])) return math.sqrt(dmin) - self.thickness/2.0
def get_distance(self, point): """ single point distance function Parameters ---------- point: :class:`compas.geometry.Point` The point in R<sup>3</sup> space to query for it's distance. Returns ------- float The distance from the query point to the surface of the object. """ if not isinstance(point, Point): p = Point(*point) else: p = point p.transform(self.inversetransform) dx = abs(p.x) - (self.box.xsize / 2.0 - self.radius) dy = abs(p.y) - (self.box.ysize / 2.0 - self.radius) dz = abs(p.z) - (self.box.zsize / 2.0 - self.radius) inside = max(dx, max(dy, dz)) - self.radius dx = max(dx, 0) dy = max(dy, 0) dz = max(dz, 0) if inside + self.radius < 0: return inside else: corner = sqrt(dx * dx + dy * dy + dz * dz) - self.radius return corner
def get_distance(self, point): """ single point distance function """ if not isinstance(point, Point): point = Point(*point) point.transform(self.inversetransform) dxy = length_vector_xy(point) # distance_point_point_xy(self.torus.center, point) d2 = sqrt((dxy - self.torus.radius_axis)**2 + point.z**2) return d2 - self.torus.radius_pipe
def get_distance(self, point): if not isinstance(point, Point): point = Point(*point) point.transform(self.inversetransform) x, y, z = point # Tetrahedron if self.type == 0: return (max(abs(x + y) - z, abs(x - y) + z) - self.radius) / self.sqrt3 # Octahedron elif self.type == 1: s = abs(x) + abs(y) + abs(z) return (s - self.radius) * self.tan30 # Dodecahedron elif self.type == 2: v = Vector((1+sqrt(5))/2, 1, 0) v.unitize() px = abs(x / self.radius) py = abs(y / self.radius) pz = abs(z / self.radius) p = Vector(px, py, pz) a = p.dot(v) b = p.dot(Vector(v.z, v.x, v.y)) c = p.dot(Vector(v.y, v.z, v.x)) q = (max(max(a, b), c) - v.x) * self.radius return q # Icosahedron elif self.type == 3: r = self.radius * 0.8506507174597755 v = Vector((sqrt(5) + 3)/2, 1, 0) v.unitize() w = sqrt(3)/3 px = abs(x / r) py = abs(y / r) pz = abs(z / r) p = Vector(px, py, pz) a = p.dot(v) b = p.dot(Vector(v.z, v.x, v.y)) c = p.dot(Vector(v.y, v.z, v.x)) d = p.dot([w,w,w]) - v.x q = max(max(max(a, b), c) - v.x, d) * r return q else: return 0
def get_distance(self, point): """ single point distance function """ if not isinstance(point, Point): point = Point(*point) point.transform(self.inversetransform) dxy = length_vector_xy( point) # distance_point_point_xy(self.cylinder.center, point) d = dxy - self.cylinder.radius d = max(d, abs(point.z) - self.cylinder.height / 2.0) return d
def get_distance(self, point): if not isinstance(point, Point): point = Point(*point) m = matrix_from_frame(self.frame) mi = matrix_inverse(m) point.transform(mi) tp = Point(point[0], point[1], 0) cp = closest_point_on_polyline_xy(tp, self.polyline) d = tp.distance_to_point(cp) if is_point_in_polygon_xy(tp, self.polyline): d = -1. * d d = max(d, abs(point.z) - self.height / 2.0) return d
def visualize_urscript(script): M = [ [-1000, 0, 0, 0], [0, 1000, 0, 0], [0, 0, 1000, 0], [0, 0, 0, 1], ] rgT = matrix_to_rgtransform(M) cgT = Transformation.from_matrix(M) robot = Robot() viz_planes = [] movel_matcher = re.compile(r"^\s*move([lj]).+((-?\d+\.\d+,?\s?){6}).*$") for line in script.splitlines(): mo = re.search(movel_matcher, line) if mo: if mo.group(1) == "l": # movel ptX, ptY, ptZ, rX, rY, rZ = mo.group(2).split(",") pt = Point(float(ptX), float(ptY), float(ptZ)) pt.transform(cgT) frame = Frame(pt, [1, 0, 0], [0, 1, 0]) R = Rotation.from_axis_angle_vector( [float(rX), float(rY), float(rZ)], pt) T = matrix_to_rgtransform(R) plane = cgframe_to_rgplane(frame) plane.Transform(T) viz_planes.append(plane) else: # movej joint_values = mo.group(2).split(",") configuration = Configuration.from_revolute_values( [float(d) for d in joint_values]) frame = robot.forward_kinematics(configuration) plane = cgframe_to_rgplane(frame) plane.Transform(rgT) viz_planes.append(plane) return viz_planes
def get_distance(self, point): """ single point distance function Parameters ---------- point: :class:`compas.geometry.Point` The point in R<sup>3</sup> space to query for it's distance. Returns ------- float The distance from the query point to the surface of the object. """ if not isinstance(point, Point): p = Point(*point) else: p = point p.transform(self.inversetransform) return self.distobj.get_distance(p)
def get_distance(self, point): """ single point distance function """ if not isinstance(point, Point): point = Point(*point) frame = Frame.from_plane(self.cone.plane) m = matrix_from_frame(frame) mi = matrix_inverse(m) point.transform(mi) dxy = length_vector_xy(point) a = 1.1 c = [sin(a), cos(a)] # dot product d = sum( [i * j for (i, j) in zip(c, [dxy, point.z - self.cone.height])]) return d
def get_distance(self, point): """ single point distance function Parameters ---------- point: :class:`compas.geometry.Point` The point in R<sup>3</sup> space to query for it's distance. Returns ------- float The distance from the query point to the surface of the object. """ if not isinstance(point, Point): point = Point(*point) point.transform(self.inversedmatrix) f = (point.z + self.cone.height / 2) / self.cone.height temprad = self.cone.radius - f * self.cone.radius dxy = length_vector_xy(point) - temprad return max(dxy, abs(point.z) - self.cone.height / 2)
def get_distance(self, point): """ single point distance function Parameters ---------- point: :class:`compas.geometry.Point` The point in R<sup>3</sup> space to query for it's distance. Returns ------- float The distance from the query point to the surface of the object. """ if not isinstance(point, Point): point = Point(*point) point.transform(self.inversedmatrix) d = ((point.z * point.z) / (self.rb * self.rb)) + ( (point.y * point.y) / (self.ra * self.ra)) + ( (point.x * point.x) / (self.ra * self.ra)) * (1 + self.k * point.z) - 1 return d
import math from compas.geometry import Point from compas.geometry import Quaternion from compas.geometry import Rotation from compas.geometry import Transformation from compas.geometry import Translation # transform with identity matrix x = Transformation() a = Point(1, 0, 0) b = a.transformed(x) assert a == b # translate t = Translation.from_vector([5, 1, 0]) b = a.transformed(t) assert b == [6, 1, 0] # in-place transform r = Rotation.from_axis_and_angle([0, 0, 1], math.pi) a.transform(r) assert str(a) == str(Point(-1.0, 0.0, 0.0)) # rotation from quaternion q = Quaternion(0.918958, -0.020197, -0.151477, 0.363544) assert q.is_unit R = Rotation.from_quaternion(q) assert R.quaternion == q
def unroll(zone): unrolled = [] for quadmesh, trimesh in zone: flatmesh = trimesh.copy() fkeys = list( trimesh.faces_where_predicate(partial(endswith_NAME, '-00'))) for fkey in fkeys: nbrs = trimesh.face_neighbors(fkey) if len(nbrs) == 1: root = fkey break root = None for key in trimesh.face_vertices(root): if trimesh.vertex_degree(key) == 2: corner = key break corner = None origin = trimesh.vertex_coordinates(corner) zaxis = trimesh.face_normal(root, unitized=True) xaxis = trimesh.edge_direction( corner, trimesh.face_vertex_descendant(root, corner)) yaxis = normalize_vector(cross_vectors(zaxis, xaxis)) frame = Frame(origin, xaxis, yaxis) frame_to = Frame.worldXY() T = Transformation.from_frame_to_frame(frame, frame_to) for key in trimesh.face_vertices(root): x, y, z = trimesh.vertex_coordinates(key) point = Point(x, y, z) point.transform(T) flatmesh.set_vertex_attributes(key, 'xyz', point) tovisit = deque([root]) visited = set([root]) while tovisit: fkey = tovisit.popleft() for u, v in trimesh.face_halfedges(fkey): nbr = trimesh.halfedge[v][u] if nbr is None: continue if nbr in visited: continue tovisit.append(nbr) visited.add(nbr) origin = trimesh.vertex_coordinates(v) zaxis = trimesh.face_normal(nbr, unitized=True) xaxis = trimesh.edge_direction(v, u) yaxis = normalize_vector(cross_vectors(xaxis, zaxis)) frame = Frame(origin, xaxis, yaxis) origin = flatmesh.vertex_coordinates(v) zaxis = [0, 0, 1] xaxis = flatmesh.edge_direction(v, u) yaxis = normalize_vector(cross_vectors(xaxis, zaxis)) frame_to = Frame(origin, xaxis, yaxis) T = Transformation.from_frame_to_frame(frame, frame_to) w = trimesh.face_vertex_ancestor(nbr, v) x, y, z = trimesh.vertex_coordinates(w) point = Point(x, y, z) point.transform(T) flatmesh.set_vertex_attributes(w, 'xyz', point) for key, attr in quadmesh.vertices(True): x, y, z = flatmesh.vertex_coordinates(key) attr['x'] = x attr['y'] = y attr['z'] = z unrolled.append(quadmesh) return unrolled
# ============================================================================== # Main # ============================================================================== if __name__ == '__main__': from compas.geometry import Point from compas.geometry import Translation from compas_plotters import Plotter2 plotter = Plotter2() a = Point(0.0, 0.0) b = Point(5.0, 0.0) c = Point(5.0, 5.0) T = Translation([0.1, 0.0, 0.0]) plotter.add(a, edgecolor='#ff0000') plotter.add(b, edgecolor='#00ff00') plotter.add(c, edgecolor='#0000ff') plotter.draw(pause=1.0) for i in range(100): a.transform(T) plotter.redraw(pause=0.01) plotter.show()
from compas.geometry import Plane from compas.geometry import Line from compas.geometry import Polygon from compas.geometry import matrix_from_axis_and_angle M = matrix_from_axis_and_angle([0, 0, 1], pi / 2) point = Point(0.0, 0.0, 0.0) normal = Vector(0.0, 0.0, 1.0) plane = Plane(point, normal) line = Line([0.0, 0.0, 0.0], [1.0, 0.0, 0.0]) triangle = Polygon([[0.0, 0.0, 0.0], [1.0, 0.0, 0.0], [1.0, 1.0, 0.0]]) polygon = Polygon([[0.0, 0.0, 0.0], [1.0, 0.0, 0.0], [1.0, 1.0, 0.0], [0.0, 1.0, 0.0]]) p = Point(1.0, 1.0, 1.0) p.transform(M) print(*p) print(repr(p)) print(p.distance_to_point(point)) print(p.distance_to_line(line)) print(p.distance_to_plane(plane)) print(p.in_triangle(triangle))
"""Example: transform point and vector """ from compas.geometry import Point from compas.geometry import Vector from compas.geometry import Rotation # create Rotation around point with axis and angle point = Point(1.0, 0.0, 0.0) axis, angle = [-0.248, -0.786, -0.566], 2.78 R = Rotation.from_axis_and_angle(axis, angle, point=point) # apply Transformation to Point p = Point(1, 1, 1) p.transform(R) # apply Transformation to Vector v = Vector(1, 1, 1) v.transform(R) # should not be the same! print(p) print(v)
"""Change-basis transformation vs transformation between two frames. """ from compas.geometry import Point from compas.geometry import Frame from compas.geometry import Transformation F1 = Frame([2, 2, 2], [0.12, 0.58, 0.81], [-0.80, 0.53, -0.26]) F2 = Frame([1, 1, 1], [0.68, 0.68, 0.27], [-0.67, 0.73, -0.15]) # transformation between 2 frames F1, F2 Tf = Transformation.from_frame_to_frame(F1, F2) # change-basis transformation between two frames F1 and F2. Tc = Transformation.from_change_of_basis(F1, F2) # they are different print(Tf) print(Tc) # This is how to use Tf: transform geometry into another coordinate frame pt = Point(2, 2, 2) pt.transform(Tf) print(pt, "==", F2.point) # This is how to use Tc: represent geometry in another coordinate frame pt = Point(0, 0, 0) # local point in F1 pt.transform(Tc) print(pt, "==", F2.to_local_coordinates(F1.point))
from math import radians from compas.geometry import Vector from compas.geometry import Line from compas.geometry import Rotation from compas.geometry import Translation from compas_plotters import Plotter2 point = Point(0.0, 3.0, 0.0) vector = Vector(2.0, 0.0, 0.0) direction = vector.unitized() loa = Line(point, point + direction) R = Rotation.from_axis_and_angle(Vector(0.0, 0.0, 1.0), radians(3.6)) T = Translation(direction.scaled(0.1)) plotter = Plotter2() plotter.add(vector, point=point, draw_point=True) plotter.add(loa) plotter.draw(pause=1.0) for i in range(100): point.transform(T) vector.transform(R) plotter.redraw(pause=0.01) plotter.show()
def unroll(meshes, edge): quadmesh, trimesh = meshes flatmesh = trimesh.copy() u, v = edge root = trimesh.halfedge[u][v] if root is None: root = trimesh.halfedge[v][u] u, v = v, u origin = trimesh.vertex_coordinates(u) zaxis = trimesh.face_normal(root, unitized=True) xaxis = normalize_vector(trimesh.edge_direction(u, v)) yaxis = normalize_vector(cross_vectors(zaxis, xaxis)) frame = Frame(origin, xaxis, yaxis) frame_to = Frame.worldXY() T = Transformation.from_frame_to_frame(frame, frame_to) for key in trimesh.face_vertices(root): x, y, z = trimesh.vertex_coordinates(key) point = Point(x, y, z) point.transform(T) flatmesh.set_vertex_attributes(key, 'xyz', point) tovisit = list(trimesh.faces()) tovisit.remove(root) fkey = root while tovisit: for u, v in trimesh.face_halfedges(fkey): nbr = trimesh.halfedge[v][u] if nbr is None: continue if nbr not in tovisit: continue tovisit.remove(nbr) break fkey = nbr u, v = v, u origin = trimesh.vertex_coordinates(u) zaxis = trimesh.face_normal(fkey, unitized=True) xaxis = normalize_vector(trimesh.edge_direction(u, v)) yaxis = normalize_vector(cross_vectors(xaxis, zaxis)) frame = Frame(origin, xaxis, yaxis) origin = flatmesh.vertex_coordinates(u) zaxis = [0, 0, 1.0] xaxis = normalize_vector(flatmesh.edge_direction(u, v)) yaxis = normalize_vector(cross_vectors(xaxis, zaxis)) frame_to = Frame(origin, xaxis, yaxis) T = Transformation.from_frame_to_frame(frame, frame_to) w = trimesh.face_vertex_ancestor(fkey, u) x, y, z = trimesh.vertex_coordinates(w) point = Point(x, y, z) point.transform(T) flatmesh.set_vertex_attributes(w, 'xyz', point) for key, attr in quadmesh.vertices(True): x, y, z = flatmesh.vertex_coordinates(key) attr['x'] = x attr['y'] = y attr['z'] = z return quadmesh
"""Example: Transform a point and invert the transformation """ from compas.geometry import Point from compas.geometry import Rotation from math import pi p = Point(3, 4, 5) T = Rotation.from_axis_and_angle([2, 2, 2], pi / 4) p.transform(T) # transform Point p with T print(p) Tinv = T.inverse() # create inverse Transformation to T p.transform(Tinv) # transform Point p with inverse Transformation # check if p has the same values as in the beginning print(p) # == (3, 4, 5) # Btw, what is the result of multiplying T with Tinv? print(T * Tinv)