The Omni Group
These forums are now read-only. Please visit our new forums to participate in discussion. A new account will be required to post in the new forums. For more info on the switch, see this post. Thank you!

Go Back   The Omni Group Forums > OmniGraffle > OmniGraffle General
FAQ Members List Calendar Search Today's Posts Mark Forums Read

 
Best way to draw a segmented donut Thread Tools Search this Thread Display Modes
Hi, I would like to draw a segmented donut similar to the attached image.

Any advice ? Or a stencil that exists ?

Thanks

--

Sorry ignore that found a similar link after more searching
Attached Thumbnails
Click image for larger version

Name:	Safari.png
Views:	634
Size:	89.6 KB
ID:	2502  

Last edited by gberks; 2012-08-24 at 01:50 PM..
 
It's not an easy object to draw in OmniGraffle. The adjustable wedge shape can be used to do this, along with a circle in the middle. (See attached screenshot for a crude example.)
Attached Thumbnails
Click image for larger version

Name:	Screen Shot 2012-08-24 at 5.14.12 PM.png
Views:	634
Size:	102.5 KB
ID:	2503  
 
A sample of the kind of code you could use to build a tool, if this was a regular requirement.

Code:
property plstBlockArrowLineColor : {34081, 38505, 51776}
property pPointsPerDeg : 0.25

property plstCentre : {300, 300}
property plstSize : {200, 200}

property pSegments : 5

tell application id "OGfl"
	
	set oWin to front window
	set oCanvas to canvas of oWin
	
	-- Create a circle
	set {rLeft, rTop} to plstCentre
	set {rWidth, rHeight} to plstSize
	set rRadius to rWidth / 2
	tell oCanvas
		set oCentre to make new shape with properties {name:"Circle", size:plstSize, origin:{rLeft - rRadius, rTop - rRadius}}
		
		set lngParts to pSegments
		set rTheta to 0
		set rDelta to 360 / lngParts
		repeat with i from 1 to lngParts
			set oBlock to my BlockArc(plstCentre, rRadius * 1.5, rTheta, rDelta, rRadius, it)
			set rTheta to rTheta + rDelta
		end repeat
	end tell
	tell oWin
		set selection to {oBlock}
	end tell
	
	--activate
	--tell application id "sevs" to click (my GetMenuItem("OGfl", {"Edit", "Shapes", "Make Custom Shape"}))
	--set strArcName to name of oBlock
	--tell oCanvas
	--	set oNewBlock to duplicate oBlock to end of graphics
	--end tell
end tell


on BlockArc({rX, rY}, rRadius, rFromArc, rArcSize, rWidth, oCanvas)
	return MakeArc(true, {rX, rY}, rRadius, rFromArc, (rFromArc + rArcSize), rWidth, pPointsPerDeg, false, false, oCanvas)
end BlockArc


-- CENTER, RADIUS, FROM DEGREES, TO DEGREES, WIDTH, 
-- BEZIER POINTS PER DEGREE OF ARC, HEAD ARROW, TAIL ARROW
on MakeArc(pblnBlockArrow, {rX, rY}, rRadius, rFrom, rTo, rWidth, rPointsPerDegree, blnHeadArrow, blnTailArrow, oCanvas)
	-- (CURRENTLY A SIMPLE FUNCTION OF THE ARROW WIDTH)
	set {rStart, rEnd} to {rFrom, rTo}
	
	if pblnBlockArrow then
		-- CALCULATE THE LENGTH OF ANY ARROWS 
		if (blnHeadArrow or blnTailArrow) then
			set rArrow to (rWidth / (pi * rRadius)) * 180
			if blnHeadArrow then set rEnd to rTo - rArrow
			if blnTailArrow then set rStart to rFrom + rArrow
		end if
	end if
	
	-- AND THE AMOUNT OF ARC WHICH IT TRAVELS
	set rArc to rEnd - rStart
	if rArc < 0 then set rArc to (rEnd + 360) - rStart
	
	-- HOW MANY POINTS WILL WE USE TO DRAW THE SHAFT ?
	set lngPoints to (rArc * rPointsPerDegree) as integer
	if lngPoints > 0 then
		set rDelta to rArc / lngPoints
		
		if pblnBlockArrow then
			set oGraphic to BlockArrow(oCanvas, {rX, rY}, rFrom, rTo, rStart, rEnd, rDelta, lngPoints, rWidth, blnHeadArrow, blnTailArrow, rRadius)
		else
			set oGraphic to ArcArrow(oCanvas, {rX, rY}, rFrom, rTo, rDelta, lngPoints, blnHeadArrow, blnTailArrow, rRadius)
		end if
		
		return oGraphic
	else
		return missing value
	end if
end MakeArc


on BlockArrow(oCanvas, {rX, rY}, rFrom, rTo, rStart, rEnd, rDelta, lngPoints, rWidth, blnHeadArrow, blnTailArrow, rRadius)
	
	-- GET THE INNER AND OUTER RADII OF THE BLOCK ARROW
	set rW to rWidth / 2
	set {rRadOut, rRadin} to {rRadius + rW, rRadius - rW}
	
	-- COLLECT THE POINTS FOR THE OUTER AND INNER FLANKS OF THE ARROW
	set {lstOuter, lstInner} to {{}, {}}
	set rTheta to rStart
	repeat with i from 1 to lngPoints
		set {dX, dY} to {sin(rTheta), cos(rTheta)}
		set end of lstOuter to {rX + (rRadOut * dX), rY - rRadOut * dY}
		set end of lstInner to {rX + (rRadin * dX), rY - rRadin * dY}
		set rTheta to rTheta + rDelta
	end repeat
	set {dX, dY} to {sin(rTheta), cos(rTheta)}
	set end of lstOuter to {rX + (rRadOut * dX), rY - rRadOut * dY}
	set end of lstInner to {rX + (rRadin * dX), rY - rRadin * dY}
	
	-- MAKE HEAD AND/OR TAIL ARROWS IF REQUIRED
	set {lstHead, lstTail} to {{}, {}}
	set {rInnerBarb, rOuterBarb} to {rRadius - rWidth, rRadius + rWidth}
	-- TAIL ARROW ?
	if blnTailArrow then
		-- inner barb, tip, outer barb
		set lstTail to {{rX + (rInnerBarb * (sin(rStart))), rY - rInnerBarb * (cos(rStart))}, ¬
			{rX + (rRadius * (sin(rFrom))), rY - rRadius * (cos(rFrom))}, ¬
			{rX + (rOuterBarb * (sin(rStart))), rY - rOuterBarb * (cos(rStart))}}
	end if
	-- HEAD ARROW ?
	if blnHeadArrow then
		set lstHead to {{rX + (rOuterBarb * (sin(rEnd))), rY - rOuterBarb * (cos(rEnd))}, ¬
			{rX + (rRadius * (sin(rTo))), rY - rRadius * (cos(rTo))}, ¬
			{rX + (rInnerBarb * (sin(rEnd))), rY - rInnerBarb * (cos(rEnd))}}
	end if
	
	-- JOIN THE SHAFT TO ANY ARROW TIPS
	set lstPoints to (lstOuter & lstHead & reverse of lstInner & lstTail)
	
	-- GATHER THE POINTS IN THE TRIPLET FORMAT EXPECTED FOR CUSTOM SHAPES
	set oFirstPoint to item 1 of lstPoints
	set lstBezier to {oFirstPoint, oFirstPoint}
	repeat with i from 2 to length of lstPoints
		set oPoint to item i of lstPoints
		set lstBezier to lstBezier & {oPoint, oPoint, oPoint}
	end repeat
	set end of lstBezier to oFirstPoint
	
	-- AND RETURN A CUSTOM SHAPE
	tell application id "OGfl"
		tell oCanvas to set oShape to make new shape with properties {point list:lstBezier, draws stroke:true, stroke color:plstBlockArrowLineColor}
		set notes of oShape to "From " & rFrom & "º" & return & "To " & rTo & "º"
	end tell
	return oShape
end BlockArrow

on GetRadPoint({rX, rY}, rRadius, rTheta)
	{rX + (rRadius * (sin(rTheta))), rY - rRadius * (cos(rTheta))}
end GetRadPoint

-- RETURNS A REFERENCE TO A CLICKABLE MENU ITEM
-- E.G. set mnuZoomFit to GetMenuItem("OGfl", {"View", "Zoom", "Zoom to Selection"})
on GetMenuItem(strAppCode, lstMenu)
	set lngChain to length of lstMenu
	if lngChain < 2 then return missing value
	
	tell application id "sevs"
		set lstApps to every application process where its creator type = strAppCode
		if length of lstApps < 1 then return missing value
		tell first item of lstApps
			-- GET THE TOP LEVEL MENU
			set strMenu to item 1 of lstMenu
			set oMenu to menu strMenu of menu bar item strMenu of menu bar 1
			
			-- TRAVEL DOWN THROUGH ANY SUB-MENUS
			repeat with i from 2 to (lngChain - 1)
				set strMenu to item i of lstMenu
				set oMenu to menu strMenu of menu item strMenu of oMenu
			end repeat
			
			-- AND RETURN THE FINAL MENU ITEM
			return menu item (item -1 of lstMenu) of oMenu
		end tell
	end tell
end GetMenuItem

-- BASIC TRIG FUNCTIONS PUBLISHED BY OTHERS
-- COULD USE THE KSH SHELL, BUT THESE ARE PROBABLY FASTER ...

-- Trig functions from:
-- http://lists.apple.com/archives/applescript-users/2004/Feb/msg00939.html

on cos(x) -- degrees
	local myCos, numerator, denominator, factor
	
	set myCos to 0
	if (x = 90) or (x = 270) then
		set myCos to 0
	else
		set x to (x - (((x / 360) div 1) * 360)) * (pi / 180)
		set {myCos, numerator, denominator, factor} to {0, 1, 1, -(x ^ 2)}
		repeat with i from 2 to 40 by 2
			set myCos to myCos + numerator / denominator
			set numerator to numerator * factor
			set denominator to denominator * i * (i - 1)
		end repeat
	end if
	return myCos
end cos
-- 
-- ----------------------------
on sin(x) -- degrees
	local mySin, numerator, denomintator, factor
	
	set mySin to 0
	if (x = 180) or (x = 360) then
		set mySin to 0
	else
		set x to (x - (((x / 360) div 1) * 360)) * (pi / 180)
		set {mySin, numerator, denominator, factor} to {0, x, 1, -(x ^ 2)}
		repeat with i from 3 to 40 by 2
			set mySin to mySin + numerator / denominator
			set numerator to numerator * factor
			set denominator to denominator * i * (i - 1)
		end repeat
	end if
	return mySin
end sin
Attached Thumbnails
Click image for larger version

Name:	Screen Shot 2012-08-25 at 11.31.16.png
Views:	580
Size:	29.0 KB
ID:	2504  
 
For an existing tool, download this stencil

and set head=false, tail=false (h=false, t=false) to remove arrowheads from the block arcs.



Attached Thumbnails
Click image for larger version

Name:	Screen Shot 2012-08-25 at 11.39.13.png
Views:	1635
Size:	68.8 KB
ID:	2506   Click image for larger version

Name:	Screen Shot 2012-08-25 at 12.47.49.png
Views:	1588
Size:	44.3 KB
ID:	2507  

Last edited by RobTrew; 2012-08-25 at 03:49 AM..
 
 


Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes


Similar Threads
Thread Thread Starter Forum Replies Last Post
Can't draw a line ??? Rodney OmniGraffle General 5 2011-10-15 10:03 AM
Help - Drawing segmented circle. Simon Knight OmniGraffle General 4 2011-04-15 09:11 AM
I just want to draw a line!?! joeworkman OmniGraffle General 3 2008-03-10 11:30 AM


All times are GMT -8. The time now is 03:53 AM.


Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2024, vBulletin Solutions, Inc.