thinking inside the box: converting scalable vector ...trdata/reports/tr2018-856.pdf · electron...
TRANSCRIPT
1
ThinkingInsidetheBox:
ConvertingScalableVector
GraphicstoEncapsulated
PostScript
DartmouthComputerScienceTechnicalReportTR2018-856ByTrevorDavis
2 Davis
2
TableofContents1.Introduction............................................................................................................31.1.Background..........................................................................................................................................................31.2.PrimaryTasks.....................................................................................................................................................41.3.OtherTasks..........................................................................................................................................................4
2.DesignDecisions,Frameworks,andLibraries...........................................................52.1.ChoiceofProgrammingLanguages...........................................................................................................62.3.TheElectronFramework...............................................................................................................................72.3.ReactandRedux................................................................................................................................................82.4.ScalableVectorGraphics.............................................................................................................................102.5.AdditionalLibraries......................................................................................................................................113.RenderingShapes...................................................................................................123.1.ANoteonPostScript.....................................................................................................................................123.2.DartDraw’sExportLandingPoint...........................................................................................................123.3.Line-BasedShapes.........................................................................................................................................143.4.Ellipses................................................................................................................................................................213.5.Arcs.......................................................................................................................................................................243.6.RoundedRectangles......................................................................................................................................263.7.BezierCurves...................................................................................................................................................273.7.Text.......................................................................................................................................................................28
4.ComputingBoundingBoxes....................................................................................314.1.TheBoundingBoxObject............................................................................................................................314.2.LinesandFreehandPaths...........................................................................................................................324.3.Rectangles..........................................................................................................................................................344.4.Polygons.............................................................................................................................................................354.5.Ellipses................................................................................................................................................................374.6.Arcs.......................................................................................................................................................................394.7.RoundedRectangles......................................................................................................................................414.8.BezierCurves...................................................................................................................................................41
5.FileSavingandOpening.........................................................................................415.1.SavingfileswithIPC......................................................................................................................................425.2.Openingfiles.....................................................................................................................................................43
6.FutureWork...........................................................................................................446.1.ComplexShapeIntersection......................................................................................................................446.2.ColorFlattening...............................................................................................................................................456.3.FileCompression............................................................................................................................................46
7.Reflection...............................................................................................................47
8.References.............................................................................................................49
3
1.Introduction
1.1.Background
In1984,avectorgraphicdrawingapplicationcalledMacDrawwasreleasedaspart
ofthefirstAppleMacintoshsystems.Followingitsinitialsuccess,MacDraw
underwentseveraliterationsuntilitbecameClarisDraw1.0v4in1994,which
continuedtofunctiononMacOSXforoveradecade.WhenMacOSX10.5Leopard
debutedinOctober2007,however,itdidnotsupportClassicapplications,including
MacDraw.UsersofIntelbasedMacshavebeenunabletouseMacDrawontheir
machineseversince,promptingacalltocreateacompatibleversionofMacDrawby
theauthorsofIntroductiontoAlgorithms.1
Thecallwentunanswereduntilautumn2017whenProfessorTomCormenof
DartmouthCollegeassignedseveralundergraduatesthetaskofcreatingDartDraw,
areplicaofMacDrawwithafewkeyimprovements.Thesesixundergraduates,
includingmyself,weregivenapproximatelyninemonthstocompletetheirtask,
brokendownintoindividualresponsibilities.
AsoneoftheauthorsofIntroductiontoAlgorithms,Cormenhadpreviouslyused
MacDrawtocreatethefiguresforthebookbyexportingdrawingsfromthedrawing
applicationandembeddingthemwithinhisLaTeXdocuments.Asamemberofthe
1https://en.wikipedia.org/wiki/MacDraw
4 Davis
4
DartDrawteam,mytaskwastohandlethecreationofEPSfilesfromtheDartDraw
application.
1.2.PrimaryTasks
PostScriptisastackbased,proceduralprogramminglanguagecreatedbyAdobefor
pagedescription.PrinterscanprintdirectlyfromPostScriptfiles.Thereisasimilar
filetypeknownasEncapsulatedPostScript(EPS),whichallowsforthumbnail
imagesoftheresultingPDFaswellasadditionalmetadata.Inparticular,everyEPS
filecontainsinformationabouttheenclosingrectangleoftheimagecreatedbythe
filecalledtheBoundingBox.Thisfeatureisparticularlyusefulforcreatingimages
thatcanbeembeddedinotherfilessuchastextdocuments.
Myprimarytaskforthisthesiswastwofold:
• EnableDartDrawtoexportEPSfilesthatdescribetheimagecreatedbya
user.
• EnsurethattheseEPSfilescontainanink-basedboundingboxoftheimage.
Thecoreofthisdocumentdescribesmyworkonthesetwoprimarytasks.
1.3.OtherTasks
InadditiontohandlingtheEPSexportfunctionality;Imanagedtwootherrelated
tasksinthecreationofDartDraw.
5
DartDrawneededafilesaveformatsothatuserscansavedrawingsandreturnto
themlater.WhenwecreatedDartDraw,weleveragedtheReduxpredictablestate
container(seesection2.3),whichtracksthestateofauser’sdrawinginanobject
treecalledthestore.Iusedthestoreasthecoreofastandardfilesaveformatwith
theextension“dart.”
Lastly,Icreatedaninter-processcommunicationcomponentintheReactJS
frameworktohandleeventspassedbetweenthemainprocessandwindow
processesinDartDraw.Seesection5.1formoreinformation.
2.DesignDecisions,Frameworks,andLibraries
CreatinganapplicationlikeDartDrawrequiresanunderstandingofmanyexisting
utilitiesthatmakeaprogrammer’slifeeasier.Intheearlystagesofthisproject,the
DartDrawteamspentaconsiderableamountoftimedecidinguponthebase
structureofourproject.Thesectionsbelowdiscussthebenefitsandtradeoffsofour
decisions.
AnonlineGitHubrepositoryisavailableforamorein-depthlookattheproject.
6 Davis
6
2.1.ChoiceofProgrammingLanguages
Giventheplethoraofprogramminglanguagesthatexisttoday,itwasadaunting
taskforourteamtodecidewhichonetousetocreateDartDraw.Eventually,we
narroweddownourchoicestotwolanguages:SwiftandJavaScript.
SwiftisApple’sproprietaryprogramminglanguagethatisspecificallydesignedfor
easyusewithiOSandOSXapplications.ItworkshandinhandwithObjective-Cand
hasmanycustomlibrariesthatmakethingslikemenuoptionsandstylingtrivialfor
developers.Furthermore,itworkswithApple’sadvancedXcodeIDEthateven
simplifiescertaintaskssuchaslayoutdesigndowntoadrag-and-dropprocedure.
Ontheotherhand,manyundergraduatestudentsdonotknowSwift,andithasa
significantlearningcurve.SwiftisalsoexclusivelyusedforAppleapplications.
JavaScriptbyitselfisprimarilyascriptinglanguageforwebpages,butithas
recentlybecomemoreversatile.Now,librariessuchasReactJSmakeiteasytouse
JavaScriptindesktopapplications.JavaScriptisoneofthemostpopular
programminglanguageswithoneofthefastestgrowinguserbases.Itisfast,multi-
platform,andexpressive.Becauseofitsprevalenceinwebapplications,thereisa
JavaScriptlibraryforvirtuallyeverything.Manyoftheselibrariesresideinthenpm
packageecosystem,anenormouscollectionofJavaScriptlibrariescontrolledbythe
Node.jsJavaScriptruntime(see2.2).
7
Bothoftheseprogramminglanguagespresentexcellentoptionsforapplicationslike
DartDraw,butourprojectteamwasmuchmorefamiliarwithJavaScriptthanSwift,
makingJavaScripttheclearchoiceforalowentrancebarriertothisproject.Asan
addedbonus,theuseofJavaScriptandcertainlibrariesandframeworksdescribed
belowallowedustomakeDartDrawacrossplatformapplication,includingthe
potentialforaweb-basedversionoftheapplication.
2.3.TheElectronFramework
Thegoalofthisprojectwastocreateauserfriendly,vector-based,robustgraphics
desktopapplication.Tothatend,wedidnotwanttospendexcessivetimeworrying
aboutboilerplatecodingforappframes,menus,andthelike.However,werealized
thatourgoalcouldnotberealizedwithoutconsideringhowthesebasiccomponents
affecttheuserexperiences.TheElectronframeworkprovidedasolutiontothis
conflict.
Accordingtoelectronjs.org,“Electronisaframeworkforcreatingnative
applicationswithwebtechnologieslikeJavaScript,HTML,andCSS.Ittakescareof
thehardpartssoyoucanfocusonthecoreofyourapplication.”2Tobemore
specific,ElectronusesChromium,anopen-sourcewebbrowserprojectstartedby
Google.Thebrowserstructureactsasacontainerofsortsforanofflinedesktop
2“Electron|BuildCrossPlatformDesktopAppswithJavaScript,HTML,andCSS.”Electronjs.AccessedMay9,2018.https://electronjs.org/.
8 Davis
8
application.Consequentially,Electron-basedapplicationsarecompatiblewithMac,
Windows,andLinuxoutofthebox.Electronevenhandlesnativemenus.
AkeyfeatureofElectronisitsseparationbetweenthemainprocessandthe
browserprocesses.Creation,manipulation,anddestructionofbrowserprocesses
arehandledfromthemainprocess,whichalsohandlesappstartupandmenu
options.BrowserprocessesaretheparentprocessesforeachwindowofanElectron
application.Importantly,thisallowsourteamtocreateamulti-windowapplication
usingaframeworklikeReactJSthatisintendedforsinglepageapplications.Each
windowofDartDrawishandledasaseparateinstanceoftheapplicationthatis
controlledbythemainprocess.
ElectronrunsontheNode.jsruntime.Asaresult,Electron-basedappscanleverage
theentirebodyofthenpmpackageecosystem,includingtheonesdescribedbelow.
2.3.ReactandRedux
React–oftencalledReactJS–isanopensourceJavaScriptlibraryusedforcreating
interactiveuserinterfaces.ThekeyfeatureofReactJSisitsbreakdowninto
components.Acomponentisrenderedindependentlyaccordingtoinputdataanda
stateforeachcomponent.Eachcomponentcanbefurtherbrokendownintosub
components,whichmeansthatapplicationsbuiltwithReactJSareveryscalable.
Importantly,ReactJScomponentscanrenderaccordingtodeveloper-specifiedrules
andanykindofdatathatispassedthroughtheapp.
9
ReduxisanotheropensourceJavaScriptlibrary,anditisusedtomanagethestateof
theapplication.Reduxstoresthestateofanapplicationinanobjecttreecalledthe
store.SupposeaDartDrawusercreatedadrawingtoexplaintheBreadth-First
Searchalgorithm.Theusermighthaveagraphwithverticesandedges,andthey
mightincludethatgraphseveraltimestodemonstratevariousstagesofthe
algorithm.Itiseasytoimagineanobjecttreewiththedrawingstateattheroot,and
groupsrepresentingthegraphsaschildren.Eachofthegroupswouldhavevertices,
edges,andlabelsaschildren,andeachofthosewouldhavechildrenrepresenting
informationlikedimensions,transformations,andauniqueid.Althoughthisisa
simplifiedexplanationofDartDraw’sReduxstate,itissufficienttoexplainthebasics
oftheinternalstructure.WhentheReduxstateneedstobechanged,anactionis
dispatchedtodoso.Thisideaisexploredfurtherbelow.
AlthoughReactandReduxareseparatelibraries,theyareoftenusedtogether.
ThereisevenanotherJavaScriptlibrarycalledReact-Reduxthatseamlessly
integratesthetwo.ThestateofthedrawingismaintainedbyReduxwhilethe
visualizationofthedrawingishandledbyReact.Whenwewanttochangethe
drawing,weneedtochangeboth.React-Reduxhandlesthiswithitsconnectmodule.
WhenanactionisdispatchedbyReduxtochangetheReduxstate,theconnect
modulemapsthechangingpartsofthestatetoinputoftheappropriateReact
components,therebycausingthemtore-render.
10 Davis
10
Byutilizingthesethreelibrariesinconjunctionwithoneanother,DartDrawonly
changesthepartsoftheinternalstatethatitneedsto.Atthesametime,individual
componentsofthevisualdrawingre-renderindependently.ADartDrawuser
thereforeexperiencesafastandlightweightapplicationthatletsthemchangethe
drawingwithoutanynoticeabledelay.
2.4.ScalableVectorGraphics
BecausetheElectronframeworkisbasedontheChromiumproject,ourappisable
toleverageChromebrowsersupportforrenderingScalableVectorGraphics(SVG),
anXML-basedstandardforrepresentingtwo-dimensionalgraphicsthatwas
adoptedbytheWorldWideWebConsortium.Notably,SVGsupportsinteractivity,
makingitidealforadrawingappwithinaChromiumshell.
InordertoutilizeSVGasourgraphicsstandard,webasedtheinternalstructureof
theReduxstoreonthesamestandard.Inotherwords,theparametersforvarious
SVGshapesandfiguresarethesameastheparametersforDartDrawfiguresinthe
Reduxstore.Whenausermanipulatesashapeusingtheinteractivecomponentsof
SVGsuchasclickordrag,theyalsomanipulatetheshape’srepresentationinthe
Reduxstore,whichinturnre-rendersthecorrespondingReactcomponents.
11
2.5.AdditionalLibraries
Anapplicationofthissizeandcomplexityrequiredthatweavoidreinventingthe
wheelwhenpossible.Asawhole,ourteamusedmanydifferentlibrariesalongwith
React,Redux,andReact-Redux.ForthepurposesofexportingEPSfilesandhandling
inter-processcommunication,Ipersonallyreliedontwodistinctlibraries:
• math.jsisamathlibraryforNode.js.Itscorefunctionsdonotdifferinany
meaningfulwayfromJavaScript’sbuilt-inmathlibraryexceptthatmath.js
allowsforcalculationswitharbitraryprecision.Forcomplexcalculations
involvinglarge,irrational,orcomplexnumbers(e.g.solvingquadratic
equations),math.jsisnotonlyhelpfulbutessentialaswell.
• transformation-matrix-jsis“anaffinetransformationmatrixclassfor
JavaScriptthatperformsvarioussuchasrotate,scale,translate[…]and
convertingtoandfromanSVG/DOMmatrix.”3InDartDraw,thislibraryis
usefulinconvertinguseractionsonshapes(transforms)totransformation
matricesstoredaschildnodesofshapesintheReduxstore.These
transformscanpropagatedownthroughtheshapesintheReduxdrawing
statewhenperformedongroups.Whencomputingboundingboxes,itis
sometimesusefultoworkwithcanonicalformsofshapesbeforeapplyingthe
appropriatetransformsviathislibrary.
3“Transformation-matrix-js.”Npm.AccessedMay11,2018.https://www.npmjs.ocom/package/transformation-matrix-js.
12 Davis
12
3.RenderingShapes
3.1.ANoteonPostScriptAdistinctadvantagewhenitcomestoexportingEPSfilesfromDartDrawisthatEPS
isavectorgraphicsformat,allowingittoeasilyrepresentthescalablevector
graphicsofourapp.EPSalsohastheabilitytodefineproceduresandapply
geometrictransformations.
However,therearenotabledifferencesbetweentherepresentationsoffigures
renderedbyEPSandDartDrawfiguresdescribedintheapplication’sReduxstore.
Mostofthesedifferencesarisefromthestack-basedparadigmofPostScript.All
literalssuchasintegersandfloatsareplacedbythe(Encapsulated)PostScript
interpreteronthestack.PostScriptoperandspoptheirrequirednumberof
argumentsoffofthestackbeforeexecuting.
Section3.2describestheconversionprocessfromReduxrepresentationsofSVGto
figuresrenderedbyEPS.Followingthatsection,theremainderofchapter3
describeshowPostScriptoperandsareusedtorenderthedifferenttypesofshapes
supportedbyDartDraw.
3.2.DartDraw’sExportLandingPoint
TheReactcomponentsthathandlemenuactionsarefoundwithin
DartDraw/src/components.ThefileLeftMenu.jshandlesactionsrelatedtotool
13
selection,shapemanipulation,andexportingEPSfiles.Eachoftheseactionsis
handledbybuttonswithintheLeftMenurendermethod,whichbindsbuttonclicks
tovariousmethodsoftheLeftMenucomponent.
Whentheexportbuttonisclickedbyauser,thegenerateEpsfunctionfrom
DartDraw/src/eps/eps.jsiscalledwiththedrawingstatenodeoftheReduxstoreas
anargument.ThissimplefunctionlooksthroughallfiguresintheReduxstorebyID
andhandlesthepostscriptgenerationforeachfigure.Thenitappendsthegenerated
EPStoanAdobeEPSpresettemplate.ItalsocreatesaninstanceoftheboundingBox
classtocomputetheboundingboxofthetotaldrawing,whichitwritesintothe
Adobepresettemplate.Finally,thefunctioninvokesthesavedialogandsavesthe
aboveinformationtoafilethatisnamedbytheuser.
ForeachfigureinthedrawingstateoftheReduxstore,anewinstanceofthe
epsShapeclassiscreated.Thisclass-foundinDartDraw/src/eps/epsShape.js–is
responsibleforparsingthefiguresandgeneratingthecorrespondingEPS.This
abstractclasscontainsmethodssuchasgetStrokeWidth,getCoords,andproduceEps,
allofwhichareimplementedbythecorrespondingclassesforeachshape.The
produceEpsmethodreturnsEPS,anditiscalledfromwithineps.jstogeneratethe
contentforeachsavedfile.
Shape-specificclassesarediscussedbelow.
14 Davis
14
3.3.Line-BasedShapes
PostScriptwascreatedandisprimarilyusedasastandardforprintingdocuments.
Consequentially,thePostScriptgraphicscommandscanbethoughtofas
descriptionsforapen’smovementonpaper.
Forexample,thePostScriptmovetocommandtakestwoarguments:anxcoordinate
andaycoordinate.Whenthiscommandisexecuted,ittakesthetoptwovaluesoff
ofthestackandtreatsthemastheyvalueandxvalue,respectivelybefore“picking
upthepen”andmovingittothespecifiedlocation.ItisworthnotingthatPostScript
alwayshasanotionofthecurrentlocationrelativetotheoriginofthepageatthe
bottomleft-handcorner,whereastheDartDrawappdescribescoordinatesin
relationtotheoriginatthetopleft-handcorner.
Anothercommandcalledlinetoalsotakesanxcoordinateandaycoordinate.Itputs
thepenonthepageatthecurrentlocationanddrawsastraightlinetothegiven
coordinate.
Thisiswheredrawingcommandssuchaslinetobecomeslightlymorenuanced.Ink
isneverrenderedinPostScript-generateddocumentsunlessthecommandstrokeor
filliscalled.Instead,thePostScriptinterpretermaintainsacurrentpaththatis
unrealizeduntiladrawingcommandiscalled.ThisparticularfeatureofPostScript
allowsDartDrawtocreateseverallineswithamovetocommandandseverallineto
commandsbeforerenderingthemallatoncewiththestrokecommand.
15
Twoothercommandsareworthmentioningbeforediscussingspecificshapes.The
newpathcommandresetsthecurrentpath,afeatureitsharesincommonwiththe
movetocommand.Theclosepathcommanddrawsalineinthecurrentpathfromthe
currentpointtothestartofthecurrentpath.Iftherenderedlinesdonotmakea
cohesiveoutline,PostScriptautomaticallyfillsinthegap.Thiscommandisoften
usedbeforecallingfill.
Thefollowingshapesarerenderedinaverysimilarfashion.Asweshallseein
chapter4,however,theirboundingboxesarerathermorecomplex.
LinesEPSforlinesiscreatedinDartDraw/src/eps/epsLine.js.ThisepsLineobject’s
constructortakesashapeobjectasaparametertotheconstructorandassumesthat
theshapegivenrepresentsaline.Ittakesthefirstpointintheline’spoints attribute
andappliesthepropertransformationsutilizingthetransform-matrix.js libraryand
theline’stransform attribute.Then,itaccountsforthediscrepancybetween
PostScript’scoordinatesystemoriginandDartDraw’scoordinatesystemoriginby
subtractingtheresultingycoordinatesfromtheapplication’scanvasheight.
Afterobtainingtherequiredcoordinates,theproduceEps methodoftheobject
parsesthestrokeattributeofthelinetogetthestrokecolorandtheparsesthe
strokeWidthattributetogetthewidthoftheline.
16 Davis
16
Finally,theproduceEps methodtakesadvantageofJavaScript’stemplatefeaturethat
allowsvariablevaluestobesubstitutedintoastring.ItcreatesanEPSsnippet
similartothefollowing:
0 0 0 setrgbcolor 5 setlinewidth newpath 10 10 moveto 20 20 lineto stroke (Figure1)
Whichwouldcreateablacklinethatis5pointswidefrom(10,10)to(20,20).
RectanglesandPolygonsBothrectanglesandpolygonsarecreatedinthesamemanneraslineswiththree
keydifferences.
First,awrap-aroundloopthroughthesetofpointsinarectangleorgeneralpolygon
allowstheshapeoutlinetobeclosed.
Second,thecommandsshowninFigure1arerepeatedtwice.Inthefirstofthetwo
identicalsections,thesetlinewidthcommandisomittedandthestrokecommandis
replacedwithfill.ThissequencetellsPostScripttorenderthefilloftheshapebefore
overlayingtheoutline.
17
Third,theclosepath commandiscalledaftertheendofeachoftheabovesections.
Whenthelinesdonotformacohesivepath(asinFigure2),PostScriptfillsitin
automatically(asinFigure3).Thoughthedifferenceisslight,wecanseethatthe
upperleft-handcornerofFigure2isnotquiterightbecausethepathisnotclosed.
(Figure2) (Figure3)
Free-HandPathsFree-handpathsarerepresentedasanarrayofverysmalllinesbetweencontrol
points.Theyarerenderedinthesamewayaspolygonsexceptthattheyareneither
closednorfilled.Therefore,thefillandclosepathcommandsarenotused.
ArrowsSVGrepresentsarrowsdifferentlythanitrepresentsothershapes.Whendrawing
anarrowheadonaline,SVGfirstrendersthearrowseparatelyinanabstract
viewingbox,whichisvisualizedinauser-friendlydisplaywithintheDartDraw
application.Afterthearrowisrendered,itisattachedtotheappropriatelineby
connectingamarkeronthearrowheadtoamarkerontheline,thusattachingitand
displayinganarrowinthefrontendgraphics.
18 Davis
18
Renderingarrowsthereforerequiresoneadditionalstepinadditiontothenormal
processofidentifyingandmanipulatingpointsaswithothershapes.
First,wedeterminethearrowhead’sheightandlengtharrowLength andarrowHeight,
whichisamatterofsubtractionofpoints.Inthecaseofbarbedarrowheads,the
arrowheadrepresentationintheReduxstorehasanadditionalpointtoaccountfor
theindentationinthebarbedarrowhead.Weusethispointtocomputeavalue
calledminorLengththatdenotestheEuclidiandistancebetweenthetipofthearrow
andtheintersectionofthelinewiththearrowhead.Thisdistinctionisshownin
Figure4.
(Figure4)
Aftercomputingthesevalues,itisnecessarytoconsiderthelinetowhichthe
arrowheadwillbeattachedinordertocontinuewithrenderingcalculations.First,
supposethatthelineishorizontalandthatthearrowheadispointingtowards(1,0)
ontheunitcircle.Thenwenotethatthetipofthearrowheadisattheendoftheline.
arrowLength
minorLength
19
Wecancallthispoint𝑃!"#.Theothertwopointsonatriangulararrowhead(ortwo
ofthethreeremainingpointsonabarbedarrowhead)requirethatwefirstcompute
anintermediarypoint,whichwecancall𝑃! .Stillassumingthatthelineishorizontal:
𝑃! = (𝑃!"#. 𝑥 − 𝑎𝑟𝑟𝑜𝑤𝐿𝑒𝑛𝑔𝑡ℎ,𝑃!"#.𝑦)
Lastly,theremainingpoints𝑃!and𝑃!arecomputedrelativeto𝑃! .
𝑃! = (𝑃! . 𝑥,𝑃! .𝑦 − 𝑎𝑟𝑟𝑜𝑤𝐻𝑒𝑖𝑔ℎ𝑡)𝑃! = (𝑃! . 𝑥,𝑃! .𝑦 + 𝑎𝑟𝑟𝑜𝑤𝐻𝑒𝑖𝑔ℎ𝑡)
Notethattheonlydifferencebetweenabarbedarrowheadandatriangular
arrowheadisthatabarbedarrowheadhasanadditionalpoint𝑃!,where
𝑃! = (𝑃!"#. 𝑥 −𝑚𝑖𝑛𝑜𝑟𝐿𝑒𝑛𝑔𝑡ℎ,𝑃!"#.𝑦).
Nowwemusttransformthesepointsaccordingtotheactualpositionoftheline.
Fortunately,itiseasytogettheangleofrotation𝜃 ofthelinetowhichthe
arrowheadisattached.Thenweonlyneedtorotatethepointscomputedaboveby
theangle𝜃togettheactualcoordinatesofthearrowhead.
Finally,weuseamoveto commandandmultiple lineto commandstoconnectthese
pointsinthesamewayaswewouldwitharectangleorotherpolygon.Inthecaseof
atriangulararrowhead,theorderofthesepointsis𝑃!"#,𝑃!,𝑃!,and𝑃!"#.Ifwehavea
barbedarrowhead,thentheorderis𝑃!"#,𝑃!,𝑃!,𝑃!,and𝑃!"#.
20 Davis
20
Inthecaseofanarrow“tail”astheyarecalledwithintheapp,weonlyneedtoset𝑃!
equaltothestartingpointoftheline(points0and1intheline’spointsattribute),
computethecoordinatesofthearrow’stiprelativeto𝑃! usingthearrowLength,and
processasabove.
Ifarrowsareflipped(accordingtotheBooleanflipattributeinthearrow’sRedux
state),webegininthesamefashionasabove,swap𝑃! and𝑃!"#,andproceedas
above,keepinginmindthatweneedtoinvertthewaythatwecompute𝑃!,𝑃!,and
𝑃!relativeto𝑃! and𝑃!"#sincethedirectionofthearrowsisflipped.
Whilethelogicaboveisallthatisneededtorenderthearrowheads,wearenot
done.Asitstands,wewouldberenderingarrowheadsonalinewithsomespecified
strokethickness.Ifwedonotalterthelineafterrenderingthearrowheads,thenthe
thicknessofthelinewillcauseitto“pokeout”pastthetipofthearrow.Therefore,
weneedtoalterthepointsattributeofthelinebeforemakingitintoalineobject
thatcanberenderedandinfluencetheboundingboxofthedrawing.
Asluckwouldhaveit,wealreadyhavethepointsthatweneed.Bygettingthe
produceEpsmethodofthearrowclasstoreturnanobjectthatincludesdataabout
thearrow’spointsinadditiontotheEPSthatweneedtoexport,wecanchangethe
linetowhichthearrowisattachedwhenwefirstparsetheshapewithineps/eps.js.
Supposethatwehavealinewithaclassictriangulararrowheadthatisnotflipped.
Thepointatwhichwewantthelinetoendisthepointatwhichthelineandthe
21
arrowheadshapeintersect,whichisofcourse𝑃! .Wecanmakesimilarcomparisons
using𝑃! ,𝑃!"#or𝑃!dependingonwhetherwehaveanarrowheadoranarrow“tail”
andwhetherornottheyareflipped.
Foralinetobemodifiedinthisway,wemustfirstcopytheentiretyoftheoriginal
lineshapeusingDartDraw’sowndeepCopyfunction.Thiswaywecanalterthe
pointsinthecopyandusethattorendertheappropriatelineandaffectthe
boundingbox.Ifweinsteadmodifiedtheoriginallineobjectormodifiedareference
totheoriginalline,itwouldchangethepointsthatthearrowheadusesasreferences
forwheretorenderitself,thuschangingthelocationofthearrowheadandcausing
thesameissueoftheline“stickingout”thatweweretryingtofixinthefirstplace.
Inordertomakesurethatarrowheadsandarrow“tails”arerenderedonthecorrect
lines,eachline’sReduxstatehasfourimportantattributes:arrowHeadId and
arrowTailId,whichdeterminewhicharrowheadswithinthearrowsnodeofthe
Reduxstoretoattachtotheline,and arrowHeadShown and arrowTailShown,which
areBooleanvaluesthatdeterminewhetherornotthearrowheadorarrow“tail”is
renderedandaffectstheboundingboxofthedrawing.
3.4.EllipsesPostScripthasaveryusefulcommandcalledarc thattakesacenterpoint,aradius,a
startingangle,andanendingangleasanargument.Forthemostpart,thiscommand
22 Davis
22
isusefulindrawingcirclesorpartialcircles.However,withacoupleofclever
modifications,itispossibletousethearc commandtodrawgeneralellipses.
ThefirstmodificationthatwemakeistoapplyPostScriptcoordinatesystem
transformations.Thecommandstranslate, rotate,and scale canbeusedtoaffectthe
PostScriptcoordinatesystemasifthepaperbeingdrawnuponwasbeingshifted,
turned,orstretched.
ThesecondmodificationthatwemakeistodefineaprocedureinPostScript.
Proceduresareapowerfulcomponentofthelanguagethatallowsusersto
modularizecommontasks.Here,weuseittospecifytheorderoftransformations
thatareneededtodrawcomplexshapes.Thefollowingprocedureisusedin
drawingellipseswithinsrc/eps/epsEllipse.js:
/ellipse 6 dict begin /angle exch def /yradius exch def /xradius exch def /yC exch def /xC exch def /savematrix currentmatrix def xC yC translate angle rotate xradius yradius scale 0 0 1 360 arc savematrix setmatrix
(Figure5)TheprocedureshowninFigure5beginsbydeclaringadictionaryforthevariables,
anecessarysyntacticalcomponentofPostScriptprocedures.Theitemsinthe
dictionaryaretheangleofrotationoftheellipse,its𝑦radius,its𝑥radius,the𝑥
23
coordinateofitscenterpoint,the𝑦coordinateofitscenterpoint,andthecurrent
matrix.Thecurrentmatrix commandreturnsthecurrent3x3transformationmatrix
ofthePostScriptcoordinatesystem.Itallowstransformationstobeappliedand
savedpriortoaproceduresuchas/ellipsesothatthesametransformationmatrix
canberestoredwhentheprocedureexits.
AswecanseefromFigure5,the/ellipse procedureappliestransformationsafter
definingitsdictionary.EllipsesintheDartDrawReduxstorearerepresentedinthe
canonicalform,sotheprocedurefirstmakesatranslationtoresettheoriginofthe
PostScriptcoordinatesystem,followedbyascalinginthexandydirectionsto
stretchthecircleintoanellipse.Finally,arotationinthereversedirectionofthe
rotationoftheellipseisappliedsothattheactual“ink”drawingonthePostScript
coordinatesystemresultsinanellipserotatedbytheintendedamountinthe
correctangulardirection.Lastly,theproceduredrawsacanonicalcircle.
Inorderforthisproceduretowork,wefirstneedtoobtaintheappropriatedatafor
theellipse.Eachellipseinthedrawing.shapes.byIdnodeoftheReduxstorehasthe
followingdata:{cx,cy,fill,id,rx0,ry0,stroke,strokeWidth,transform,type}.Thecx
andcyvariablesarethecoordinatetotranslatetoafterbeingtransformedbythe
transform-matrix.jslibrary.Thetransformedrxvariable(callitrx1)isfoundby
transformingthecenterpoint’sxcoordinate,transformingthepointontheedgeof
theellipsewithbasecoordinates(center.x+rx,center.y),andthetransformedry
24 Davis
24
variablery1isfoundanalogously.Finally,wehavetoobtaintheangleofrotation,
whichwecandowiththefollowingmethod(showninpseudocode).
Find the point that is rx1 pixels right of the ellipse’s center; call this p0
Transform that point using transform-matrix.js: call this p1
Compute the vector from the center to p1; call this v The cosine of the angle of rotation for v is equal to (v1.y * ry) / (ry2) The above simplifies to v1.y / ry. Call this value c Letα = arccos(c) If v.y < 0, α = - α Return α
(Figure6) Whenallofthevariableshavebeencomputed,theellipseprocedureiscalled.Atthe
endoftheprocedure,thesetmatrixcommandrestorestheprevioustransformation
matrixofthePostScriptcoordinatesystem.Thisstepiscrucialbecauseitoccurs
beforethefill commandiscalled.Ifitdidnot,thenthestrokewouldbeaffectedby
theellipsetransformation.Inthefinaldrawing,theoutlineoftheellipsewouldbe
inconsistentinwidth.
3.5.ArcsArcsinDartDrawcanbeviewedaspartialoutlinesofellipses.Infact,weonlyneed
threeadditionalvariablestorenderarcs–thoughaswewillsee,boundingboxes
requireseveraladditionalconsiderations.
Thefirsttwovariablesarethestartandendanglesofthearc,measuredby
counterclockwiserotationfrom(1,0)ontheunitcircle.Thestartandendpointsof
therotationofthearcaregivenbythepointsattribute.Usingthese,wecancalculate
25
thetwoanglesinthesamewaythatwecalculatedtheangleofrotationofanellipse.
However,wemustbesuretocalculatetheseanglesbeforeapplyingany
transformations.Otherwise,transformedpointsmaybemistakenfornon-
transformedpoints,resultingininaccurateangles.
ThethirdadditionalvariablethatisneededtorenderarcsisflipArc.Thisisaspecial
SVGcomponentofthearcobjectthattellsuswhichdirectionthearcisdrawn.By
default,flipArcisfalse,whichmeansthatthearcisdrawncounterclockwise
betweenthestartandtheendangleofthearc.IfflipArcistrue,thearcisdrawn
clockwise.TorepresentthisdifferenceinPostScript,thearcncommandisused
insteadofarc,whichtellsPostScripttodrawthearcinthecorrectdirection.
ThePostScriptprocedureforarcsisasfollows:
/arc 8 dict begin /rotateAngle exch def /secondAngle exch def /firstAngle exch def /yradius exch def /xradius exch def /yC exch def /xC exch def /savematrix currentmatrix def xc yc translate rotateAngle rotate xradius yradius scale 0 0 1 secondAngle firstAngle arcDirection savematrix setmatrix
(Figure7)
Here,arcDirectionisequaltoeither“arc”or“arcn.”
26 Davis
26
3.6.RoundedRectangles
Roundedrectanglesarethesameasnormalrectanglesinalmosteverywayexcept
thattheyhavean𝑥radiusanda𝑦radiusatthecorner.Thesevaluesareequalto
distancesinthe𝑥and𝑦directionfromeachcornertowardstheinsideofthe
rectangle,wheretheresultingpointsarethecentersofellipseswiththexradiusand
yradiusoftherectangleasitsownradii.
Itiseasytorendertheseshapeswithaclevertrick.First,wenotethateachcorner
ofaroundedrectangleisaquadrantofanellipse.Ifweremoveeachofthose
quadrants,across-likeshaperemains(Figure8).
(Figure8)
Wecanrenderthisshapewithtworectangleswithoutastroke.Gettingtherestof
theshapefilledinrequiresthatwerendertheellipsesfirst,thenthecross-like
figureoverthemtooverlapthepartoftheellipses’outlinethatshouldnotbe
showinginsidethefigure.Lastly,werenderthefourlinesthatconnecttheoutlines
oftheellipsequadrants.
27
Asluckwouldhaveit,wealreadyknowhowtorendereachoftheseshapes,andwe
cantransformallofthemsimultaneouslywhenneededusingthetransformation
matrixoftheroundedrectangleshapeintheReduxstore.
3.7.BezierCurves
InDartDraw,Beziercurvesarecubicratherthanquadratic.CubicBeziercurvesare
representedbytwoendpointsP0andP3alongwithtwointermediarycontrolpoints
P1andP2.Theyaredescribedbythefollowingequation:
𝐵 𝑡 = (1− 𝑡)!𝑃! + 3(1− 𝑡)!𝑡𝑃! + 3 1− 𝑡 𝑡!𝑃! + 𝑡!𝑃!, 0 ≤ 𝑡 ≤ 1
BezierobjectsintheReduxStorehaveapointsattributethatspecifiespointsP0,P1,
P2,andP3foreachcurve.Oncewerotateandtranslatethesepointsaccordingtothe
transformattributeofeachcurve,wecansimplyplugthemintothecurveto
commandofPostScript,asinthefollowingexample:
0 0 moveto 25 50 75 50 100 0 curveto (Figure9) Theabovewouldmovethepento(0,0)thenmakeasemicirclecurveto(100,0)
usingthepoints(25,50)and(75,50)ascontrolpoints.
28 Davis
28
3.7.Text
PostScripthasaspecialshow commandthatdisplaystextonthescreen.Foritto
workspecifiedtextmustbeonthestackdirectlyontopofaspecifiedfont,as
follows:
/Helvetica findfont 24 scalefont setfont 1 1 1 setrgbcolor newpath 0 0 moveto (hello world) show (Figure10) TheEPSshownaboveusesthefindfont commandtolookuptheappropriatefontin
thePostScriptdictionary.Justastheuser-defineddictionarieswesawearlierto
accessthevariablesusedinthe/ellipseand/arcprocedures,PostScripthasbuilt-in
dictionariesforavarietyofpurposes,includingpre-definedfonts.Italsohasa
fallbackprocedureintheeventthattheuser-specifiedfontisnotfound;inthiscase,
ittypicallyprintsinHelvetica.
TheaboveEPSthenscalesthefonttotheappropriatesizeinpointsandsetsthe
strokecolor. Itbeginsanewpath,movestotheupperleft-handcornerofthetextto
bewritten,andshowsthespecifiedtextusingtheshow command.
29
Scaling,translating,androtatingtextisfairlystraightforwardaswell,using
commandsthatwehavealreadyseeninearlierprocedures.Forexample,ifwe
wouldliketorotatetextby90degrees,wecandosoasfollows:
/Helvetica findfont 24 scalefont setfont 1 1 1 setrgbcolor gsave newpath 0 0 translate 90 rotate (hello world) show grestore (Figure11)
Notethatthisprocedureislargelythesameasbeforewiththreekeydifferences.
First,weaddarotatecommand.Second,weusethetranslatecommandinsteadof
themovetocommandsothattheoriginofthecoordinatesystemissettotheupper
left-handcornerofthetextandcanberotatedaroundthatpoint.Lastly,weusethe
gsave andgrestore commandstosaveareferencetothecurrenttransformation
matrixofthecoordinatesystempriortoanytransformationsandtorestoreitafter
thetexthasbeenrendered.
ThestructureofthetextboxobjectinDartDrawissuchthatthereisnoautomatic
expansionofthetextboxtoaccommodatetextthatrunsover.Instead,theusersees
textwraparoundtothenextline.Becausethereisnowaytodetectthiswrap
aroundbehaviorfromthebackend,itcannotbehandledbytheexport
functionality.Therefore,weinsteadimposeacoupleofconstraintsupontheuser.
30 Davis
30
First,anytextthatausertypesbeforeacarriagereturnisassumedtobeonthe
sameline.IftheuserseesthetextwraparoundintheDartDrawdisplay,thisisonly
aproductofthefactthatheorshehasnotmadethetextboxwideenoughto
accommodatethetext.ThecorrespondingEPSfilewillnotrenderanytextthatis
meanttobeonthesamelinebutdoesnotfitwithinthetextbox.Second,the
backendexportfunctionalityusesthenewlinecharacter“\n”asadelimiterwhen
parsing.Theparsercreatesanarrayofstringstodisplayastext,afterwhichit
appliesanynecessarytransformationsandstacksthesestringsonaline.
Forexample,todisplaythefollowingstringoftextinblackHelvetica,startingat
coordinate(100,100),androtatedby45degrees,theexportfunctionalitywould
createtheEPSfragmentshownbelowit:
“Goodmorning,sunshine!TheEarthsays:Hello!”/Helvetica findfont 24 scalefont setfont 1 1 1 setrgbcolor gsave 100 100 translate 45 rotate 0 -24 moveto newpath (Good morning sunshine!) show newpath 0 -48 moveto (The Earth says:) show newpath 0 -72 moveto (Hello!) show (Figure12)
31
4.ComputingBoundingBoxes
ThemostimportantseparatingfactorbetweenEPSfilesandotherPostScriptfilesis
theconceptofaboundingboxinEPS.Theboundingboxisspecifiedintermsofthe
lowerleft-handxcoordinate(llx),thelowerleft-handycoordinate(lly),theupper
right-handxcoordinate(urx),andtheupperright-handycoordinate(ury).Alarge
portionofmyroleintheDartDrawprojectwastocomputeink-basedbounding
boxesforexportedEPSfiles.
4.1.TheBoundingBoxObject
UsingJavaScriptallowedmetohandlethecreationofboundingboxesinanobject-
orientedfashion.Thefilesrc/eps/eps.jscreatesaboundingboxobject,which
initiallyhasarbitrarilyhighvaluesforllxandllyandarbitrarilylowvaluesforurx
andury;thatis,thereisnoboundingboxasnofigureshaveyetbeenrendered.
Themainjobofeps/eps.jsisthentoparsethroughadeepcopyofthedrawingstate
withintheDartDrawReduxstoretoparseeachshape.Eachoftheseshapesismade
intoanepsShapeobject,whereepsShapeisanabstractclassthatdefinesseveral
methodsincludingproduceEPS,getAngle,andgetCoords.Asitparsesthedrawing
stateandcreateseachepsShapeobject,eps/eps.jscallstheupdateBoundsIfNecessary
methodofthebounding box class,whichtakesanepsShapeasanargument.
Theboundingboxobjectitselfisdefinedwithinsrc/eps/boundingBox.js.The
object’supdateBoundsIfNecessary methodconsistsofaswitchstatementbasedon
32 Davis
32
thetypeofthegivenepsShape.Forexample,ifthetypeoftheshapeis“ellipse,”the
methodappropriatelycallsitshelpermethodupdateBoundsEllipseHelper.Allsuch
helpermethodshavetheabilitytomanipulatethellx,lly,urx,anduryvaluesofthe
boundingboxobjectbasedontheparametersoftheepsShapeobjectthatit
considers.
Below,IdiscusshowtheboundingboxofeachfigureinDartDrawiscomputed.
4.2.LinesandFreehandPathsForlinesandforallshapes,itisimportanttofirstnotethatastrokeinPostScriptis
dividedoneithersideofapoint.Forexample,averticallineofstrokewidth5,
increasinginyvalueandendingat(10,10)wouldspreadoneithersidetocorner
pointsof(7.5,10)and(12.5,10)(seeFigure9).
(Figure13)
stroke on either side
33
Second,wemustrememberthattheoriginoftheDartDrawcoordinatesystemisin
theupperleft-handcornerwhiletheoriginofthePostScriptcoordinatesystemisin
thelowerleft-handcorner.It’sthereforenecessarytosubtractthe𝑦valueofashape
fromthecanvasheightoftheDartDrawwindowwheneverthat𝑦valuecomesfrom
theReduxstaterepresentationandwewishtoconvertitanEPSrepresentation.
Theboundingboxesoflinesarefairlyeasytocomputeandformthebasisforthe
boundingboxcomputationsofotherfigures.Giventwopoints𝑃!and𝑃!,wecan
assumeWLOGthatthevectorofthelineistowards𝑃!.Wecangetthe𝑥and𝑦
componentsofthisvectorbysubtractingthecorrespondingpoints.Then,wecan
findtheangleofrotationofthevectorfrom(1,0)ontheunitcircleasfollows:
∆𝑥 = 𝑃!. 𝑥 − 𝑃!. 𝑥∆𝑦 = 𝑃!.𝑦 − 𝑃!.𝑦𝜃 = 𝑡𝑎𝑛!!(∆𝑦,∆𝑥)
NotethattheimplementationofthisequationwithintheDartDrawbackenduses
theatan2functioninplaceof𝑡𝑎𝑛!!,thearctangent.Thatisbecauseatan2can
distinguishbetweendiametricallyopposedanglesandhasarangeof[−𝜋,𝜋]while
𝑡𝑎𝑛!!cannotdosoandislimitedtoarangeof(!!!, !!).
Theendsofthelinesareflat,whichmeansthattheedgeofthisflatlinesegmentis
orthogonalto𝜃.Wecancallthisangle𝜑,and𝜑 = 𝜃 + !!forthepointofthelineend
thatisrotationallyclockwiserelativeto𝑃!.Wecanusethispointasareferenceto
34 Davis
34
computethe𝑥and𝑦componentsofthevectorbetweenlineendpointsandthe
cornersofthenon-zerostrokeline.Callingthisvector𝑣,weset:
𝑣! = cos 𝜑 × !"#$%&'()"!!
and𝑣! = sin 𝜑 × !"#$%&'()"!!
.
Ourfourcornerpointsarethusequalto:
(𝑃!. 𝑥 + 𝑣! ,𝑃!.𝑦 + 𝑣!)(𝑃!. 𝑥 − 𝑣! ,𝑃!.𝑦 − 𝑣!)(𝑃!. 𝑥 + 𝑣! ,𝑃!.𝑦 + 𝑣!)(𝑃!. 𝑥 − 𝑣! ,𝑃!.𝑦 − 𝑣!)
Thenweneedonlycomparethesevaluestotheboundingboxcoordinatesand
updatetheboundingboxaccordingly.
4.3.RectanglesBecauserectanglesarerenderedusinglines,computingtheboundingboxof
rectanglesisaverysimilarprocesstotheoneusedforcomputingtheboundingbox
oflines.However,aswenotedinsection3,PostScriptfillsinthecornersofclosed
shapesrenderedwithlinesafterclosepathiscalled,andwemustaccountforthis.
Becauselinesonlyintersectatanglesof !!inrectangles,weknowthattheadditional
inkfilledinbyPostScriptbetweenrenderedlinesisasquare.Furthermore,we
knowthatthesidesareoflength!"#$%&'()"!!
andthatthediagonalisoflength
!"#$%&'()"!!
× 2.Ifwecanfindtheangleofthevector𝑣fromeachintersectionof
35
linestothecorrespondingcorneroftheadditionalfilled-inbox,thenwecanfindthe
coordinatesofthecornerofeachfilled-inbox.
Infact,wecansaythatthisangleis𝜑 = 𝜃 − !!
(where𝜃iscomputedinthesame
wayasitisforlines)becausethehypotenuseofthefilled-insquarebisectstheright
angle.Thenweset𝑣! = cos 𝜑 × !"#$%&'()"!!
× 2and
𝑣! = sin 𝜑 × !"#$%&'()"!!
× 2.Foreachlineintherectanglefrom𝑃! 𝑡𝑜 𝑃!,thereis
onlyonesuchcornerpointofafilledinbox.Oncewehave𝑣!and𝑣! ,thispointis:
(𝑃!. 𝑥 + 𝑣! ,𝑃!.𝑦 + 𝑣!)Thenwecomparethispointtotheboundingboxcoordinatesandupdatethe
boundingbox.
4.4.Polygons
Justastheweneededtoaddanextrasteptomovefromtheboundingboxesoflines
totheboundingboxesofrectangles,wemustaddyetanothersteptomovefromthe
boundingboxesofrectanglestotheboundingboxesofpolygons.
Unlikerectangleswherethecornersarealwaysanglesof !!,thecornersofpolygons
canbeanyangle.Ifthisangleisgreaterthan𝜋,itisnotanextremumofthepolygon,
soitcanbeignored.Supposethatpoints𝑃!,𝑃!,and𝑃!makeacornerat𝑃!.Ifthe
36 Davis
36
vectorfrom𝑃!to𝑃!hasthesamesignforits𝑥and𝑦componentsasthevectorfrom
𝑃!to𝑃!,thentheangleofthecornerisgreaterthan𝜋,meaningthatwedon’thave
toconsiderthiscornerwhencomputingtheboundingbox.
Otherwise,wemustcomputetheangle𝜔betweenthesetwovectorsforuseinthe
computationofthelengthandangleofthevectorfromtheactualcornertothe
cornerofthefilled-inspace.Wecanusethedotproductrule,whichstatesthat:
𝑨 ∙ 𝑩 = 𝑨 × 𝑩 × cos (𝜔),
so
𝜔 = 𝑐𝑜𝑠!!𝑨 ∙ 𝑩𝑨 × 𝑩
Thefilled-inregionforthecornerofapolygonisaquadrilateralthatcanbebisected
intotwotriangles.Thisdividinglineisthevector𝑣thatwearelookingfor.Sincewe
knowthelengthofoneofthesidesis!"#$%&'()"!!
,andtheangleoppositethissideis
!!,wecanfind 𝑣 .
𝑣 = 𝑠𝑡𝑟𝑜𝑘𝑒𝑊𝑖𝑑𝑡ℎ
2 × 𝑐𝑠𝑐𝜔2
Thenwefindtheangleofrotationof 𝑣fromthepoint(1,0)ontheunitcircle,andwe
callthisangle𝜑.Afterfindingtheangle𝜃ofthevectorfrom𝑃! to𝑃!(computedin
thesamewayasitwasforlines),wecancompute𝜑usingtheparallelogramrule.
37
𝜑 = 𝜃 +𝜔2
Finally,𝑣! = cos 𝜑 × 𝑣 and𝑣! = sin 𝜑 × 𝑣 ,sowecheckwhetherornotwe
needtoupdatetheboundingboxbasedonthepoint(𝑃!. 𝑥 + 𝑣! ,𝑃!.𝑦 + 𝑣!).
4.5.Ellipses
Thefollowingderivationoftheellipseboundingboxequationisbasedonthework
ofMarkC.Hendricks,PhD.
Tobegin,weassumethattheellipseiscenteredattheoriginsincewecanoffsetthe
resultingboundingboxbytheappropriateamountafterthefact.Supposethatwe
havesuchanellipsethathasbeenrotatedaroundtheoriginbyanangle𝛼.Thenwe
recallthatequationforastandardellipsewithhorizontalradiusℎandvertical
radius𝑣:
𝑥!!
ℎ! + 𝑦!!
𝑣! = 1
Here,(𝑥!,𝑦!)isapointontheboundaryoftheellipseaftertheellipsehasbeen
rotatedinreversebyangle𝛼tomakeastandardellipse.Nowwecanfind𝑥!and𝑦!
intermsofthepoints𝑥and𝑦ontheboundaryoftheoriginalnon-rotatedellipse.
𝑥! = 𝑥 cos 𝛼 + y sin 𝛼
38 Davis
38
𝑦! = 𝑦 cos 𝛼 − 𝑥 𝑠𝑖𝑛 𝛼
Substitutiongetsustheequationofarotatedellipse.
𝑥 cos 𝛼 + y sin 𝛼 !
ℎ! + 𝑦 cos 𝛼 − 𝑥 𝑠𝑖𝑛 𝛼 !
𝑣! = 1
Expandingandsettingtheright-handsideoftheequationto0givesthefollowing.
𝑣!𝑥!𝑐𝑜𝑠! 𝛼 + 2𝑣!𝑥𝑦𝑐𝑜𝑠 𝛼 𝑠𝑖𝑛 𝛼 + 𝑣!𝑦!𝑠𝑖𝑛! 𝛼 + ℎ!𝑦!𝑐𝑜𝑠! 𝛼
− 2ℎ!𝑥𝑦𝑐𝑜𝑠 𝛼 𝑠𝑖𝑛 𝑎 + ℎ!𝑥!𝑠𝑖𝑛! 𝛼 − ℎ!𝑣! = 0
Whenwehold𝑦constant,wegetaquadraticequationforxwiththefollowing
coefficients:
𝑎 = 𝑣!𝑐𝑜𝑠! 𝛼 + ℎ!𝑠𝑖𝑛! 𝛼 𝑏 = 2𝑦𝑐𝑜𝑠 𝛼 𝑠𝑖𝑛 𝑎 (𝑣! − ℎ!)
𝑐 = 𝑦! 𝑣!𝑠𝑖𝑛! 𝛼 + ℎ!𝑐𝑜𝑠! 𝛼 − ℎ!𝑣!Usingthequadraticformula,wegetonesolutionwhen𝑏! − 4𝑎𝑐 = 0.Usingthe
variablesdefinedaboveandalittlebitofalgebratosolveforx,wefindthat:
𝑥! = −𝑎ℎ!𝑣!
𝑐𝑜𝑠! 𝛼 𝑠𝑖𝑛! 𝛼 𝑣! − ℎ! ! − 𝑎 𝑣!𝑐𝑜𝑠! 𝛼 + ℎ!𝑠𝑖𝑛! 𝛼
39
Wegetthexcoordinatesoftheboundingboxfortherotatedellipsebytakingthe
squarerootofbothsidesoftheaboveequation.Lastly,wemustoffsetthetwox
coordinatesbythexcoordinateoftheellipse’struecentertoaccountforourinitial
assumptionthattheellipseiscenteredattheorigin.
Theyvaluesoftheboundingboxoftherotatedellipsearecomputedanalogously.
Theparametersusedintheaboveequationarederivedaccordingtotheprocess
describedinsection3.
4.6.Arcs
Anarcissimplyapartialoutlineofanellipse.Thelogicforfindingtheextremais
fairlysimplewhilethemathtodosoisrathercumbersome.
Theprocedureisasfollows:
Find the minX and maxX of the base ellipse For each of these values: Find the corresponding y coordinate using the implicit quadratic equation Find the angle of rotation of this x,y pair Determine if this angle lies between the start and end angle of the arc If it does: This is an extremum. Update the bounding box If it does not: This is not an extremum. Repeat the above for minY and maxY. Test the coordinates at the start and end angle of the arc, accounting for stroke width (Figure14)
40 Davis
40
Findingthecorrespondingycoordinatetominx(forexample)isthedifficultpartof
thisprocedureandtheonlyonewithmaththatwehavenotalreadyexamined.
Tosolvethis,wenotethatwecanalsorepresentellipsesusingtheimplicit
quadraticequation:
𝐴𝑥! + 𝐵𝑥𝑦 + 𝐶𝑦! + 𝐷𝑥 + 𝐸𝑦 + 𝐹 = 0Thevaluesforthecoefficientsareasfollows,withℎ,𝑣,and𝛼definedasbefore.
𝐴 = ℎ!𝑠𝑖𝑛! 𝛼 + 𝑣!𝑐𝑜𝑠! 𝛼 𝐵 = 2 𝑣! − ℎ! 𝑠𝑖𝑛 𝛼 𝑐𝑜𝑠 𝛼 𝐶 = ℎ!𝑐𝑜𝑠! 𝛼 + 𝑣!𝑠𝑖𝑛! 𝛼 𝐷 = −2𝐴𝑥!"#$"% − 𝐵𝑦!"#$"% 𝐸 = −𝐵𝑥!"#$"% − 2𝐶𝑦!"#$"%
𝐹 = 𝐴𝑥!"#$"%! + 𝐵𝑥!"#$"%𝑦!"#$"% + 𝐶𝑦!"#$"%! − ℎ!𝑣!
Thenthecoefficientsofthequadraticequationtosolveforthexcoordinate,for
example,are:
𝑎 = 𝐴
𝑏 = 𝐵𝑦 + 𝑑𝑐 = 𝐶𝑦! + 𝐸𝑦 + 𝐹
Wehaveonesolutionfor𝑦when𝑏! − 4𝑎𝑐 = 0.Wecansolvefor𝑥giventhe𝑦
coordinateofanextremuminasimilarfashion,thoughweneednotshowallofthe
equations.
41
4.7.RoundedRectanglesSinceroundedrectanglearecreatedfromDartDrawrectanglesandellipses,the
boundingboxofaDartDrawdrawingisalteredseparatelybyeachofthecomponent
shapes.
4.8.BezierCurvesInsection3,wesawthatfourpointsinthecoordinatesystemdefineeachcubic
BeziercurvesusedinDartDraw.AlthoughBeziercurvesarefairlyeasytorender,
computingtheboundingboxesoftheseshapesisadifficultprocessthatisbeyond
thescopeofthisthesis.
However,thesefourpointsareeasytoaccesswithintheBoundingBoxclass.The
updateBoundsBezierHelper methodleveragesthegetCoords methodoftheepsShape
classtogetthefourpointsneededtodefineaBeziercurve.EverycubicBeziercurve
isboundbythepolygondescribedbyitsfourcontrolpoints.Therefore,the
BoundingBoxclasscheckseachpointwithanoffsetofhalfofthestrokeWidthofthe
Beziercurvetoseeifthisboundingpolygonpushespasttheedgesofthecurrent
DartDrawboundingbox.Whilenotprecise,thismethodisaccurate.
5.FileSavingandOpening
Asdiscussedthroughoutthisthesis,theinternalstructureoftheDartDraw
applicationrestsentirelyupontheReduxframework.WhatmakestheRedux
42 Davis
42
frameworksousefulisthatitstoresexactlywhatweneedtoknowaboutthestate
ofadrawingwithnomissingorsuperfluousinformation.Therefore,itisthebasisof
theDartDrawfilesaveformat.
5.1.SavingfileswithIPCIntheintroductiontothisthesis,IdiscussedtherelationshipbetweentheElectron
mainprocessandthebrowserprocesses.Becauseelectronprocesseshandlemenu
eventsandbrowserprocessescanrenderseparatedrawingsfromeachother,this
relationshipbecomesimportantinthefilesaveprocess.
ThemenuiscreatedusingtheElectronMenumodule,whichallowsadeveloperto
createatemplatemenuformatandsetthatasthenativemenu.Inthiscase,wehave
OSXmenuoptionsforsavingandopening,alongwithotherfunctionalitynot
discussedhere.
Whenauserdecidestosaveafile,theyclickonFile>SavewithintheElectronmenu,
whichthenhandlestheappropriateclickeventdescribedinDartDraw/electron.js.
Inthecaseofafilesave,theclickeventbeginsbygettingthecurrentlyfocused
browserprocess–seenbytheuserasawindowwitharendereddrawing–using
thecommandBrowser.getFocusedWindow().Next,ittakesadvantageofinter-process
communication(IPC)tocommunicatebetweentheElectronmainprocessandthis
specificbrowserprocess.
43
Electron’sIPCmoduleenablestheprocessestocommuteinthisway.Theideais
thatthemainprocessside“pings”aparticularchannelonthebrowsersideusing
theipcMainsubmodule,sendingamessageandaneventalongwiththeping.The
browsersideusestheipcMain submoduletolistenformessagesonthefilesave
channel.Whenitreceivesaping,itinterpretsthemessageasthemainprocess
askingforafilesave.ThebrowserprocessthenaccessestheReduxstore,convertsit
fromJSONtoastring,andsendsitbacktothemainprocessoverthecorrectchannel
usingtheeventthatwassentbythemainprocess.
Whenthemainprocessreceivesaresponsefromabrowserprocessoverthefile
savechannel,itsaveswhateveritwasgivenusingElectron’sfilesavemodule.
Specifically,thismoduleopensanOSXnativesavedialog,allowingtheusertoinput
afilename.Themainprocesssavesthegivenstringtothisfilename,checkingtosee
ifsuchafilenamealreadyexistsandexitinggracefullywhenitencountersanerror.
5.2.OpeningfilesDartDrawopensfilesinmuchthesamewayasitsavesthem,butinreverse.Whena
useroptstoopenafilefromtheDartDrawmenu,themainprocessshowsanative
OSXopendialogthroughwhichtheusermayselectoneormultiplefiles.Foreach
filethatisselected,themainprocessattemptstoopenthefileandthetextintoa
JSONobjectrepresentingthedrawingstateportionofaDartDrawReduxstore.
Uponeachsuccess,themainprocesscreatesanewbrowserprocess,instantiates
theIPCfilesavechannelinthatprocess,andsendsitaReduxstorerepresentinga
44 Davis
44
drawing.Finally,eachnewbrowserprocessparsesitsdrawingstateandrendersit
accordingly.
6.FutureWork
ImpressiveastheDartDrawapplicationmaybe,thereareafewimportantwaysin
whichtheapplicationcouldbeimproved.Below,Ifocusonthepotential
improvementsthatwouldfallundermyresponsibility.
6.1.ComplexShapeIntersectionOneusefulfeatureofDartDrawallowsausertoselectacoloroftheirchoiceasthe
canvascolor.Whenevershapesarethesamecolorasthebackground,weavoid
expandingtheboundingboxofthetotaldrawingbasedonthatshape.Wewould
not,forexample,wantanEPSfiletorepresentadrawingofsignificantdimensions
whentheonlyfigurespresentinthedrawingarethesamecolorasthecanvas.
Withoutlossofgenerality,let’sassumethatthecanvasiswhite.Awhiterectangle
drawnbytheusershouldnotresultinacalltoanyboundingboxhelperfunction
becausetheboundingboxshouldnotexpand.However,itmaywellbethatthis
rectangleoverlapsaredellipse.Anink-basedboundingboxshouldaccountforall
partsofthisredellipsethatarenotcoveredbythewhiterectangle,whichmeans
thatwewouldhavetocomputethepointsofintersectionbetweenthetwoshapes.
45
Additionally,wehavetomakeanextrapassthroughthelistofshapeseverytimewe
considerupdatingtheboundingboxes.Ifweweretodrawtheredellipsefirst,the
boundingboxwouldhavethenecessarydimensionstoencapsulatetheredellipse.If
weweretothendrawthewhiterectangleovertheredellipse,theboundingbox
wouldnotupdatebecausethewhiterectangleisthesamecolorasthecanvas.This
isaproblem;weknowhaveaboundingboxthatisnotink-basedbecauseit
encompassestheareainwhichthepartoftheredellipsethatisnocoveredbythe
whiterectangleusedtobevisible.Therefore,wemustinstead“lookahead”through
thelistofshapesintheReduxstoreeachtimethatweconsiderupdatingthe
boundingboxes.Ifwetakethisapproach,wewouldconsidertheredellipseand
realizethatitisgoingtobeoverlappedbythewhiterectangledowntheroad,sowe
canupdatetheboundingboxaccordingtothepointsofintersectionbetweenthe
twoshapesinsteadofnaivelyconsideringeachshapeonlyinisolation.
Currently,DartDrawexportfunctionalityaccountsforintersectionsbetweenlines,
rectangles,roundedrectangles,andellipses.Futureworkwouldincludeaccounting
forintersectionbetweenmorecomplexshapesincludingarcs,Beziercurves,
freehandpaths,andtext.
6.2.ColorFlatteningEachshapetypeinDartDrawhasanassociatedcontextmenuwithintheappthat
allowsuserstoselectdifferentfeaturesofthatshape.Onefeaturethatiscommonto
allshapesiscolor,whichmayapplytothefilland/orthestrokeofthatshape.The
46 Davis
46
usercanchoosewhetherthecolorisrepresentedbyRGBorCMYK.Ineithercase,
thecolorinPostScriptisrepresentedinCMYK.
Fortunatelyforthefrontendoftheapplication,theusermayalsomanipulatethe
alphachannelofthecolorpalettewhenstylingtheirdrawings.Unfortunatelyforthe
backendoftheapplication–includingexportingEPSfiles–thisbehaviorisnot
supported.Thatmeansthatthereisnoautomaticwaytoincludeopacityforshapes
dictatedbyEPSfiles.
Adobehandlesthisissuewithatechniqueknownascolorflattening.Theideaisthat
multipleshapeswithsomedegreeofopacitycanoverlapinanymannerofways,
creatinganewcolorattheareasofoverlap.Ofcoursethisnewcolorcanbe
calculatedwithrelativeease,buttheareasofoverlapcanbeverydifficultto
computeforanarbitrarynumberofoverlaps.Whiletheproblemissolvable,itis
beyondthescopeofthisthesis.
6.3.FileCompressionThecurrentversionofDartDrawiscapableofopeningDartDrawfiles,recognizing
whenfilesarenotDartDrawfilesandshouldnotbeopened,andcansavefilesinthe
DartDrawfileformat.Furthermore,JeanZhouhaswrittenastandalonePython
scripttoconvertMacDrawfilesintotheDartDrawfileformat.
47
However,DartDrawdoesnotcurrentlysupportcompressedfiles.Onepotential
methodthatwouldbeeasilyimplementedinascriptinglanguagelikeJavaScriptis
Huffmanencoding,acompressiontechniquethatcangreatlyreducefilesizewhen
usedonaknownandfinitesetofsymbolssuchastheASCIIcharactersusedto
representtheReduxStoreintheDartDrawfileformat.
7.Reflection
Workingonthisprojecthasbeenbothchallengingandextremelyrewarding.From
thebeginning,IwasopposedtotheideaoftheJavaScript-basedReact-Reduxdesign
thatthemajorityofthegroupfavoredasitmeantthatIwouldhavetolearnanew
programminglanguageinadditiontoPostScript.
Whilegettinguptospeedwasquitechallenging,Icannowconfidentlysaythatmy
colleaguesmadeawisechoicetosetupourprojectthisway.TheReduxAPIis
incrediblyeasytouseandmakestranslationbetweentheapplication’sinformation
andtheexportedPostScriptfilesmuchlesspainlessthanitmighthavebeen.
Furthermore,IseetheruntimebenefitsofusingtheReactframeworkto
individuallyapplychangestofiguresonthefrontend.ComparedtoSwift-based
applicationsthatIhavemadeinthepastusingXcode,DartDrawisquiteaspeedy
anduser-friendlygraphicsapplication.
48 Davis
48
TherearecertainlydecisionsthatIwouldhavemadedifferentlyifIhadthe
opportunitytogobackanddothisprojectagain.Mostly,Iwoulddoallofthemath
thatIendedupneedingaheadoftime.AfterlearninghowtousetheReact-Redux
framework,readinguponsomebasicPostScript,andcomputingthebounding
boxesforafigureortwo,IwasconvincedthatIwasreadytostartcodinginearnest.
Inreality,thereisnocodewrittenbeforeacoupleofmonthsagothatIdidnot
changeatleastalittlebitinthepastfewweeks.AsIrealizedmorelogicaland
efficientwaystoorganizethisproject–suchastheconnectionbetweenrendering
arcsandellipses,orhowtoapplyquadraticsolverstobotharcsandBeziercurves–
IcametoadmittomyselfthatmyinitialeffortsbeliedthelackofplanningIdidfor
thelongterm.
Evenso,Iamproudoftheapplicationthatwehavemade.Therearecertainlybugs
toworkoutandfeaturestoadd,butIgenuinelybelievethatuserscouldenjoytheir
experiencewithDartDrawasitstandsnow.Whetherwepolishwhatwe’vemade
afterweturninthesethesesorithastowaituntilanotherundergraduatefits
togetherthefinalpieces,it’scleartomethatweaccomplishedanimpressivefeatin
softwareengineeringwithlimitedtime,resources,andinitialknowledge.
IamimpressedbymycolleaguesCollin,Elisabeth,Emma,Jean,Luisa,andMichelle,
andIamthankfultomyadvisor,ThomasCormen.
49
8.References
AppleInc.“Swift4.”Swift–AppleDeveloper.2018.AccessedMay9,2018.
https://developer.apple.com/swift/.
“Electron|BuildCrossPlatformDesktopAppswithJavaScript,HTML,andCSS.”
Electronjs.AccessedMay7,2018.https://electronjs.org/.
Hendricks,MarkC.RotatedEllipsesandTheirIntersectionswithLines.PDF.March8,
2012.
“Transformation-matrix-js.”Npm.AccessedMay11,2018.
https://www.npmjs.ocom/package/transformation-matrix-js.
Wikipedia,s.v.,“Ellipse,”lastmodifiedMay23,2018,
https://en.wikipedia.org/wiki/MacDraw
Wikipedia,s.v.,“MacDraw,”lastmodifiedFebruary17,2018,
https://en.wikipedia.org/wiki/MacDraw