C. Draw Geometries

You have learned Point class in the last session. In this session, we will learn some more geometry classes and visualize them with the plotter.

  • vector

  • line

  • polygon

  • circle

  • pointcloud

  • transformation

1. Vector

A vector is a geometric object that has magnitude and direction. In Python, it could be represented through a list of XYZ components.

my_vector = [1, 2, 0]  # xyz coordinates of the vector

A vector can be added, subtracted, multiplied by another vector. For example, here's the example to add two vectors in Python.

vector1 = [1, 2, 0]
vector2 = [0, 1, 0]
vector3 = [vector1[i] + vector2[i] for i in range(3)]
print(vector3)

[1, 3, 0]

compas.geometry provides geometric operation functions to simplify the use of basic Python operations. These functions always return native Python objects. The last example can be realized by using compas.geometry.add_vectors.

from compas.geometry import add_vectors
vector1 = [1, 2, 0]
vector2 = [0, 1, 0]
vector3 = add_vectors(vector1, vector2)
print(vector3)

COMPAS Vector class which contains useful geometric properties and methods.

Now let's create a Vector object and check its length. In Vector class, length is the attribute of the object.

from compas.geometry import Vector
my_vector = Vector(1, 2, 0)
print(my_vector)
print(my_vector.length)

Vector(1.000, 2.000, 0.000) 2.23606797749979

A vector could also be constructed from start and end points. COMPAS geometry types could be used interchangeably with native Python types. Both a COMPAS Point object or a list composed of 3 components could be used as input.

from compas.geometry import Point, Vector
my_vector = Vector.from_start_end(Point(0, 0, 0), Point(1, 2, 0))
# my_vector = Vector.from_start_end([0, 0, 0], [1, 2, 0]
print(my_vector)
print(my_vector == Vector(1, 2, 0))

Vector(1.000, 2.000, 0.000) True

Operators such as + or * involving COMPAS geometry objects always return a new COMPAS geometry object. For example, scaling my_vector by 2 can use the class method Vector.scale(n) as well as * 2.

from compas.geometry import Vector
my_vector = Vector(1, 2, 0)
my_vector.scale(2)
print(my_vector)
print(my_vector == Vector(2, 4, 0))
print(my_vector == Vector(1, 2, 0) * 2)

Vector(2.000, 4.000, 0.000) True True

Exercise: Draw three Vectors

Question: Now you are given three points: point1: [0, 0, 0], point2: [0, 1, 0], point3: [3, 2, 0]. You need to draw three vectors as shown in the following picture.

from compas.geometry import Point
from compas_plotters import GeometryPlotter

# ==============================================================================
# Point Geometry
# ==============================================================================
point1 = Point(0, 0, 0)
point2 = Point(0, 1, 0)
point3 = Point(3, 2, 0)

# ==============================================================================
# Plottor Visualization
# ==============================================================================
plotter = GeometryPlotter(show_axes=True)

plotter.add(point1)
plotter.add(point2)
plotter.add(point3)

plotter.zoom_extents()
plotter.show()

Solution:

Firstly, create three vectors from the start- and end- points with the 3 points. Here are a few different ways to create them.

vector1 = point2 - point1
vector2 = point3 - point2
vector3 = point3 - point1
from compas.geometry import Vector
vector1 = Vector.from_start_end(point1, point2)
vector2 = Vector.from_start_end(point2, point3)
vector3 = Vector.from_start_end(point1, point3)
vector3 = vector1 + vector2

Secondly, add the vectors to the plotter and give each of them color.

plotter.add(vector1, color=(1, 0, 0))
plotter.add(vector2, color=(0, 1, 0))
plotter.add(vector3, color=(0, 0, 1))

vector1 and vector3 are in the right location, because they both start from the origin. vector2 is pointing at the right location but it doesn't start from point2. Remember, the vector has only magnitude and direction. We could add the start point in our plotter.

plotter.add(vector1, point=point1, color=(1, 0, 0))
plotter.add(vector2, point=point2, color=(0, 1, 0))
plotter.add(vector3, point=point1, color=(0, 0, 1))

2. Line

from compas.geometry import Line
from compas_plotters import GeometryPlotter

# create a line
my_line = Line([0, 0, 0], [1, 1, 0])

# visualize the line
plotter = GeometryPlotter(show_axes=True)
plotter.add(my_line, draw_points=False, draw_as_segment=True)
plotter.zoom_extents()
plotter.show()

A Polygon represents an ordered collection of points in space connected by straight line segments forming a closed boundary around the interior space. It has a closed boundary that separates its interior from the exterior.

from compas.geometry import Polygon
from compas_plotters import GeometryPlotter

my_polygon = Polygon([[0, 0, 0], [1, 1, 0], [2, 1, 0], [1, -1, 0]])

plotter = GeometryPlotter(show_axes=True)
plotter.add(my_polygon, edgecolor=(0, 0, 1), facecolor=(1, 1, 0))
plotter.zoom_extents()
plotter.show()

from compas.geometry import Polygon
from compas_plotters import GeometryPlotter

# Construct a regular polygon from a number of sides and a radius.
my_polygon = Polygon.from_sides_and_radius_xy(5, 2.0) 

plotter = GeometryPlotter(show_axes=True)
plotter.add(my_polygon, edgecolor=(0, 0, 1), facecolor=(0.7, 0.7, 1.0))
plotter.zoom_extents()
plotter.show()

A Polyline is a sequence of points connected by line segments. Different from a Polygon, a Polyline doesn't have an interior and an exterior.

from compas.geometry import Polyline
from compas_plotters import GeometryPlotter

my_polyline = Polyline([[0, 0, 0], [1, 1, 0], [2, 1, 0], [1, -1, 0]])

plotter = GeometryPlotter(show_axes=True)
plotter.add(my_polyline, color=(1, 0, 0), linewidth=3)
plotter.zoom_extents()
plotter.show()

5. Circle

from compas.geometry import Plane, Circle
from compas_plotters import GeometryPlotter

my_plane = Plane([2, 1, 0], [0, 0, 1])  # center and normal
my_circle = Circle(my_plane, 2)

plotter = GeometryPlotter(show_axes=True)
plotter.add(my_circle, edgecolor=(0, 0, 1), facecolor=(0, 1, 1), linewidth=3)

plotter.zoom_extents()
plotter.show()

6. PointCloud

from random import random

from compas.geometry import Pointcloud
from compas.utilities import i_to_rgb
from compas_plotters import GeometryPlotter

# ==============================================================================
# Pointcloud Geometry
# ==============================================================================
pcl = Pointcloud.from_bounds(10, 5, 0, 100)

# ==============================================================================
# Visualize Plottor
# ==============================================================================
plotter = GeometryPlotter(show_axes=True)

for point in pcl.points:
    plotter.add(point, facecolor=i_to_rgb(random(), normalize=True))

plotter.zoom_extents()
plotter.show()

7. Transformation

Transformation means changes in geometric shape, which is represented by a 4x4 transformation matrix. Here we will learn 3 typical transformations in COMPAS: translation, rotation and scale.

A COMPAS geometry object can be transformed by calling the method .transform() or .transformed(). The former modifies the object in place, whereas the latter returns a new object.

7.a: Translation

Translation is to move the geometry, one of the most basic transformation types. The shape, size and orientation of the geometry remain the same.

from compas.geometry import Translation
my_polygon = Polygon.from_sides_and_radius_xy(5, 2.0)
T = Translation.from_vector([1, 2, 3])
print(T)
my_polygon.transform(T)

Transformation([[1.0, 0.0, 0.0, 1.0], [0.0, 1.0, 0.0, 2.0], [0.0, 0.0, 1.0, 3.0], [0.0, 0.0, 0.0, 1.0]])

.transformed() creates a new polygon.

my_polygon = Polygon.from_sides_and_radius_xy(5, 2.0)
T1 = Translation.from_vector([1, 2, 0])
T2 = Translation.from_vector([2, 1, 0])
my_polygon.transform(T1)
my_polygon2 = my_polygon.transformed(T2)
my_polygon = Polygon.from_sides_and_radius_xy(5, 2.0)
T1 = Translation.from_vector([1, 2, 0])
T2 = Translation.from_vector([2, 1, 0])
my_polygon2 = my_polygon.transformed(T2)
my_polygon.transform(T1)

7.b: Rotation

Rotation is to rotate the geometry by a certain degree.

R = Rotation.from_axis_and_angle([0, 0, 1], math.radians(15))
my_polygon.transform(R)

7.c: Scale

Scale is to enlarge or shrink the geometry by a scale factor.

S = Scale.from_factors([0.5, 1, 1])  # scale factors along X, Y, Z
my_polygon.transform(S)

7.d: Frame

Frame plays an important role in transformation, especially in 3D. A frame defines a local coordinate system and transformation can be created between different coordinate systems represented by frames.

from compas.geometry import Frame, Transformation
f1 = Frame([1, 1, 1], [0.68, 0.68, 0.27], [-0.67, 0.73, -0.15])
T = Transformation.from_frame(f1)
print(T)

Transformation([[0.6807833515407016, -0.6687681911461376, -0.29880283595731283, 1.0], [0.6807833515407016, 0.7282315441900513, -0.0788216106888398, 1.0], [0.2703110366411609, -0.14975955581430114, 0.9510541619236438, 1.0], [0.0, 0.0, 0.0, 1.0]])

f2 = Frame([1, 1, 1], [0.68, 0.68, 0.27], [-0.67, 0.73, -0.15])
T = Transformation.from_frame_to_frame(f1, f2)
f1.transform(T)
print(f1 == f2)

True

Exercise: Free sketch with COMPAS Geometry (optional)

Create COMPAS geometry objects and visualize them in the plotter.

Inspiration:

Last updated