Aligning points, polyline endpoints - understanding issue with Compas Geometry

I am beginner with Compas and confused about the behaviour of the code, see below. I created a root regular triangle, and after that I wanted to add a regular square at one edge of the triangle with aligned vertices. Some points now have not the same coordinates, but they should have. Also the plotter is showing a gap between endpoints of polyline pl4 and polyline pl9, and also between pl8 and pl9. I want to add more regular polygons to the other edges of the triangle, i.e. a pentagon or a hexagon, and 2 of their vertices should be aligned with 2 of the triangle vertices. Do I miss something conceptually?

from compas.geometry import Point, Polyline, Rotation
from compas_plotters import Plotter
from numpy import math

xaxis, yaxis, zaxis = [1, 0, 0], [0, 1, 0], [0, 0, 1]
a = Point(0,0)
b = Point(1,0)
pl1 = Polyline([a,b])
R = Rotation.from_axis_and_angle(zaxis,math.radians(120))
pl2 = pl1.transformed(R)
R = Rotation.from_axis_and_angle(zaxis,math.radians(240))
pl3 = pl1.transformed(R)
plotter = Plotter()
plotter.add(pl1,draw_points=False)
plotter.add(pl2,draw_points=False)
plotter.add(pl3,draw_points=False)

pl4 = Polyline([[pl1[1].x,pl1[1].y],[pl2[1].x,pl2[1].y]])
pl5 = Polyline([[pl2[1].x,pl2[1].y],[pl3[1].x,pl3[1].y]])
pl6 = Polyline([[pl3[1].x,pl3[1].y],[pl1[1].x,pl1[1].y]])
plotter.add(pl4,draw_points=False)
plotter.add(pl5,draw_points=False)
plotter.add(pl6,draw_points=False)

R = Rotation.from_axis_and_angle([0,0,1],math.radians(270),[pl4[0].x,pl4[0].y,1])
pl7 = pl4.transformed(R)
R = Rotation.from_axis_and_angle([0,0,1],math.radians(270),[pl7[1].x,pl7[1].y,1])
pl8 = pl7.transformed(R)
R = Rotation.from_axis_and_angle([0,0,1],math.radians(270),[pl8[0].x,pl8[0].y,1])
pl9 = pl8.transformed(R)
plotter.add(pl7,draw_points=False)
plotter.add(pl8,draw_points=False)
plotter.add(pl9,draw_points=False)
plotter.show()

print(pl4)
Polyline([Point(1.000, 0.000, 0.000), Point(-0.500, 0.866, 0.000)])
print(pl9)
Polyline([Point(0.366, 2.366, 0.000), Point(-0.500, 0.866, 0.000)])
print(pl4[1].x,pl9[1].x)
-0.4999999999999998 -0.5
print(pl4[1].x==pl9[1].x)
False
print(pl8[0].x,pl9[0].x)
0.36602540378443976 0.3660254037844397
print(pl8[0].x==pl9[0].x)
False
print(pl8[1].x,pl7[1].x)
1.866025403784439 1.866025403784439
print(pl8[1].x==pl7[1].x)
True
print(pl4[0].x,pl7[0].x)
1.0 1.0
print(pl4[0].x==pl7[0].x)
True

For me it is looking like a bug in the Compas Geometry transform rotate routine. I tried the same with the shapely package, with this it is working, no gaps are occuring, see code below.

from shapely.geometry import Point, LinearRing
from shapely import affinity
import numpy as np
import matplotlib.pyplot as plt


def create_linear_ring(point_1, point_2, n):
    points = [point_1, point_2]
    for k in range(1, n-1):
        points.append(affinity.rotate(points[k-1], 180 - 360/n, origin=points[k]))
    ring = LinearRing(points)
    return ring

rings_series = range(3, 7)
rings = []

# create triangle
a = Point(2 / 3 * 0.5 * 1.0 * 3**0.5, 0)
b = Point(-1 / 3 * 0.5 * 1.0 * 3**0.5, 0.5)
c = Point(-1 / 3 * 0.5 * 1.0 * 3**0.5, -0.5)
print(a, b, c)
ring = LinearRing([a, b, c])
print(ring)
rings.append(ring)
x, y = ring.xy
plt.plot(x, y)

# create square
ring = create_linear_ring(Point(rings[0].coords[0]), Point(rings[0].coords[1]), n=rings_series[1])
rings.append(ring)
x, y = ring.xy
plt.plot(x, y)

# create pentagon
ring = create_linear_ring(Point(rings[0].coords[1]), Point(rings[0].coords[2]), n=rings_series[2])
rings.append(ring)
x, y = ring.xy
plt.plot(x, y)

#create hexagon
ring = create_linear_ring(Point(rings[0].coords[2]), Point(rings[0].coords[3]), n=rings_series[3])
rings.append(ring)
x, y = ring.xy
plt.plot(x, y)

plt.axis('square')
plt.show()

compas2

hi,

sorry for the late response.

thanks for the investigation :slight_smile:
i will look into this asap and let you know what i find…

tom

sorry for the delay…

a few things.

  1. the “gap” in the drawing might be related to how we draw stuff. you can zoom in as far as you like, you will see that there is no real gap.

  1. the shapely example is slightly different than the original one. if i do the same but with compas i get the same result as the one you posted.
from compas.geometry import Point, Polygon, Rotation
from compas.colors import Color
from compas_plotters import Plotter
from numpy import math


def create_linear_ring(a, b, n):
    points = [a, b]
    for k in range(1, n - 1):
        R = Rotation.from_axis_and_angle(
            [0, 0, 1], math.radians(180 - 360 / n), point=points[k]
        )
        points.append(points[k - 1].transformed(R))
    ring = Polygon(points)
    return ring


rings = []

# create triangle
a = Point(2 / 3 * 0.5 * 1.0 * 3**0.5, 0)
b = Point(-1 / 3 * 0.5 * 1.0 * 3**0.5, 0.5)
c = Point(-1 / 3 * 0.5 * 1.0 * 3**0.5, -0.5)
ring = Polygon([a, b, c])
rings.append(ring)

# create square
ring = create_linear_ring(a, b, n=4)
rings.append(ring)

# create pentagon
ring = create_linear_ring(b, c, n=5)
rings.append(ring)

# create hexagon
ring = create_linear_ring(c, a, n=6)
rings.append(ring)

# plotter
plotter = Plotter()
plotter.add(rings[0])
plotter.add(rings[1], edgecolor=Color.orange(), linewidth=1.0)
plotter.add(rings[2], edgecolor=Color.green(), linewidth=1.0)
plotter.add(rings[3], edgecolor=Color.red(), linewidth=1.0)
plotter.zoom_extents()
plotter.show()

  1. the mismatch between the points in the comparison of example 1 is in the order of 1e-17, which is to be expected when working with floats. it is not clear from you comparison if this is any different with shapely since the comparison was largely based on the visual inspection of the two plots.

so i don’t really see an issue, but happy to investigate and discuss this further :slight_smile: