/* Ċ Ġ* ĠCopyright Ġ 2 0 1 9 ĠPeter ĠRes pon dek Ċ Ġ* Ċ Ġ* ĠLicensed Ġunder Ġthe ĠApache ĠLicense , ĠVersion Ġ 2 . 0 Ġ( the Ġ" License "); Ċ Ġ* Ġyou Ġmay Ġnot Ġuse Ġthis Ġfile Ġexcept Ġin Ġcompliance Ġwith Ġthe ĠLicense . Ċ Ġ* ĠYou Ġmay Ġobtain Ġa Ġcopy Ġof Ġthe ĠLicense Ġat Ċ Ġ* Ċ Ġ* ĠĠĠĠ Ġhttps :// www . apache . org / licenses / LICENSE - 2 . 0 Ċ Ġ* Ċ Ġ* ĠUnless Ġrequired Ġby Ġapplicable Ġlaw Ġor Ġagreed Ġto Ġin Ġwriting , Ġsoftware Ċ Ġ* Ġdistributed Ġunder Ġthe ĠLicense Ġis Ġdistributed Ġon Ġan Ġ" AS ĠIS " ĠBASIS , Ċ Ġ* ĠWITHOUT ĠWARRANTIES ĠOR ĠCONDITIONS ĠOF ĠANY ĠKIND , Ġeither Ġexpress Ġor Ġimplied . Ċ Ġ* ĠSee Ġthe ĠLicense Ġfor Ġthe Ġspecific Ġlanguage Ġgoverning Ġpermissions Ġand Ċ Ġ* Ġlimitations Ġunder Ġthe ĠLicense . Ċ Ġ*/ Ċ Ċ package Ġcom . l any ard . library Ċ import Ġandroid . graphics . Point Ċ import Ġandroid . graphics . PointF Ċ import Ġcom . l any ard . helpers . distance Ċ import Ġcom . l any ard . helpers . to Point Ċ import Ġkotlin . math . min Ċ Ċ /** Ċ Ġ* ĠP lots Ġa Ġcard inal Ġspline Ġgiven Ġa Ġlist Ġof Ġcoordinates Ċ Ġ* Ċ Ġ* Ġ@ author ĠPeter ĠRes pon dek Ċ Ġ*/ Ċ Ċ class ĠCard inal Spline Ġ( path Ġ: ĠList < Point >, Ġt ension : ĠFloat Ġ= Ġ 0 . 5 F Ġ) Ġ{ ĊĠĠĠ Ġdata Ġclass ĠDistance TableEntry Ġ( Ġvar Ġt : ĠFloat , Ġvar Ġdistance : ĠFloat Ġ) Ġ{ ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġvar Ġlength Ġ: ĠFloat Ġ= Ġ 0 . 0 F ĊĠĠĠ Ġvar Ġpath Ġ: ĠMutable List < Point > ĊĊĠĠĠ Ġvar Ġt ension Ġ: ĠFloat ĊĊĠĠĠ Ġinit Ġ{ ĊĠĠĠĠĠĠĠ Ġthis . path Ġ= Ġpath . to Mutable List () ĊĠĠĠĠĠĠĠ Ġthis . t ension Ġ= Ġt ension ĊĠĠĠĠĠĠĠ Ġvar Ġdist Ġ: ĠFloat Ġ= Ġ 0 . 0 F ĊĠĠĠĠĠĠĠ Ġif Ġ( Ġthis . path . size Ġ!= Ġ 0 Ġ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( Ġsegment Ġin Ġ 1 Ġuntil Ġthis . path . size Ġ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdist Ġ+= Ġthis . path [ segment Ġ- Ġ 1 ]. distance ( Ġthis . path [ segment ] Ġ). toFloat () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġthis . length Ġ= Ġdist ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġl erp ( a : ĠFloat , b : ĠFloat , f : ĠFloat ) Ġ: ĠFloat ĊĠĠĠ Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġa Ġ+ Ġf Ġ* Ġ( b Ġ- Ġa ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠEvalu ates Ġa Ġcurve Ġwith Ġfour Ġpoints Ġusing Ġthe ĠCat m ull - Rom Ġmethod ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param Ġt ension Ġhow Ġta ught Ġthe Ġcurve Ġis . ĠBet ween Ġ 0 . 0 f Ġand Ġ 1 . 0 f ĊĠĠĠĠ Ġ* Ġ@ param Ġt Ġtime Ġto Ġevaluate ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġevaluate ( p 0 : ĠPoint , Ġp 1 : ĠPoint , Ġp 2 : ĠPoint , Ġp 3 : ĠPoint , Ġt ension : ĠFloat , Ġt : ĠFloat ) Ġ: ĠPoint F ĊĠĠĠ Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġt 2 Ġ= Ġt Ġ* Ġt ĊĠĠĠĠĠĠĠ Ġval Ġt 3 Ġ= Ġt 2 Ġ* Ġt ĊĊĠĠĠĠĠĠĠ Ġval Ġs Ġ= Ġ( 1 Ġ- Ġt ension ) Ġ/ Ġ 2 ĊĊĠĠĠĠĠĠĠ Ġval Ġb 1 Ġ= Ġs Ġ* Ġ(( - t 3 Ġ+ Ġ( 2 Ġ* Ġt 2 )) Ġ- Ġt ) ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġs (- t 3 Ġ+ Ġ 2 Ġt 2 Ġ- Ġt ) P 1 ĊĠĠĠĠĠĠĠ Ġval Ġb 2 Ġ= Ġs Ġ* Ġ(- t 3 Ġ+ Ġt 2 ) Ġ+ Ġ( 2 Ġ* Ġt 3 Ġ- Ġ 3 Ġ* Ġt 2 Ġ+ Ġ 1 ) ĠĠĠĠĠĠĠĠĠ Ġ// Ġs (- t 3 Ġ+ Ġt 2 ) P 2 Ġ+ Ġ( 2 Ġt 3 Ġ- Ġ 3 Ġt 2 Ġ+ Ġ 1 ) P 2 ĊĠĠĠĠĠĠĠ Ġval Ġb 3 Ġ= Ġs Ġ* Ġ( t 3 Ġ- Ġ 2 Ġ* Ġt 2 Ġ+ Ġt ) Ġ+ Ġ(- 2 Ġ* Ġt 3 Ġ+ Ġ 3 Ġ* Ġt 2 ) ĠĠĠĠĠ Ġ// Ġs ( t 3 Ġ- Ġ 2 Ġt 2 Ġ+ Ġt ) P 3 Ġ+ Ġ(- 2 Ġt 3 Ġ+ Ġ 3 Ġt 2 ) P 3 ĊĠĠĠĠĠĠĠ Ġval Ġb 4 Ġ= Ġs Ġ* Ġ( t 3 Ġ- Ġt 2 ); ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġs ( t 3 Ġ- Ġt 2 ) P 4 ĊĊĠĠĠĠĠĠĠ Ġval Ġx Ġ= Ġ( p 0 . x * b 1 Ġ+ Ġp 1 . x * b 2 Ġ+ Ġp 2 . x * b 3 Ġ+ Ġp 3 . x * b 4 ) ĊĠĠĠĠĠĠĠ Ġval Ġy Ġ= Ġ( p 0 . y * b 1 Ġ+ Ġp 1 . y * b 2 Ġ+ Ġp 2 . y * b 3 Ġ+ Ġp 3 . y * b 4 ) ĊĊĠĠĠĠĠĠĠ Ġreturn ĠPoint F ( x , y ) ĊĠĠĠ Ġ} ĊĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠEvalu ates Ġa Ġcurve Ġwith Ġany Ġnumber Ġof Ġpoints Ġusing Ġthe ĠCat m ull - Rom Ġmethod ĊĠĠĠĠ Ġ* Ġ@ param Ġtime Ġtime Ġalong Ġcurve Ġto Ġevaluate Ġ 0 . 0 f Ġto Ġ 1 . 0 f ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ return Ġposition Ġalong Ġcurve ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġevaluate Curve ( Ġtime : ĠFloat Ġ) Ġ: ĠPoint F ĊĠĠĠ Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġp Ġ: ĠInt ĊĠĠĠĠĠĠĠ Ġval Ġlt Ġ: ĠFloat ĊĠĠĠĠĠĠĠ Ġval Ġdelta T Ġ= Ġ 1 . 0 F Ġ/ Ġ( path . size Ġ- Ġ 1 ) ĊĊĠĠĠĠĠĠĠ Ġif Ġ( Ġtime Ġ== Ġ 1 . 0 F Ġ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġp Ġ= Ġpath . size Ġ- Ġ 1 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlt Ġ= Ġ 1 . 0 F ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġp Ġ= Ġ( time Ġ/ Ġdelta T ). toInt () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlt Ġ= Ġ( time Ġ- Ġdelta T Ġ* Ġp ) Ġ/ Ġdelta T ; ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġvar Ġi 0 Ġ: ĠInt Ġ= Ġp - 1 ĊĠĠĠĠĠĠĠ Ġif Ġ( p Ġ== Ġ 0 ) Ġ{ Ġi 0 Ġ= Ġ 0 Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġi 1 Ġ: ĠInt Ġ= Ġp ĊĠĠĠĠĠĠĠ Ġval Ġi 2 Ġ: ĠInt Ġ= Ġmin ( path . size Ġ- Ġ 1 , Ġp + 1 ) ĊĠĠĠĠĠĠĠ Ġval Ġi 3 Ġ: ĠInt Ġ= Ġmin ( path . size Ġ- Ġ 1 , Ġp + 2 ) ĊĊĠĠĠĠĠĠĠ Ġ// ĠInterpol ate ĊĠĠĠĠĠĠĠ Ġval Ġpp 0 Ġ= Ġpath [ i 0 ] ĊĠĠĠĠĠĠĠ Ġval Ġpp 1 Ġ= Ġpath [ i 1 ] ĊĠĠĠĠĠĠĠ Ġval Ġpp 2 Ġ= Ġpath [ i 2 ] ĊĠĠĠĠĠĠĠ Ġval Ġpp 3 Ġ= Ġpath [ i 3 ] ĊĊĠĠĠĠĠĠĠ Ġreturn Ġevaluate ( pp 0 , Ġpp 1 , Ġpp 2 , Ġpp 3 , Ġt ension , Ġlt ) ĊĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġcreate Distance Table ( Ġtable : ĠMutable List < Distance TableEntry > Ġ) ĊĠĠĠ Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġnum Points Min 1 Ġ= Ġpath . size Ġ- Ġ 1 ; ĊĊĠĠĠĠĠĠĠ Ġvar Ġdist So Far Ġ= Ġ 0 . 0 F ĊĊĠĠĠĠĠĠĠ Ġval Ġstart Ġ= ĠDistance TableEntry ( 0 . 0 F , 0 . 0 F ) ĊĠĠĠĠĠĠĠ Ġtable . add ( start ) ĊĠĠĠĠĠĠĠ Ġfor Ġ( Ġi Ġin Ġ 1 Ġuntil Ġpath . size Ġ){ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġdist Ġ= Ġpath [ i - 1 ]. distance ( path [ i ]) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdist So Far Ġ+= Ġdist . toFloat () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcurr Ġ= ĠDistance TableEntry ( Ġi . toFloat () Ġ/ Ġnum Points Min 1 , Ġdist So Far Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtable . add ( Ġcurr Ġ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠSplit Ġcurve Ġinto Ġa Ġnumber Ġof Ġsegments . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġget Non Uniform ( Ġsegments : ĠInt Ġ) ĊĠĠĠ Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġarray Ġ= Ġmutable ListOf < Point >() ĊĠĠĠĠĠĠĠ Ġval Ġnum Points Desired Min 1 Ġ= Ġsegments - 1 ĊĠĠĠĠĠĠĠ Ġfor Ġ( Ġi Ġin Ġ 0 Ġuntil Ġsegments Ġ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġt Ġ= Ġi . toFloat () Ġ/ Ġnum Points Desired Min 1 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġarray . add ( evaluate Curve ( t ). to Point ()) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġpath Ġ= Ġarray ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠModify Ġthe Ġcurve Ġso Ġpoints Ġare Ġ( rough ly ) Ġequ ally Ġsp aced ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param Ġsegments Ġnumber Ġof Ġpoints Ġthe Ġcurve Ġshould Ġhave ĊĠĠĠĠ Ġ*/ ĊĊĠĠĠ Ġfun Ġget Uniform ( Ġsegments : ĠInt Ġ) ĊĠĠĠ Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġarray Ġ= Ġmutable ListOf < Point >() ĊĠĠĠĠĠĠĠ Ġval Ġdist Table Ġ= Ġmutable ListOf < Distance TableEntry >() ĊĠĠĠĠĠĠĠ Ġcreate Distance Table ( Ġdist Table Ġ) ĊĠĠĠĠĠĠĠ Ġval Ġnum Points Desired Min 1 Ġ= Ġsegments - 1 ĊĠĠĠĠĠĠĠ Ġval Ġtotal Length Ġ= Ġdist Table [ path . size - 1 ]. distance ; ĊĊĠĠĠĠĠĠĠ Ġfor Ġ( Ġi Ġin Ġ 0 Ġuntil Ġsegments Ġ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġdist T Ġ= Ġi . toFloat () Ġ/ Ġnum Points Desired Min 1 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġdistance Ġ= Ġdist T Ġ* Ġtotal Length ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġt Ġ= Ġtime Value From Dist ( Ġdistance , Ġdist Table Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġp Ġ= Ġevaluate Curve ( Ġt Ġ). to Point () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġarray . add ( p ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġpath Ġ= Ġarray ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġtime Value From Dist ( Ġdist : ĠFloat , Ġtable : ĠMutable List < Distance TableEntry > Ġ) Ġ: ĠFloat ĊĠĠĠ Ġ{ ĊĠĠĠĠĠĠĠ Ġfor Ġ( Ġi Ġin Ġpath . size Ġ- Ġ 2 Ġdown To Ġ 0 Ġstep Ġ 1 Ġ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġentry Ġ= Ġtable [ i ]; ĊĠĠĠĠĠĠĠ Ġif Ġ( Ġdist Ġ> Ġentry . distance Ġ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif ( i Ġ== Ġthis . path . size - 1 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġ 1 . 0 F ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnext Entry Ġ= Ġtable [ i + 1 ]; ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġl erp T Ġ= Ġ( dist Ġ- Ġentry . distance ) Ġ/ Ġ( next Entry . distance Ġ- Ġentry . distance ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġt Ġ= Ġl erp ( entry . t , Ġnext Entry . t , Ġl erp T ); ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġt ; ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġ 0 . 0 F ĊĠĠĠ Ġ} Ċ Ċ }