package Ġinfo . ben jamin h ill . script gen Ċ Ċ import Ġinfo . ben jamin h ill . utils . Normal Vector 2 D Ċ import Ġmu . K Log gable Ċ import Ġorg . apache . commons . math 4 . geometry . e uclidean . tw od . Line Ċ import Ġorg . apache . commons . math 4 . geometry . e uclidean . tw od . Vector 2 D Ċ import Ġorg . w 3 c . dom . Element Ċ import Ġjava . awt . Basic Stroke Ċ import Ġjava . awt . Color Ċ import Ġjava . awt . Rendering Hints Ċ import Ġjava . awt . image . Buffered Image Ċ import Ġjava . io . File Ċ import Ġjava . util .* Ċ import Ġjavax . xml . parsers . Document BuilderFactory Ċ import Ġkotlin . math . abs Ċ import Ġkotlin . math . round ToInt Ċ Ċ /** Ċ Ġ* ĠWrapper Ġaround Ġa Ġlist Ġof Ġpoints . Ċ Ġ* ĠCan Ġsimplify Ġthe Ġsteps Ġfor Ġeasier Ġdrawing , Ġproduce Ġa Ġguess Ġof Ġwhat Ġthe Ġbot Ġwill Ġdraw , Ġand Ġhas Ġa Ġvariety Ġof Ġoutput Ġformats . Ċ Ġ*/ Ċ open Ġclass ĠScript ( ĊĠĠĠ Ġprivate Ġval Ġpoints : ĠList < Normal Vector 2 D > Ċ ) Ġ{ ĊĠĠĠ Ġ/** ĠRender Ġa Ġscript Ġinto Ġa Ġsample Ġimage , Ġgood Ġfor Ġtesting Ġ*/ ĊĠĠĠ Ġfun Ġto Image ( background Image : ĠBufferedImage ? Ġ= Ġnull ): ĠBufferedImage Ġ{ ĊĊĠĠĠĠĠĠĠ Ġ/** ĠA Ġsample Ġrendering Ġ*/ ĊĠĠĠĠĠĠĠ Ġval Ġoutput Image Ġ= Ġbackground Image Ġ?: ĠBufferedImage ( ĊĠĠĠĠĠĠĠĠĠĠĠ ĠScale Free Image . RESOL UTION , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠScale Free Image . RESOL UTION , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠBufferedImage . TYPE _ INT _ RGB ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġval Ġoutput G 2 d Ġ= Ġoutput Image . create Graphics () !!. apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( background Image Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcolor Ġ= ĠColor . BLACK ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfill Rect ( 0 , Ġ 0 , Ġoutput Image . width , Ġoutput Image . height ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġset Rendering Hint ( Rendering Hints . KEY _ ANTI ALIAS ING , ĠRendering Hints . VALUE _ ANTI ALIAS _ ON ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcolor Ġ= ĠColor ( 2 5 5 , Ġ 0 , Ġ 0 , Ġ 1 5 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġa Ġfew Ġmm Ġwide Ġpen ? ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstroke Ġ= ĠBasic Stroke ( 1 f ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġthis . points . map Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠVector 2 D ( it . x , Ġit . y ). scalar Multiply ( Scale Free Image . RESOL UTION . toDouble ()) ĊĠĠĠĠĠĠĠ Ġ}. zip With Next (). forEach Ġ{ Ġ( a , Ġb ) Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcheck ( a . x . round ToInt () Ġin Ġ 0 .. Scale Free Image . RESOL UTION ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcheck ( a . y . round ToInt () Ġin Ġ 0 .. Scale Free Image . RESOL UTION ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġoutput G 2 d . draw Line ( a . x . round ToInt (), Ġa . y . round ToInt (), Ġb . x . round ToInt (), Ġb . y . round ToInt ()) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġoutput G 2 d . dispose () ĊĠĠĠĠĠĠĠ Ġreturn Ġoutput Image ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĠRender Ġa Ġscript Ġinto Ġa Ġplain Ġtext Ġchunk , Ġgood Ġfor Ġexporting Ġ*/ ĊĠĠĠ Ġfun Ġto Text () Ġ= Ġthis . points . join ToString (", \ n ") Ġ{ Ġit . toString () Ġ} ĊĊĠĠĠ Ġfun Ġremove Duplicates (): ĠScript Ġ= ĠScript ( ĊĠĠĠĠĠĠĠ Ġpoints Ġ= Ġthis . points . filter Indexed Ġ{ Ġindex , Ġvector 2 D Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( index Ġ== Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvector 2 D Ġ!= Ġthis . points [ index Ġ- Ġ 1 ] ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ) ĊĊĠĠĠ Ġfun Ġr amer D ou glas Pe u cker ( maxSize : ĠInt Ġ= Ġ 1 _ 0 0 0 ): ĠScript Ġ{ ĊĠĠĠĠĠĠĠ Ġlogger . info Ġ{ Ġ" ram er D ou glas Pe u cker Ġfrom Ġ${ points . size } Ġto Ġ$ maxSize " Ġ} ĊĠĠĠĠĠĠĠ Ġvar Ġmax Delta Ġ= Ġ 0 . 0 0 0 0 1 ĊĠĠĠĠĠĠĠ Ġvar Ġiterations Ġ= Ġ 0 ĊĠĠĠĠĠĠĠ Ġval Ġresult Ġ= Ġpoints . to Mutable List () ĊĠĠĠĠĠĠĠ Ġresult . addAll ( points ) ĊĠĠĠĠĠĠĠ Ġwhile Ġ( result . size Ġ> ĠmaxSize ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġiterations ++ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġresult . clear () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġresult . addAll ( ram er D ou glas Pe u cker Recursion ( points , Ġmax Delta )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmax Delta Ġ*= Ġ 1 . 0 5 ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġlogger . info Ġ{ Ġ" max Delta Ġof Ġ$ max Delta Ġis Ġunder Ġsize Ġcap Ġ$ maxSize Ġafter Ġ$ iterations Ġpasses ." Ġ} ĊĠĠĠĠĠĠĠ Ġreturn ĠScript ( points Ġ= Ġresult ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĠIter atively Ġdelete Ġsmallest Ġ 3 - point Ġtriangles . Ġ ĠCould Ġdo Ġlots Ġof Ġcaching , Ġbut Ġme h . Ġ*/ ĊĠĠĠ Ġfun Ġvis val ing am Why att ( maxSize : ĠInt Ġ= Ġ 1 _ 0 0 0 ): ĠScript Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġresult Ġ= Ġpoints . to Mutable List () ĊĠĠĠĠĠĠĠ Ġwhile Ġ( result . size Ġ> ĠmaxSize ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( result . size Ġ% Ġ 1 0 0 0 Ġ== Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . info Ġ{ Ġ" vis val ing am Why att Ġ${ result . size }" Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtriangles Ġ= Ġresult . window ed ( 3 ). map Ġ{ ĠTrip le ( it [ 0 ], Ġit [ 1 ], Ġit [ 2 ]) Ġ}. map Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit Ġto Ġabs ( it . first . x Ġ* Ġ( it . second . y Ġ- Ġit . third . y ) Ġ+ Ġit . second . x Ġ* Ġ( it . third . y Ġ- Ġit . first . y ) Ġ+ Ġit . third . x Ġ* Ġ( it . first . y Ġ- Ġit . second . y )) Ġ/ Ġ 2 . 0 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġmin Tri Area Ġ= Ġtriangles . min By OrNull Ġ{ Ġit . second Ġ} !! ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġidx Ġ= Ġtriangles . indexOf ( min Tri Area ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġresult . remove At ( idx Ġ+ Ġ 1 ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn ĠScript ( points Ġ= Ġresult ) ĊĠĠĠ Ġ} ĊĊĊĠĠĠ Ġcompanion Ġobject Ġ: ĠK Log gable Ġ{ ĊĠĠĠĠĠĠĠ Ġoverride Ġval Ġlogger Ġ= Ġlogger () ĊĊĠĠĠĠĠĠĠ Ġ/** ĠHack y Ġparse Ġof Ġa ĠSVG , Ġlike Ġwhat ĠSt ipple Gen 2 Ġproduces Ġ*/ ĊĠĠĠĠĠĠĠ Ġfun Ġfile To Path ( svg Xml File : ĠFile ): ĠList < Vector 2 D > Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġassert ( svg Xml File . can Read ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġdoc Ġ= ĠDocument BuilderFactory . newInstance (). new Document Builder (). parse ( svg Xml File ) !! ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġpath Element Ġ= Ġdoc . getElementsByTagName (" path ") !!. item ( 0 ) !! Ġas ĠElement ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġpen Ġ= ĠScanner ( path Element . getAttribute (" d ")) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġpen . next () Ġ// Ġdiscard Ġthe Ġfirst Ġcharacter ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġpoints Ġ= Ġmutable ListOf < Vector 2 D >() ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhile Ġ( pen . hasNext ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpoints . add ( Vector 2 D ( pen . next Double (), Ġpen . next Double ())) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġpoints ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* ĠDelete Ġany Ġmid points Ġthat Ġaren 't Ġ" interest ing Ġenough " Ġto Ġfall Ġoutside Ġthe Ġerror Ġbar ĊĠĠĠĠĠĠĠĠ Ġ* ĠRe cursively Ġsub div ides ĊĠĠĠĠĠĠĠĠ Ġ* Ġhttps :// en . wikipedia . org / wiki / R amer % E 2 % 8 0 % 9 3 D ou glas % E 2 % 8 0 % 9 3 Pe u cker _ algorithm ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġprivate Ġfun Ġr amer D ou glas Pe u cker Recursion ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġpoints : ĠList < Normal Vector 2 D >, ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmax Distance Allowed : ĠDouble ĊĠĠĠĠĠĠĠ Ġ): ĠList < Normal Vector 2 D > Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( points . size Ġ<= Ġ 2 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġpoints ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġline Ġ= ĠLine ( points . first (), Ġpoints . last (), Ġ 1 . 0 E - 1 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġdistances Ġ= Ġpoints . map Indexed Ġ{ Ġindex , Ġn vector 2 D Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġindex Ġto Ġn vector 2 D ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}. filter Ġ{ Ġ( index , Ġ_) Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġindex Ġ!= Ġ 0 Ġ&& Ġindex Ġ!= Ġpoints . size Ġ- Ġ 1 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}. map Ġ{ Ġ( index , Ġvector 2 D ) Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġindex Ġto Ġline . distance ( vector 2 D ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġ( max Idx , Ġmax Dist ) Ġ= Ġdistances . max By OrNull Ġ{ Ġ(_, Ġdistance ) Ġ-> Ġdistance Ġ} !! ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġif Ġ( max Dist Ġ< Ġmax Distance Allowed ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠlistOf ( points . first (), Ġpoints . last ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġleft Side Ġ= Ġr amer D ou glas Pe u cker Recursion ( points . sub List ( 0 , Ġmax Idx Ġ+ Ġ 1 ), Ġmax Distance Allowed ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġright Side Ġ= Ġr amer D ou glas Pe u cker Recursion ( points . sub List ( max Idx , Ġpoints . size ), Ġmax Distance Allowed ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġleft Side . plus ( right Side . drop ( 1 )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } ĊĊĊĊĊĊĊĊ ĊĊĊĊĊĊ