package Ġorg . open rnd r . extra . shapes Ċ // ĠCode Ġadapted Ġfrom Ġhttp :// we itz . de / h obby / Ċ Ċ import Ġorg . open rnd r . math . Vector 2 Ċ import Ġorg . open rnd r . shape . Segment Ċ import Ġorg . open rnd r . shape . Shape Ċ import Ġorg . open rnd r . shape . Shape Contour Ċ import Ġkotlin . math . atan 2 Ċ import Ġkotlin . math . cos Ċ import Ġkotlin . math . sin Ċ import Ġkotlin . math . sqrt ĊĊ Ċ fun ĠShape Contour . h obby Curve () Ġ: ĠShape Contour Ġ{ ĊĠĠĠ Ġval Ġvertices Ġ= Ġsegments . map Ġ{ Ġit . start Ġ} ĊĠĠĠ Ġreturn Ġh obby Curve ( vertices , Ġclosed ) Ċ } Ċ Ċ fun ĠShape . h obby Curve () Ġ: ĠShape Ġ{ ĊĠĠĠ Ġreturn ĠShape ( cont ours . map Ġ{ ĊĠĠĠĠĠĠĠ Ġit . h obby Curve () ĊĠĠĠ Ġ}) Ċ } Ċ Ċ /** Ċ Ġ* ĠUses ĠH obby 's Ġalgorithm Ġto Ġconstruct Ġa Ġ[ Shape Contour ] Ġthrough Ġa Ġgiven Ġlist Ġof Ġpoints . Ċ Ġ* Ġ@ param Ġpoints ĠThe Ġlist Ġof Ġpoints Ġthrough Ġwhich Ġthe Ġcurve Ġshould Ġgo . Ċ Ġ* Ġ@ param Ġclosed ĠWhether Ġto Ġconstruct Ġa Ġclosed Ġor Ġopen Ġcurve . Ċ Ġ* Ġ@ param Ġcurl ĠThe Ġ' curl ' Ġat Ġthe Ġendpoints Ġof Ġthe Ġcurve ; Ġthis Ġis Ġonly Ġapplicable Ġwhen Ġ[ closed ] Ġis Ġfalse . ĠBest Ġresults Ġfor Ġvalues Ġin Ġ[- 1 , Ġ 1 ], Ġwhere Ġa Ġhigher Ġvalue Ġmakes Ġsegments Ġcloser Ġto Ġcircular Ġar cs . Ċ Ġ* Ġ@ return ĠA Ġ[ Shape Contour ] Ġthrough Ġ[ points ]. Ċ Ġ*/ Ċ fun Ġh obby Curve ( points : ĠList < Vector 2 >, Ġclosed : ĠBoolean Ġ= Ġfalse , Ġcurl : ĠDouble Ġ= Ġ 0 . 0 ): ĠShape Contour Ġ{ ĊĠĠĠ Ġif Ġ( points . size Ġ<= Ġ 1 ) Ġreturn ĠShape Contour . EMPTY ĊĊĠĠĠ Ġval Ġm Ġ= Ġpoints . size ĊĠĠĠ Ġval Ġn Ġ= Ġif Ġ( closed ) Ġm Ġelse Ġm Ġ- Ġ 1 ĊĊĠĠĠ Ġval Ġdiffs Ġ= ĠArray ( n ) Ġ{ Ġpoints [( it + 1 ) Ġ% Ġm ] Ġ- Ġpoints [ it ] Ġ} ĊĠĠĠ Ġval Ġdistances Ġ= ĠArray ( n ) Ġ{ Ġdiffs [ it ]. length Ġ} ĊĊĠĠĠ Ġval Ġgamma Ġ= ĠarrayOf Null s < Double >( m ) ĊĠĠĠ Ġfor Ġ( i Ġin Ġ( if Ġ( closed ) Ġ 0 Ġelse Ġ 1 ) Ġuntil Ġn ){ ĊĠĠĠĠĠĠĠ Ġval Ġk Ġ= Ġ( i Ġ+ Ġm Ġ- Ġ 1 ) Ġ% Ġm ĊĠĠĠĠĠĠĠ Ġval Ġn 1 Ġ= Ġdiffs [ k ]. normalized ĊĠĠĠĠĠĠĠ Ġval Ġs Ġ= Ġn 1 . y ĊĠĠĠĠĠĠĠ Ġval Ġc Ġ= Ġn 1 . x ĊĠĠĠĠĠĠĠ Ġval Ġv Ġ= Ġrotate ( dif fs [ i ], Ġ- s , Ġc ) ĊĠĠĠĠĠĠĠ Ġgamma [ i ] Ġ= Ġatan 2 ( v . y , Ġv . x ) ĊĠĠĠ Ġ} ĊĠĠĠ Ġif Ġ(! closed ) Ġgamma [ n ] Ġ= Ġ 0 . 0 ĊĊĠĠĠ Ġval Ġa Ġ= ĠarrayOf Null s < Double >( m ) ĊĠĠĠ Ġval Ġb Ġ= ĠarrayOf Null s < Double >( m ) ĊĠĠĠ Ġval Ġc Ġ= ĠarrayOf Null s < Double >( m ) ĊĠĠĠ Ġval Ġd Ġ= ĠarrayOf Null s < Double >( m ) ĊĊĠĠĠ Ġfor Ġ( i Ġin Ġ( if Ġ( closed ) Ġ 0 Ġelse Ġ 1 ) Ġuntil Ġn ){ ĊĠĠĠĠĠĠĠ Ġval Ġj Ġ= Ġ( i Ġ+ Ġ 1 ) Ġ% Ġm ĊĠĠĠĠĠĠĠ Ġval Ġk Ġ= Ġ( i Ġ+ Ġm Ġ- Ġ 1 ) Ġ% Ġm ĊĊĠĠĠĠĠĠĠ Ġa [ i ] Ġ= Ġ 1 Ġ/ Ġdistances [ k ] ĊĠĠĠĠĠĠĠ Ġb [ i ] Ġ= Ġ( 2 Ġ* Ġdistances [ k ] Ġ+ Ġ 2 Ġ* Ġdistances [ i ]) Ġ/ Ġ( distances [ k ] Ġ* Ġdistances [ i ]) ĊĠĠĠĠĠĠĠ Ġc [ i ] Ġ= Ġ 1 Ġ/ Ġdistances [ i ] ĊĠĠĠĠĠĠĠ Ġd [ i ] Ġ= Ġ-( 2 Ġ* Ġgamma [ i ] !! Ġ* Ġdistances [ i ] Ġ+ Ġgamma [ j ] !! Ġ* Ġdistances [ k ]) Ġ/ Ġ( distances [ k ] Ġ* Ġdistances [ i ]) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġlateinit Ġvar Ġalpha : ĠArray < Double > ĊĠĠĠ Ġlateinit Ġvar Ġbeta : ĠArray < Double ?> ĊĊĠĠĠ Ġif Ġ(! closed ) Ġ{ ĊĠĠĠĠĠĠĠ Ġa [ 0 ] Ġ= Ġ 0 . 0 ĊĠĠĠĠĠĠĠ Ġb [ 0 ] Ġ= Ġ 2 Ġ+ Ġcurl ĊĠĠĠĠĠĠĠ Ġc [ 0 ] Ġ= Ġ 2 Ġ* Ġcurl Ġ+ Ġ 1 ĊĠĠĠĠĠĠĠ Ġd [ 0 ] Ġ= Ġ- c [ 0 ] !! Ġ* Ġgamma [ 1 ] !! ĊĊĠĠĠĠĠĠĠ Ġa [ n ] Ġ= Ġ 2 Ġ* Ġcurl Ġ+ Ġ 1 ĊĠĠĠĠĠĠĠ Ġb [ n ] Ġ= Ġ 2 Ġ+ Ġcurl ĊĠĠĠĠĠĠĠ Ġc [ n ] Ġ= Ġ 0 . 0 ĊĠĠĠĠĠĠĠ Ġd [ n ] Ġ= Ġ 0 . 0 ĊĊĠĠĠĠĠĠĠ Ġalpha Ġ= Ġth omas ( a . require No Null s (), Ġb . require No Null s (), Ġc . require No Null s (), Ġd . require No Null s ()) ĊĠĠĠĠĠĠĠ Ġbeta Ġ= ĠarrayOf Null s ( n ) ĊĠĠĠĠĠĠĠ Ġfor Ġ( i Ġin Ġ 0 Ġuntil Ġn - 1 ){ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbeta [ i ] Ġ= Ġ- gamma [ i + 1 ] !! Ġ- Ġalpha [ i + 1 ] ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġbeta [ n - 1 ] Ġ= Ġ- alpha [ n ] ĊĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġs Ġ= Ġa [ 0 ] !! ĊĠĠĠĠĠĠĠ Ġa [ 0 ] Ġ= Ġ 0 . 0 ĊĠĠĠĠĠĠĠ Ġval Ġt Ġ= Ġc [ n - 1 ] !! ĊĠĠĠĠĠĠĠ Ġc [ n - 1 ] Ġ= Ġ 0 . 0 ĊĠĠĠĠĠĠĠ Ġalpha Ġ= Ġsh er man ( a . require No Null s (), Ġb . require No Null s (), Ġc . require No Null s (), Ġd . require No Null s (), Ġs , Ġt ) ĊĠĠĠĠĠĠĠ Ġbeta Ġ= ĠarrayOf Null s ( n ) ĊĠĠĠĠĠĠĠ Ġfor Ġ( i Ġin Ġ 0 Ġuntil Ġn ){ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġj Ġ= Ġ( i + 1 ) Ġ% Ġn ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbeta [ i ] Ġ= Ġ- gamma [ j ] !! Ġ- Ġalpha [ j ] ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġval Ġc 1 s Ġ= Ġmutable ListOf < Vector 2 >() ĊĠĠĠ Ġval Ġc 2 s Ġ= Ġmutable ListOf < Vector 2 >() ĊĠĠĠ Ġfor Ġ( i Ġin Ġ 0 Ġuntil Ġn ){ ĊĠĠĠĠĠĠĠ Ġval Ġv 1 Ġ= Ġrotate Angle ( dif fs [ i ], Ġalpha [ i ]). normalized ĊĠĠĠĠĠĠĠ Ġval Ġv 2 Ġ= Ġrotate Angle ( dif fs [ i ], Ġ- beta [ i ] !! ). normalized ĊĠĠĠĠĠĠĠ Ġc 1 s . add ( points [ i Ġ% Ġm ] Ġ+ Ġv 1 Ġ* Ġrho ( alpha [ i ], Ġbeta [ i ] !! ) Ġ* Ġdistances [ i ] Ġ/ Ġ 3 . 0 ) ĊĠĠĠĠĠĠĠ Ġc 2 s . add ( points [( i + 1 ) Ġ% Ġm ] Ġ- Ġv 2 Ġ* Ġrho ( beta [ i ] !! , Ġalpha [ i ]) Ġ* Ġdistances [ i ] Ġ/ Ġ 3 . 0 ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġreturn ĠShape Contour ( List ( n ) Ġ{ ĠSegment ( points [ it ], Ġc 1 s [ it ], Ġc 2 s [ it ], Ġpoints [( it + 1 )% m ]) Ġ}, Ġclosed = closed ) Ċ } Ċ Ċ private Ġfun Ġth omas ( a : ĠArray < Double >, Ġb : ĠArray < Double >, Ġc : ĠArray < Double >, Ġd : ĠArray < Double >): ĠArray < Double > Ġ{ ĊĠĠĠ Ġval Ġn Ġ= Ġa . size ĊĠĠĠ Ġval Ġcc Ġ= ĠarrayOf Null s < Double >( n ) ĊĠĠĠ Ġval Ġdd Ġ= ĠarrayOf Null s < Double >( n ) ĊĠĠĠ Ġcc [ 0 ] Ġ= Ġc [ 0 ] Ġ/ Ġb [ 0 ] ĊĠĠĠ Ġdd [ 0 ] Ġ= Ġd [ 0 ] Ġ/ Ġb [ 0 ] ĊĠĠĠ Ġfor Ġ( i Ġin Ġ 1 Ġuntil Ġn ){ ĊĠĠĠĠĠĠĠ Ġval Ġden Ġ= Ġb [ i ] Ġ- Ġcc [ i - 1 ] !! Ġ* Ġa [ i ] ĊĠĠĠĠĠĠĠ Ġcc [ i ] Ġ= Ġc [ i ] Ġ/ Ġden ĊĠĠĠĠĠĠĠ Ġdd [ i ] Ġ= Ġ( d [ i ] Ġ- Ġdd [ i - 1 ] !! * a [ i ]) Ġ/ Ġden ĊĠĠĠ Ġ} ĊĠĠĠ Ġval Ġx Ġ= ĠarrayOf Null s < Double >( n ) ĊĠĠĠ Ġx [ n - 1 ] Ġ= Ġdd [ n - 1 ] ĊĠĠĠ Ġfor Ġ( i Ġin Ġn - 2 Ġdown To Ġ 0 ){ ĊĠĠĠĠĠĠĠ Ġx [ i ] Ġ= Ġdd [ i ] !! Ġ- Ġcc [ i ] !! Ġ* Ġx [ i + 1 ] !! ĊĠĠĠ Ġ} ĊĠĠĠ Ġreturn Ġx . require No Null s () Ċ } Ċ Ċ private Ġfun Ġsh er man ( a : ĠArray < Double >, Ġb : ĠArray < Double >, Ġc : ĠArray < Double >, Ġd : ĠArray < Double >, Ġs : ĠDouble , Ġt : ĠDouble ): ĠArray < Double > Ġ{ ĊĠĠĠ Ġval Ġn Ġ= Ġa . size ĊĠĠĠ Ġval Ġu Ġ= ĠArray ( n ) Ġ{ Ġif Ġ( it Ġ== Ġ 0 Ġ|| Ġit Ġ== Ġn - 1 ) Ġ 1 . 0 Ġelse Ġ 0 . 0 Ġ} ĊĠĠĠ Ġval Ġv Ġ= ĠArray ( n ) Ġ{ Ġwhen Ġ( it ){ Ġ 0 Ġ-> Ġt ; Ġn - 1 Ġ-> Ġs ; Ġelse Ġ-> Ġ 0 . 0 Ġ} Ġ} ĊĠĠĠ Ġb [ 0 ] Ġ-= Ġt ĊĠĠĠ Ġb [ n - 1 ] Ġ-= Ġs ĊĠĠĠ Ġval ĠT d Ġ= Ġth omas ( a , Ġb , Ġc , Ġd ) ĊĠĠĠ Ġval ĠT u Ġ= Ġth omas ( a , Ġb , Ġc , Ġu ) ĊĠĠĠ Ġval Ġfactor Ġ= Ġ( t Ġ* ĠT d [ 0 ] Ġ+ Ġs * Td [ n - 1 ]) Ġ/ Ġ( 1 Ġ+ Ġt Ġ* ĠT u [ 0 ] Ġ+ Ġs * Tu [ n - 1 ]) ĊĠĠĠ Ġreturn ĠArray ( n ) Ġ{ ĊĠĠĠĠĠĠĠ ĠT d [ it ] Ġ- Ġfactor Ġ* ĠT u [ it ] ĊĠĠĠ Ġ} Ċ } Ċ Ċ private Ġfun Ġrho ( a : ĠDouble , Ġb : ĠDouble ): ĠDouble Ġ{ ĊĠĠĠ Ġval Ġsa Ġ= Ġsin ( a ) ĊĠĠĠ Ġval Ġsb Ġ= Ġsin ( b ) ĊĠĠĠ Ġval Ġca Ġ= Ġcos ( a ) ĊĠĠĠ Ġval Ġcb Ġ= Ġcos ( b ) ĊĠĠĠ Ġval Ġs 5 Ġ= Ġsqrt ( 5 . 0 ) ĊĠĠĠ Ġval Ġnum Ġ= Ġ 4 Ġ+ Ġsqrt ( 8 . 0 ) Ġ* Ġ( sa Ġ- Ġsb / 1 6 ) Ġ* Ġ( sb Ġ- Ġsa / 1 6 ) Ġ* Ġ( ca Ġ- Ġcb ) ĊĠĠĠ Ġval Ġden Ġ= Ġ 2 Ġ+ Ġ( s 5 Ġ- Ġ 1 ) Ġ* Ġca Ġ+ Ġ( 3 Ġ- Ġs 5 ) Ġ* Ġcb ĊĠĠĠ Ġreturn Ġnum / den Ċ } Ċ Ċ private Ġfun Ġrotate ( v : ĠVector 2 , Ġs : ĠDouble , Ġc : ĠDouble ) Ġ= ĠVector 2 ( v . x Ġ* Ġc Ġ- Ġv . y Ġ* Ġs , Ġv . x Ġ* Ġs Ġ+ Ġv . y Ġ* Ġc ) Ċ private Ġfun Ġrotate Angle ( v : ĠVector 2 , Ġalpha : ĠDouble ) Ġ= Ġrotate ( v , Ġsin ( alpha ), Ġcos ( alpha )) ĊĊ