/**
 * Copyright(c) Live2D Inc. All rights reserved.
 *
 * Use of this source code is governed by the Live2D Open Software license
 * that can be found at https://www.live2d.com/eula/live2d-open-software-license-agreement_en.html.
 */ import { CubismVector2 } from './cubismvector2' ; /**
 * 数値計算などに使用するユーティリティクラス
 */ export class CubismMath { static readonly Epsilon : number = 0.00001 ; param value param min param max return static range ( value , min , max ) { if ( value < min ) { value = min ; } else if ( value > max ) { value = max ; } return value ; } param x return static sin ( x ) { return Math . sin ( x ) ; } param x return static cos ( x ) { return Math . cos ( x ) ; } param x return static abs ( x ) { return Math . abs ( x ) ; } param x return static sqrt ( x ) { return Math . sqrt ( x ) ; } param x return static cbrt ( x ) { if ( x === 0 ) { return x ; } let cx = x ; const isNegativeNumber = cx < 0 ; if ( isNegativeNumber ) { cx = - cx ; } let ret ; if ( cx === Infinity ) { ret = Infinity ; } else { ret = Math . exp ( Math . log ( cx ) / 3 ) ; ret = ( cx / ( ret * ret ) + 2 * ret ) / 3 ; } return isNegativeNumber ? - ret : ret ; } param value return static getEasingSine ( value ) { if ( value < 0.0 ) { return 0.0 ; } else if ( value > 1.0 ) { return 1.0 ; } return 0.5 - 0.5 * this . cos ( value * Math . PI ) ; } param left param right return static max ( left , right ) { return left > right ? left : right ; } param left param right return static min ( left , right ) { return left > right ? right : left ; } param degrees return static degreesToRadian ( degrees ) { return ( degrees / 180.0 ) * Math . PI ; } param radian return static radianToDegrees ( radian ) { return ( radian * 180.0 ) / Math . PI ; } param from param to return static directionToRadian ( from , to ) { const q1 = Math . atan2 ( to . y , to . x ) ; const q2 = Math . atan2 ( from . y , from . x ) ; let ret = q1 - q2 ; while ( ret < - Math . PI ) { ret += Math . PI * 2.0 ; } while ( ret > Math . PI ) { ret -= Math . PI * 2.0 ; } return ret ; } param from param to return static directionToDegrees ( from , to ) { const radian = this . directionToRadian ( from , to ) ; let degree = this . radianToDegrees ( radian ) ; if ( to . x - from . x > 0.0 ) { degree = - degree ; } return degree ; } param totalAngle return static radianToDirection ( totalAngle ) { const ret = new CubismVector2 ( ) ; ret . x = this . sin ( totalAngle ) ; ret . y = this . cos ( totalAngle ) ; return ret ; } param a param b param c return static quadraticEquation ( a , b , c ) { if ( this . abs ( a ) < CubismMath . Epsilon ) { if ( this . abs ( b ) < CubismMath . Epsilon ) { return - c ; } return - c / b ; } return - ( b + this . sqrt ( b * b - 4.0 * a * c ) ) / ( 2.0 * a ) ; } param a param b param c param d return static cardanoAlgorithmForBezier ( a , b , c , d ) { if ( this . sqrt ( a ) < CubismMath . Epsilon ) { return this . range ( this . quadraticEquation ( b , c , d ) , 0.0 , 1.0 ) ; } const ba = b / a ; const ca = c / a ; const da = d / a ; const p = ( 3.0 * ca - ba * ba ) / 3.0 ; const p3 = p / 3.0 ; const q = ( 2.0 * ba * ba * ba - 9.0 * ba * ca + 27.0 * da ) / 27.0 ; const q2 = q / 2.0 ; const discriminant = q2 * q2 + p3 * p3 * p3 ; const center = 0.5 ; const threshold = center + 0.01 ; if ( discriminant < 0.0 ) { const mp3 = - p / 3.0 ; const mp33 = mp3 * mp3 * mp3 ; const r = this . sqrt ( mp33 ) ; const t = - q / ( 2.0 * r ) ; const cosphi = this . range ( t , - 1.0 , 1.0 ) ; const phi = Math . acos ( cosphi ) ; const crtr = this . cbrt ( r ) ; const t1 = 2.0 * crtr ; const root1 = t1 * this . cos ( phi / 3.0 ) - ba / 3.0 ; if ( this . abs ( root1 - center ) < threshold ) { return this . range ( root1 , 0.0 , 1.0 ) ; } const root2 = t1 * this . cos ( ( phi + 2.0 * Math . PI ) / 3.0 ) - ba / 3.0 ; if ( this . abs ( root2 - center ) < threshold ) { return this . range ( root2 , 0.0 , 1.0 ) ; } const root3 = t1 * this . cos ( ( phi + 4.0 * Math . PI ) / 3.0 ) - ba / 3.0 ; return this . range ( root3 , 0.0 , 1.0 ) ; } if ( discriminant == 0.0 ) { let u1 ; if ( q2 < 0.0 ) { u1 = this . cbrt ( - q2 ) ; } else { u1 = - this . cbrt ( q2 ) ; } const root1 = 2.0 * u1 - ba / 3.0 ; if ( this . abs ( root1 - center ) < threshold ) { return this . range ( root1 , 0.0 , 1.0 ) ; } const root2 = - u1 - ba / 3.0 ; return this . range ( root2 , 0.0 , 1.0 ) ; } const sd = this . sqrt ( discriminant ) ; const u1 = this . cbrt ( sd - q2 ) ; const v1 = this . cbrt ( sd + q2 ) ; const root1 = u1 - v1 - ba / 3.0 ; return this . range ( root1 , 0.0 , 1.0 ) ; } /**
     * コンストラクタ
     */ private constructor ( ) { } } import * as $ from './cubismmath' ; export namespace Live2DCubismFramework { export const CubismMath = $ . CubismMath ; export type CubismMath = $ . CubismMath ; }