package Ġnet . d ink la . ray tracer challenge . math Ċ Ċ import Ġnet . d ink la . ray tracer challenge . math . Approx . is Difference Small Ċ import Ġjava . util . Objects Ċ import Ġkotlin . math . sqrt Ċ Ċ type alias ĠVector Ġ= ĠTuple Ċ type alias ĠPoint Ġ= ĠTuple Ċ Ċ data Ġclass ĠTuple ( val Ġx : ĠDouble , Ġval Ġy : ĠDouble , Ġval Ġz : ĠDouble , Ġval Ġw : ĠDouble ) Ġ{ ĊĠĠĠ Ġfun Ġis Point (): ĠBoolean Ġ= Ġw Ġ== Ġ 1 . 0 ĊĊĠĠĠ Ġfun Ġis Vector (): ĠBoolean Ġ Ġ= Ġw Ġ== Ġ 0 . 0 ĊĊĠĠĠ Ġoperator Ġfun Ġplus ( t : ĠTuple ): ĠTuple Ġ{ ĊĠĠĠĠĠĠĠ Ġassert ( w Ġ+ Ġt . w Ġ<= Ġ 1 . 0 ) ĊĠĠĠĠĠĠĠ Ġreturn ĠTuple ( x Ġ+ Ġt . x , Ġy Ġ+ Ġt . y , Ġz Ġ+ Ġt . z , w Ġ+ Ġt . w ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoperator Ġfun Ġminus ( t : ĠTuple ): ĠTuple Ġ{ ĊĠĠĠĠĠĠĠ Ġassert ( w Ġ- Ġt . w Ġ>= Ġ 0 . 0 ) ĊĠĠĠĠĠĠĠ Ġreturn ĠTuple ( x Ġ- Ġt . x , Ġy Ġ- Ġt . y , Ġz Ġ- Ġt . z , w Ġ- Ġt . w ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoperator Ġfun Ġunary Minus () Ġ= ĠTuple (- x , Ġ- y , Ġ- z , Ġ- w ) ĊĊĠĠĠ Ġoperator Ġfun Ġtimes ( s : ĠDouble ) Ġ= ĠTuple ( x Ġ* Ġs , Ġy Ġ* Ġs , Ġz Ġ* Ġs , Ġw Ġ* Ġs ) ĊĊĠĠĠ Ġoperator Ġfun Ġdiv ( s : ĠDouble ) Ġ= ĠTuple ( x Ġ/ Ġs , Ġy Ġ/ Ġs , Ġz Ġ/ Ġs , Ġw Ġ/ Ġs ) ĊĊĠĠĠ Ġin fix Ġfun Ġdot ( v : ĠVector ): ĠDouble Ġ{ ĊĠĠĠĠĠĠĠ Ġassert ( is Vector ()) ĊĠĠĠĠĠĠĠ Ġassert ( v . is Vector ()) ĊĠĠĠĠĠĠĠ Ġreturn Ġx Ġ* Ġv . x Ġ+ Ġy Ġ* Ġv . y Ġ+ Ġz Ġ* Ġv . z Ġ// Ġ+ Ġw Ġ* Ġt . w ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġin fix Ġfun Ġcross ( v : ĠVector ): ĠVector Ġ{ ĊĠĠĠĠĠĠĠ Ġassert ( is Vector ()) ĊĠĠĠĠĠĠĠ Ġassert ( v . is Vector ()) ĊĠĠĠĠĠĠĠ Ġreturn Ġvector ( y Ġ* Ġv . z Ġ- Ġz Ġ* Ġv . y , Ġz Ġ* Ġv . x Ġ- Ġx Ġ* Ġv . z , Ġx Ġ* Ġv . y Ġ- Ġy Ġ* Ġv . x ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġmagnitude (): ĠDouble Ġ{ ĊĠĠĠĠĠĠĠ Ġassert ( is Vector ()) ĊĠĠĠĠĠĠĠ Ġfun Ġsq r Length (): ĠDouble Ġ= Ġx Ġ* Ġx Ġ+ Ġy Ġ* Ġy Ġ+ Ġz Ġ* Ġz Ġ// Ġ+ Ġw Ġ* Ġw Ġ Ġw Ġis Ġ 0 . 0 Ġfor Ġvector ĊĠĠĠĠĠĠĠ Ġreturn Ġsqrt ( sqr Length ()) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġnormalize (): ĠVector Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġl Ġ= Ġmagnitude () ĊĠĠĠĠĠĠĠ Ġreturn Ġvector ( x Ġ/ Ġl , Ġy Ġ/ Ġl , Ġz Ġ/ Ġl ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġequals ( other : ĠAny ?): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġp : ĠTuple Ġ= Ġother Ġas ? ĠTuple Ġ?: Ġreturn Ġfalse ĊĠĠĠĠĠĠĠ Ġreturn Ġis Difference Small ( x , Ġp . x ) Ġ&& Ġis Difference Small ( y , Ġp . y ) Ġ&& Ġis Difference Small ( z , Ġp . z ) Ġ&& Ġw Ġ== Ġp . w ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun ĠhashCode (): ĠInt Ġ= ĠObjects . hash ( x , Ġy , Ġz , Ġw ) ĊĊĠĠĠ Ġfun Ġreflect ( normal : ĠVector ): ĠVector Ġ= Ġthis Ġ- Ġ( normal Ġ* Ġ 2 . 0 Ġ* Ġ( this Ġdot Ġnormal )) ĊĊĠĠĠ Ġfun Ġto Vector (): ĠVector Ġ= ĠTuple ( x , Ġy , Ġz , Ġ 0 . 0 ) ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġval ĠOR IGIN Ġ= Ġpoint ( 0 , Ġ 0 , Ġ 0 ) ĊĠĠĠĠĠĠĠ Ġval ĠUP Ġ= Ġvector ( 0 , Ġ 1 , Ġ 0 ) ĊĠĠĠ Ġ} Ċ } Ċ Ċ fun Ġtuple ( x : ĠInt , Ġy : ĠInt , Ġz : ĠInt , Ġw : ĠInt ) Ġ= ĠTuple ( x . toDouble (), Ġy . toDouble (), Ġz . toDouble (), Ġw . toDouble ()) Ċ Ċ fun Ġpoint ( x : ĠInt , Ġy : ĠInt , Ġz : ĠInt ) Ġ= ĠTuple ( x . toDouble (), Ġy . toDouble (), Ġz . toDouble (), Ġ 1 . 0 ) Ċ fun Ġpoint ( x : ĠDouble , Ġy : ĠDouble , Ġz : ĠDouble ) Ġ= ĠTuple ( x , Ġy , Ġz , Ġ 1 . 0 ) Ċ Ċ fun Ġvector ( x : ĠInt , Ġy : ĠInt , Ġz : ĠInt ) Ġ= ĠTuple ( x . toDouble (), Ġy . toDouble (), Ġz . toDouble (), Ġ 0 . 0 ) Ċ fun Ġvector ( x : ĠDouble , Ġy : ĠDouble , Ġz : ĠDouble ) Ġ= ĠTuple ( x , Ġy , Ġz , Ġ 0 . 0 ) Ċ