Finding Angle of Rotation on Randomly Rotated Shape

Hi there everyone

So to preface Iâ€™m working entirely within RhinoPython and Iâ€™m attempting to align custom created randomly rotated shapes. To do this Iâ€™m trying to calculate the angle of rotation. One method Iâ€™ve been trying to implement involves; calculating the centroid of an object, then finding the point furthest from the centroid and using those two points to calculate the angle. But as of yet I havenâ€™t been able to find a way to access the points of the custom shape (without resorting to RhinoScript to get them).

For testing Iâ€™m using the AddRectangle() method to create a shape of random size.

e.g. rs.AddRectangle(plane, size, size * 3) // Size being a random int

I would then add a planar surface to the shape and calculate the surfaceâ€™s centroid.

But then I hit a snag in attempting to calculate a point to use to calculate the angle of rotation. Iâ€™ve done exhaustive research trying to find a function or anything to help me access the attributes of the rectangle or find the point through some other means but Iâ€™ve come up dry.

Iâ€™m not sure if my logic is incorrect or Iâ€™ve overlooked some function that has done exactly what Iâ€™m wanting. If anyone would help me get on the right path with this, it would be greatly appreciated!

Cheers!

Update:

So Iâ€™ve gone back and tried it again. This time iâ€™ve created two methods.

The first finds the furthest point of a rectangle (which I understand is all the points because they are equal, the rectangle is just a test shape). Hereâ€™s the code:

``` def findFarPt(shape): ```

``````# Gets the array of points from the shape
pointArr = rs.PolylineVertices(shape, 0)
arrLen = len(pointArr)

i = 0

# Holds the largest distance and index of point in array
dist = [0,0]
origin = [0,0,0]

while(i < arrLen):
# Checks the distance of the current Point2D against the origin point
# to see if has the greatest distance between the centroid
if(dist[0] < rs.Distance(origin, [pointArr[i][0],pointArr[i][1],0])):
# Assign the new greatest distance
dist[0] = rs.Distance(origin, [pointArr[i][0],pointArr[i][1],0])
# Assign the index of the Point2D
dist[1] = i
i+=1
print "Farthest Point: (Dist: ", dist[0], ") ", pointArr[dist[1]]

# Returns point with the greatest distance
return pointArr[dist[1]]
``````
``` ```

The second code block attempts to find the angle of rotation. This is based on two factors: The centroid (When the shape is centred the co-ordinates are [0,0,0]) and the point furthest away from the centroid. Hereâ€™s the second block:

``` def calcRotation(farPt): ```

``````# Calculate angle of rotation in Radians
# Rotation = atan(x1 - x2 / y1 - y2)
rotationRad = math.atan((0 - farPt[0]) / (0 - farPt[1]));

# If negative rotation, adjust angle
if(rotationDeg < 0):
rotationDeg += 180
print "Rotation Deg: ", rotationDeg

return rotationDeg
``````
``` ```

My problem now is the rotation angle (in degrees) is wrong and when I rotate the rectangle, it doesnâ€™t rotate back to an upright position.

E.g. The desired orientation of the rectangle is:

|||||
|||||
|||||
|||||

Again, thank you guys so much for your time

Iâ€™m not sure I understand - you want to get the vertices of the rectangle without going through rs.PolylineVertices(), rs.CurvePoints() or something similar? You want to do this via RhinoCommon? Or is there something else you would like to do that I didnâ€™t getâ€¦

â€“Mitch

RS should have an areacentroid method, either an all encompassing version or ones that will work on planar surfaces or planar curves solely.

I like the algorithm idea, should work for all sorts of shapes from lines to polysurfaces.

Doh! Thanks so much @Helvetosaur and @Ncik for the reply. I mustnâ€™t have searched very hard since I hadnâ€™t come across rs.PolylineVertices() which should have been immediately apparent to me thatâ€™s what I wanted.

Now Iâ€™ve run myself into a few more problems. Iâ€™ll update my original post.