Position shapes in a circle

Friday’s fun with Pixelmator Pro or basic math to position a shapes.

Regards.

use AppleScript version "2.4"
use framework "JavaScriptCore"

--~~~~~~~~~~~~~~~~~~~~~~~
property shapeAmount : 8
property shapeGap : 100
property shapeWidth : 25
property shapeHeight : 25
-- property xOrigin : 1000
-- property yOrigin : 1000
--~~~~~~~~~~~~~~~~~~~~~~~

set shapeSize to {shapeWidth, shapeHeight}
my circleOfShapesAt:{512, 512} shapeSize:shapeSize shapeAmount:shapeAmount shapeType:"rect"
my circleOfShapesAt:{1024, 512} shapeSize:shapeSize shapeAmount:shapeAmount shapeType:"ellipse"
my circleOfShapesAt:{1536, 512} shapeSize:shapeSize shapeAmount:shapeAmount shapeType:"star"
my circleOfShapesAt:{2048, 512} shapeSize:shapeSize shapeAmount:shapeAmount shapeType:"polygon"

on circleOfShapesAt:_shapeOrigin shapeSize:_shapeSize shapeAmount:_shapeAmount shapeType:_shapeString
	repeat with i from 1 to _shapeAmount
		set tAngle to (i * (360 / _shapeAmount))
		set tRadians to tAngle * (2 * pi) / 360
		
		set {xOrigin, yOrigin} to _shapeOrigin
		set xCentre to xOrigin + shapeGap * (doJsMath("cos", (tRadians)))
		set yCentre to yOrigin + shapeGap * (doJsMath("sin", (tRadians)))
		
		set xPos to xCentre
		set yPos to yCentre
		
		-- Make new shape code with position x, y and width and height
		if (_shapeString = "rect") then
			set makeShape to (my makeShapeRect:{xPos, yPos} shapeSize:_shapeSize)
		end if
		if (_shapeString = "ellipse") then
			set makeShape to (my makeShapeEllipse:{xPos, yPos} shapeSize:_shapeSize)
		end if
		if (_shapeString = "polygon") then
			set makeShape to (my makeShapePolygon:{xPos, yPos} shapeSize:_shapeSize)
		end if
		if (_shapeString = "star") then
			set makeShape to (my makeShapeStar:{xPos, yPos} shapeSize:_shapeSize)
		end if
	end repeat
end circleOfShapesAt:shapeSize:shapeAmount:shapeType:

on makeShapeRect:_Pos shapeSize:_Size
	tell application "Pixelmator Pro"
		set {theWidth, theHeight} to _Size
		tell front document
			set theProperties to {position:_Pos, width:theWidth, height:theHeight}
			make new rectangle shape layer at the beginning of layers with properties theProperties
		end tell
	end tell
end makeShapeRect:shapeSize:

on makeShapeEllipse:_Pos shapeSize:_Size
	tell application "Pixelmator Pro"
		set {theWidth, theHeight} to _Size
		tell front document
			set theProperties to {position:_Pos, width:theWidth, height:theHeight}
			make new ellipse shape layer at the beginning of layers with properties theProperties
		end tell
	end tell
end makeShapeEllipse:shapeSize:

on makeShapePolygon:_Pos shapeSize:_Size
	tell application "Pixelmator Pro"
		set {theWidth, theHeight} to _Size
		tell front document
			set theProperties to {position:_Pos, width:theWidth, height:theHeight}
			make new polygon shape layer at the beginning of layers with properties theProperties
		end tell
	end tell
end makeShapePolygon:shapeSize:


on makeShapeStar:_Pos shapeSize:_Size
	tell application "Pixelmator Pro"
		set {theWidth, theHeight} to _Size
		tell front document
			set theProperties to {position:_Pos, width:theWidth, height:theHeight}
			make new star shape layer at the beginning of layers with properties theProperties
		end tell
	end tell
end makeShapeStar:shapeSize:

on doJsMath(theMethod, argsList)
	if class of argsList is not list then set argsList to {argsList}
	set theContext to current application's JSContext's new()
	set theMathObject to theContext's objectForKeyedSubscript:"Math"
	return (theMathObject's invokeMethod:theMethod withArguments:argsList)'s toDouble()
end doJsMath
1 Like

UPDATED: Include GKShuffledDistribution method from GameplayKit framework.

use AppleScript version "2.4"
use framework "JavaScriptCore"
use framework "GameplayKit"

--~~~~~~~~~~~~~~~~~~~~~~~
property shapeAmount : 8
property shapeGap : 150
property shapeWidth : 100
property shapeHeight : 100
-- property xOrigin : 1000
-- property yOrigin : 1000
--~~~~~~~~~~~~~~~~~~~~~~~

set shapeSize to {shapeWidth, shapeHeight}

my circleOfShapesAt:{512, 512} shapeSize:shapeSize shapeAmount:shapeAmount shapeGap:shapeGap shapeType:"rect"
my circleOfShapesAt:{1024, 512} shapeSize:shapeSize shapeAmount:shapeAmount shapeGap:shapeGap shapeType:"ellipse"
my circleOfShapesAt:{1536, 512} shapeSize:shapeSize shapeAmount:shapeAmount shapeGap:shapeGap shapeType:"star"
my circleOfShapesAt:{2048, 512} shapeSize:shapeSize shapeAmount:shapeAmount shapeGap:shapeGap shapeType:"polygon"

on circleOfShapesAt:_shapeOrigin shapeSize:_shapeSize shapeAmount:_shapeAmount shapeGap:_shapeGap shapeType:_shapeString
	repeat with i from 1 to _shapeAmount
		set tAngle to (i * (360 / _shapeAmount))
		set tRadians to tAngle * pi / 180
		
		set {xOrigin, yOrigin} to _shapeOrigin
		
		set xCentre to xOrigin + _shapeGap * (doJsMath("cos", (tRadians)))
		set yCentre to yOrigin + _shapeGap * (doJsMath("sin", (tRadians)))
		
		set xPos to xCentre
		set yPos to yCentre
		
		-- Make new shape code with position x, y and width and height
		if (_shapeString = "rect") then
			set makeShape to (my makeShapeRect:{xPos, yPos} shapeSize:_shapeSize)
		end if
		if (_shapeString = "ellipse") then
			set makeShape to (my makeShapeEllipse:{xPos, yPos} shapeSize:_shapeSize)
		end if
		if (_shapeString = "polygon") then
			set makeShape to (my makeShapePolygon:{xPos, yPos} shapeSize:_shapeSize)
		end if
		if (_shapeString = "star") then
			set makeShape to (my makeShapeStar:{xPos, yPos} shapeSize:_shapeSize)
		end if
	end repeat
end circleOfShapesAt:shapeSize:shapeAmount:shapeGap:shapeType:

on makeShapeRect:_Pos shapeSize:_Size
	tell application "Pixelmator Pro"
		set {theWidth, theHeight} to _Size
		tell front document
			set theProperties to {position:_Pos, width:theWidth, height:theHeight, rotation:my randomMinMax(1, 360)}
			make new rectangle shape layer at the beginning of layers with properties theProperties
		end tell
	end tell
end makeShapeRect:shapeSize:

on makeShapeEllipse:_Pos shapeSize:_Size
	tell application "Pixelmator Pro"
		set {theWidth, theHeight} to _Size
		tell front document
			set theProperties to {position:_Pos, width:theWidth, height:theHeight}
			make new ellipse shape layer at the beginning of layers with properties theProperties
		end tell
	end tell
end makeShapeEllipse:shapeSize:

on makeShapePolygon:_Pos shapeSize:_Size
	tell application "Pixelmator Pro"
		set {theWidth, theHeight} to _Size
		tell front document
			set theProperties to {position:_Pos, width:theWidth, height:theHeight, rotation:my randomMinMax(1, 360)}
			make new polygon shape layer at the beginning of layers with properties theProperties
		end tell
	end tell
end makeShapePolygon:shapeSize:

on makeShapeStar:_Pos shapeSize:_Size
	tell application "Pixelmator Pro"
		set {theWidth, theHeight} to _Size
		tell front document
			set theProperties to {position:_Pos, width:theWidth, height:theHeight, rotation:my randomMinMax(1, 360)}
			make new star shape layer at the beginning of layers with properties theProperties
		end tell
	end tell
end makeShapeStar:shapeSize:

on randomMinMax(_min, _max)
	set randomSource to current application's GKRandomSource's alloc()'s init()
	set dist to current application's GKShuffledDistribution's alloc()'s initWithRandomSource:randomSource lowestValue:(_min as integer) highestValue:(_max as integer)
	return (dist's nextInt()) as integer
end randomMinMax

on doJsMath(theMethod, argsList)
	if class of argsList is not list then set argsList to {argsList}
	set theContext to current application's JSContext's new()
	set theMathObject to theContext's objectForKeyedSubscript:"Math"
	return (theMathObject's invokeMethod:theMethod withArguments:argsList)'s toDouble()
end doJsMath