Passed
Push — main ( 590153...ba27c8 )
by Dylan
04:30
created

Polyrat.toGLSLFormula   B

Complexity

Conditions 6

Size

Total Lines 19
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 6

Importance

Changes 0
Metric Value
cc 6
eloc 13
dl 0
loc 19
ccs 11
cts 11
cp 1
crap 6
rs 8.6666
c 0
b 0
f 0
1 2
import {Rat} from './Rat'
2 2
import Symbolizer from './Symbolizer'
3
4
interface Coefficents<Rat> {
5
  [Key: string]: Rat;
6
}
7
8
/**
9
 * @class Rational polynumber
10
 * @name Polyrat
11
 */
12 2
export class Polyrat {
13
14
  // coefficent values are indexed with their the exponents in each dimension, comma-separated, as the key
15 7
  coefficents: Coefficents<Rat> = {}
16
17
  // the dimension is how many params there are, defined by the length of the exponent keys
18 7
  dimension = 0
19
20
  // unique symbols for each dimension
21 7
  symbols = ''
22
23
  /**
24
   * Initialize a rational polynumber.
25
   */
26
  constructor(coefficents?: Coefficents<Rat>) {
27 7
    if (coefficents) this.coefficents = coefficents
28 7
    if (Object.keys(this.coefficents).length) {
29 4
      this.dimension = Object.keys(this.coefficents)[0].split(',').length
30
    }
31 7
    const sg = (new Symbolizer('xyzw')).generator()
32 7
    for (let i=0; i<this.dimension; i++) {
33 5
      this.symbols += sg.next().value
34
    }
35
  }
36
37
  /**
38
   * Evaluate the result given the parameters for each dimension.
39
   */
40
  evaluate(parameters: Rat[]): Rat {
41 1
    let result: Rat = new Rat()
42 1
    for (const [exponents, coefficent] of Object.entries(this.coefficents)) {
43 1
      let value: Rat = coefficent
44 1
      const dimensions = exponents.split(',')
45 1
      for (let i=0; i<dimensions.length; i++) {
46 1
        value = value.mul(parameters[i].pow(new Rat(parseInt(dimensions[i], 10))))
47
      }
48 1
      result = result.add(value)
49
    }
50 1
    return result
51
  }
52
53
  /**
54
   * The text representation.
55
   */
56
  toString(): string {
57
    // return JSON.stringify(this.coefficents)
58 3
    const r = []
59 3
    for (const [exponents, coefficent] of Object.entries(this.coefficents)) {
60 2
      r.push(`'${exponents}': ${coefficent.toString()}'`)
61
    }
62 3
    return `[${r.join(',')}]`
63
  }
64
65
  /**
66
   * The "calc" code for evaluating the value.
67
   */
68
  toCalcFormula(): string {
69 1
    const r: string[] = []
70 1
    for (const [exponents, coefficent] of Object.entries(this.coefficents)) {
71 5
      const t: string[] = []
72 5
      const f = coefficent.toString()
73 5
      if (f !== '1') t.push(f)
74 5
      const dimensions = exponents.split(',')
75 5
      for (let i=0; i<dimensions.length; i++) {
76 10
        if (dimensions[i] !== '0') {
77 6
          t.push(`${this.symbols[i]}^${parseInt(dimensions[i], 10)}`)
78
        }
79
      }
80 5
      if (t) r.push(t.join('*'))
81
    }
82 1
    return r.join(' + ')
83
  }
84
85
  /**
86
   * The GLSL code for evaluating the value.
87
   */
88
  toGLSLFormula(): string {
89 1
    const r: string[] = []
90 1
    for (const [exponents, coefficent] of Object.entries(this.coefficents)) {
91 5
      const t: string[] = []
92 5
      const f = coefficent.toString()
93 5
      if (f !== '1') t.push(f+'.0')
94 5
      const dimensions = exponents.split(',')
95 5
      for (let i=0; i<dimensions.length; i++) {
96 10
        if (dimensions[i] !== '0') {
97 6
          t.push(`pow(${this.symbols[i]},${parseInt(dimensions[i], 10)}.0)`)
98
        }
99
      }
100 5
      if (t) r.push(t.join('*'))
101
    }
102 1
    return r.join('+')
103
  }
104
105
  /**
106
   * Clone this.
107
   */
108
  clone(): Polyrat {
109 1
    return new Polyrat(this.coefficents)
110
  }
111
112
}
113
114
/**
115
 * Parse the string and return it as a Polyrat.
116
 */
117 2
export const stringToPolyrat = (s: string): Polyrat => {
118 1
  return new Polyrat(JSON.parse(s) as Coefficents<Rat>)
119
}
120
121
export default Polyrat
122