Best way to draw a segmented donut
1 Attachment(s)
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 |
1 Attachment(s)
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.)
|
1 Attachment(s)
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 [/CODE] |
2 Attachment(s)
For an existing tool, download [URL="http://graffletopia.com/stencils/859"]this stencil[/URL]
and set [I]head=false[/I], [I]tail=false[/I] [I](h=false, t=false)[/I] to remove arrowheads from the block arcs. [IMG]http://forums.omnigroup.com/attachment.php?attachmentid=2507&stc=1&d=1345895374[/IMG] [IMG]http://forums.omnigroup.com/attachment.php?attachmentid=2506&stc=1&d=1345891189[/IMG] |
All times are GMT -8. The time now is 08:53 PM. |
Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2024, vBulletin Solutions, Inc.