Paul van Schalkwyk
Paul van Schalkwyk

Reputation: 41

Dividing circumference into equal parts and returning coordinates

I have created several circles with different origins using Python and I am trying to implement a function that will divide each circle into n number of equal parts along the circumference. I am trying to populate an array that contains the starting [x,y] coordinate for each part on the circumference.

My code is as follows:

def fnCalculateArcCoordinates(self,intButtonCount,radius,center):
        lstButtonCoord = []

        #for degrees in range(0,360,intAngle):
        for arc in range(1,intButtonCount + 1):
            degrees = arc * 360 / intButtonCount
            xDegreesCoord = int(center[0] + radius * math.cos(math.radians(degrees)))
            yDegreesCoord = int(center[1] + radius * math.sin(math.radians(degrees)))

            lstButtonCoord.append([xDegreesCoord,yDegreesCoord])
        
        return lstButtonCoord

When I run the code for 3 parts, an example of the set of coordinates that are returned are:

[[157, 214], [157, 85], [270, 149]]

This means the segments are of different sizes. Could someone please help me identify where my error is?

Upvotes: 0

Views: 1024

Answers (1)

user2390182
user2390182

Reputation: 73450

The exact results of such trigonometric calculations are rarely exact integers. By flooring them to int, you lose some precision, of course. The approximate (Pythagorean) distance checks suggest that your math is correct:

(270-157)**2 + (149-85)**2
# 16865
(270-157)**2 + (214-149)**2
# 16994
(157-157)**2 + (214-85)**2
# 16641

Furthermore, you can use the built-in complex number type and the cmath module. In particular cmath.rect converts polar coordinates (a radius and an angle) into rectangular coordinates:

import cmath

def calc(count, radius, center):
    x, y = center
    for i in range(count):
        r = cmath.rect(radius, (2*cmath.pi)*(i/count))
        yield [round(x+r.real, 2), round(y+r.imag, 2)]

list(calc(4, 2, [0, 0]))
# [[2.0, 0.0], [0.0, 2.0], [-2.0, 0.0], [-0.0, -2.0]]
list(calc(6, 1, [0, 0]))
# [[1.0, 0.0], [0.5, 0.87], [-0.5, 0.87], [-1.0, 0.0], [-0.5, -0.87], [0.5, -0.87]]

You want to change rounding as you see fit.

Upvotes: 2

Related Questions