pimath 0.2.10 → 0.2.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/dist/pimath.js +918 -924
  2. package/dist/pimath.js.map +1 -1
  3. package/package.json +13 -12
  4. package/src/algebra/equation.ts +3 -2
  5. package/src/algebra/equationSolver.ts +2 -1
  6. package/src/algebra/factor.ts +10 -9
  7. package/src/algebra/linearSystem.ts +10 -9
  8. package/src/algebra/logicalset.ts +8 -3
  9. package/src/algebra/matrix.ts +10 -9
  10. package/src/algebra/monom.ts +10 -4
  11. package/src/algebra/operations.ts +3 -2
  12. package/src/algebra/polyFactor.ts +11 -7
  13. package/src/algebra/polynom.ts +30 -30
  14. package/src/coefficients/fraction.ts +6 -5
  15. package/src/coefficients/root.ts +6 -5
  16. package/src/errors.ts +45 -0
  17. package/src/geometry/TupleN.ts +4 -3
  18. package/src/geometry/geomMath.ts +3 -2
  19. package/src/geometry/line.ts +4 -2
  20. package/src/geometry/line3.ts +7 -6
  21. package/src/geometry/plane3.ts +3 -2
  22. package/src/geometry/point.ts +5 -4
  23. package/src/geometry/sphere3.ts +6 -5
  24. package/src/geometry/triangle.ts +3 -2
  25. package/src/geometry/vector.ts +6 -5
  26. package/src/helpers.ts +3 -1
  27. package/src/index.ts +23 -0
  28. package/src/numeric.ts +2 -1
  29. package/src/randomization/geometry/rndPoint.ts +2 -2
  30. package/src/randomization/rndHelpers.ts +2 -1
  31. package/types/algebra/equation.d.ts.map +1 -1
  32. package/types/algebra/equationSolver.d.ts.map +1 -1
  33. package/types/algebra/factor.d.ts.map +1 -1
  34. package/types/algebra/linearSystem.d.ts.map +1 -1
  35. package/types/algebra/logicalset.d.ts.map +1 -1
  36. package/types/algebra/matrix.d.ts.map +1 -1
  37. package/types/algebra/monom.d.ts.map +1 -1
  38. package/types/algebra/operations.d.ts.map +1 -1
  39. package/types/algebra/polyFactor.d.ts +1 -1
  40. package/types/algebra/polyFactor.d.ts.map +1 -1
  41. package/types/algebra/polynom.d.ts.map +1 -1
  42. package/types/coefficients/fraction.d.ts.map +1 -1
  43. package/types/coefficients/root.d.ts.map +1 -1
  44. package/types/errors.d.ts +20 -0
  45. package/types/errors.d.ts.map +1 -0
  46. package/types/geometry/TupleN.d.ts.map +1 -1
  47. package/types/geometry/geomMath.d.ts.map +1 -1
  48. package/types/geometry/line.d.ts.map +1 -1
  49. package/types/geometry/line3.d.ts.map +1 -1
  50. package/types/geometry/plane3.d.ts.map +1 -1
  51. package/types/geometry/point.d.ts.map +1 -1
  52. package/types/geometry/sphere3.d.ts.map +1 -1
  53. package/types/geometry/triangle.d.ts.map +1 -1
  54. package/types/geometry/vector.d.ts.map +1 -1
  55. package/types/helpers.d.ts.map +1 -1
  56. package/types/index.d.ts +12 -0
  57. package/types/index.d.ts.map +1 -1
  58. package/types/numeric.d.ts.map +1 -1
  59. package/types/randomization/geometry/rndPoint.d.ts +1 -1
  60. package/types/randomization/geometry/rndPoint.d.ts.map +1 -1
  61. package/types/randomization/rndHelpers.d.ts.map +1 -1
@@ -2,6 +2,7 @@
2
2
  * Polynom module contains everything necessary to handle polynoms.*
3
3
  */
4
4
  import {ShutingYard, ShutingyardType, type Token} from "piexpression"
5
+ import {InvalidArgumentError, MathError, ParseError} from "../errors"
5
6
  import type {
6
7
  IAlgebra,
7
8
  IAnalyse,
@@ -212,7 +213,7 @@ export class Polynom implements IPiMathObject<Polynom>,
212
213
  return this.divide(new Polynom(value))
213
214
  }
214
215
 
215
- throw new Error(`Cannot divide by ${value as unknown as string}`)
216
+ throw new MathError(`Cannot divide by ${value as unknown as string}`)
216
217
  }
217
218
 
218
219
  public empty(): this {
@@ -242,7 +243,7 @@ export class Polynom implements IPiMathObject<Polynom>,
242
243
  }
243
244
 
244
245
  if (!this.degree(letter).isNatural() || !P.degree(letter).isNatural()) {
245
- throw new Error('Euclidean division requires integer degrees')
246
+ throw new MathError('Euclidean division requires integer degrees')
246
247
  }
247
248
 
248
249
  // Get at least a letter
@@ -396,7 +397,7 @@ export class Polynom implements IPiMathObject<Polynom>,
396
397
 
397
398
  public getCoefficients(): Fraction[] {
398
399
  if (!this.degree().isNatural()) {
399
- throw new Error('getCoefficients() requires a polynomial with integer degrees')
400
+ throw new MathError('getCoefficients() requires a polynomial with integer degrees')
400
401
  }
401
402
 
402
403
  // Assume there is only one letter.
@@ -462,8 +463,6 @@ export class Polynom implements IPiMathObject<Polynom>,
462
463
  }
463
464
 
464
465
  public isDeveloped(polynomString: string): boolean {
465
- let P: Polynom
466
-
467
466
  // Start by removing the parenthesis after a "power"
468
467
  const pString = polynomString.replaceAll(/\^\(([-0-9/]+)\)/g, '$1')
469
468
 
@@ -473,13 +472,9 @@ export class Polynom implements IPiMathObject<Polynom>,
473
472
  }
474
473
 
475
474
 
476
- // Try to build the polynom
477
- try {
478
- // Build the polynom
479
- P = new Polynom(polynomString)
480
- } catch {
481
- return false
482
- }
475
+ // Build the polynom. A malformed string throws (ParseError) instead of
476
+ // being silently treated as "not developed".
477
+ const P = new Polynom(polynomString)
483
478
 
484
479
  // Both polynom aren't the same (once developed and reduced => they cannot be equivalent)
485
480
  if (!this.isEqual(P)) {
@@ -663,13 +658,13 @@ export class Polynom implements IPiMathObject<Polynom>,
663
658
  try {
664
659
  const k = new Fraction(value)
665
660
  return this.#multiplyByFraction(k)
666
- } catch {
667
- throw new Error('Cannot multiply by this value.')
661
+ } catch (e) {
662
+ throw new MathError('Cannot multiply by this value.', {cause: e})
668
663
  }
669
664
  }
670
665
 
671
666
  // Something went wrong...
672
- throw new Error(`Cannot multiply by this value: ${value as unknown as string}`)
667
+ throw new MathError(`Cannot multiply by this value: ${value as unknown as string}`)
673
668
  }
674
669
 
675
670
  public get numberOfVars(): number {
@@ -801,7 +796,7 @@ export class Polynom implements IPiMathObject<Polynom>,
801
796
 
802
797
  // Add the new monom to the result polynom
803
798
  if (pow.isStrictlyNegative()) {
804
- throw new Error(`Cannot replace variable "${letter}" with negative power in a Polynom`)
799
+ throw new MathError(`Cannot replace variable "${letter}" with negative power in a Polynom`)
805
800
  }
806
801
  resultPolynom.add(P.clone().pow(pow.numerator).multiply(m))
807
802
  }
@@ -817,7 +812,7 @@ export class Polynom implements IPiMathObject<Polynom>,
817
812
  // ------------------------------------------
818
813
 
819
814
  public root(): Polynom {
820
- throw new Error('Cannot take the root from a polynom')
815
+ throw new MathError('Cannot take the root from a polynom')
821
816
  }
822
817
 
823
818
  get roots(): Solution[] {
@@ -836,7 +831,7 @@ export class Polynom implements IPiMathObject<Polynom>,
836
831
  }
837
832
 
838
833
  public sqrt(): Polynom {
839
- throw new Error('Cannot take the square root from a polynom')
834
+ throw new MathError('Cannot take the square root from a polynom')
840
835
  }
841
836
 
842
837
  public subtract(...values: InputAlgebra<Polynom>[]): this {
@@ -1085,7 +1080,7 @@ export class Polynom implements IPiMathObject<Polynom>,
1085
1080
  const letters = inputStr.split('')
1086
1081
 
1087
1082
  if (fractions.length > letters.length + 1) {
1088
- throw new Error(`Too many values: ${letters.length} letters but ${fractions.length} values provided`)
1083
+ throw new InvalidArgumentError(`Too many values: ${letters.length} letters but ${fractions.length} values provided`)
1089
1084
  }
1090
1085
 
1091
1086
  let i = 0
@@ -1127,7 +1122,7 @@ export class Polynom implements IPiMathObject<Polynom>,
1127
1122
  break
1128
1123
 
1129
1124
  case ShutingyardType.CONSTANT:
1130
- throw new Error('Unsupported CONSTANT token in Polynom parser')
1125
+ throw new ParseError('Unsupported CONSTANT token in Polynom parser')
1131
1126
 
1132
1127
  case ShutingyardType.OPERATION:
1133
1128
  if (stack.length >= 2) {
@@ -1136,7 +1131,7 @@ export class Polynom implements IPiMathObject<Polynom>,
1136
1131
 
1137
1132
  // Check if the polynoms are not undefined.
1138
1133
  if (a === undefined || b === undefined) {
1139
- throw new Error('Unexpected undefined operand in Polynom parser stack')
1134
+ throw new ParseError('Unexpected undefined operand in Polynom parser stack')
1140
1135
  }
1141
1136
 
1142
1137
  if (element.token === '+') {
@@ -1147,16 +1142,16 @@ export class Polynom implements IPiMathObject<Polynom>,
1147
1142
  stack.push(a.multiply(b))
1148
1143
  } else if (element.token === '/') {
1149
1144
  if (b.degree().isStrictlyPositive()) {
1150
- throw new Error('Cannot divide a Polynom by another Polynom of degree > 0')
1145
+ throw new MathError('Cannot divide a Polynom by another Polynom of degree > 0')
1151
1146
  } else {
1152
1147
  // a.divide(b.monoms[0].coefficient)
1153
1148
  stack.push(a.divide(b.monoms[0].coefficient))
1154
1149
  }
1155
1150
  } else if (element.token === '^') {
1156
1151
  if (b.degree().isStrictlyPositive()) {
1157
- throw new Error('Cannot elevate a polynom with another polynom !')
1158
- } else if (b.monoms[0].coefficient.isRelative())
1159
- // Integer power
1152
+ throw new MathError('Cannot elevate a polynom with another polynom !')
1153
+ } else if (b.monoms[0].coefficient.isNatural())
1154
+ // Natural (positive) power
1160
1155
  {
1161
1156
  stack.push(a.pow(b.monoms[0].coefficient.value))
1162
1157
  } else {
@@ -1168,7 +1163,7 @@ export class Polynom implements IPiMathObject<Polynom>,
1168
1163
 
1169
1164
  stack.push(a)
1170
1165
  } else {
1171
- throw new Error('Cannot raise a multi-monom Polynom to a fractional power')
1166
+ throw new MathError('Cannot raise a multi-monom Polynom to a fractional power')
1172
1167
  }
1173
1168
  }
1174
1169
  }
@@ -1179,7 +1174,7 @@ export class Polynom implements IPiMathObject<Polynom>,
1179
1174
  stack.push(a.opposite())
1180
1175
  }
1181
1176
  } else {
1182
- throw new Error("Error parsing the polynom")
1177
+ throw new ParseError("Error parsing the polynom")
1183
1178
  }
1184
1179
 
1185
1180
 
@@ -1187,11 +1182,11 @@ export class Polynom implements IPiMathObject<Polynom>,
1187
1182
 
1188
1183
  case ShutingyardType.MONOM:
1189
1184
  // Should never appear.
1190
- throw new Error('Unexpected MONOM token in polynom parser')
1185
+ throw new ParseError('Unexpected MONOM token in polynom parser')
1191
1186
 
1192
1187
  case ShutingyardType.FUNCTION:
1193
1188
  // Should never appear.
1194
- throw new Error(`Unsupported function token "${element.token}" in polynom parser`)
1189
+ throw new ParseError(`Unsupported function token "${element.token}" in polynom parser`)
1195
1190
  }
1196
1191
 
1197
1192
 
@@ -1203,7 +1198,12 @@ export class Polynom implements IPiMathObject<Polynom>,
1203
1198
  */
1204
1199
  #shutingYardToReducedPolynom(inputStr: string): this {
1205
1200
  // Get the RPN array of the current expression
1206
- const SY: ShutingYard = new ShutingYard().parse(inputStr)
1201
+ let SY: ShutingYard
1202
+ try {
1203
+ SY = new ShutingYard().parse(inputStr)
1204
+ } catch (e) {
1205
+ throw new ParseError(`Cannot parse "${inputStr}" as a Polynom`, {cause: e})
1206
+ }
1207
1207
  const rpn: { token: string, tokenType: ShutingyardType }[] = SY.rpn
1208
1208
 
1209
1209
  // New version for reducing shuting yard.
@@ -1,5 +1,6 @@
1
1
  import type {compareSign, IExpression, InputValue, IPiMathObject} from "../pimath.interface"
2
2
  import {Numeric} from "../numeric"
3
+ import {InvalidArgumentError, MathError} from "../errors"
3
4
 
4
5
  export enum FRAC_TYPE {
5
6
  frac = 'frac',
@@ -263,7 +264,7 @@ export class Fraction implements IPiMathObject<Fraction>, IExpression<Fraction>
263
264
 
264
265
  public amplify = (k: number): this => {
265
266
  if (!Number.isSafeInteger(k)) {
266
- throw new Error("The amplification factor must be a safe integer.")
267
+ throw new InvalidArgumentError("The amplification factor must be a safe integer.")
267
268
  }
268
269
 
269
270
  this.#numerator *= k
@@ -405,11 +406,11 @@ export class Fraction implements IPiMathObject<Fraction>, IExpression<Fraction>
405
406
  const p: number = decimal ? decimal.length : 0
406
407
 
407
408
  if (!Number.isSafeInteger(length) || length <= 0) {
408
- throw new Error("The periodic length must be a positive integer.")
409
+ throw new InvalidArgumentError("The periodic length must be a positive integer.")
409
410
  }
410
411
 
411
412
  if (length > p) {
412
- throw new Error(`The periodic length (${length}) cannot exceed the number of decimal digits (${p}).`)
413
+ throw new InvalidArgumentError(`The periodic length (${length}) cannot exceed the number of decimal digits (${p}).`)
413
414
  }
414
415
 
415
416
  const power = Math.pow(10, p)
@@ -661,7 +662,7 @@ export class Fraction implements IPiMathObject<Fraction>, IExpression<Fraction>
661
662
 
662
663
  // if p is not a safe integer, throw error
663
664
  if (!Number.isSafeInteger(p)) {
664
- throw new Error("The root must be an integer.")
665
+ throw new InvalidArgumentError("The root must be an integer.")
665
666
  }
666
667
 
667
668
  // If negative, inverse the fraction
@@ -672,7 +673,7 @@ export class Fraction implements IPiMathObject<Fraction>, IExpression<Fraction>
672
673
 
673
674
  // if the fraction is negative and the root is even, throw error
674
675
  if (this.isNegative() && p % 2 === 0) {
675
- throw new Error("The root of a negative number must be odd.")
676
+ throw new MathError("The root of a negative number must be odd.")
676
677
  }
677
678
 
678
679
  // get the sign of the fraction and make it positive
@@ -2,6 +2,7 @@ import {Fraction} from "./fraction"
2
2
  import type {IExpression, InputValue, IPiMathObject} from "../pimath.interface"
3
3
  import {stripParenthesis} from "../helpers"
4
4
  import {Numeric} from "../numeric"
5
+ import {InvalidArgumentError, MathError, ParseError} from "../errors"
5
6
 
6
7
  export class Root implements IPiMathObject<Root>, IExpression<Root> {
7
8
  #factor: Fraction
@@ -109,7 +110,7 @@ export class Root implements IPiMathObject<Root>, IExpression<Root> {
109
110
  this.index !== rt.index ||
110
111
  !this.radical.isEqual(rt.radical)
111
112
  ) {
112
- throw new Error("Add can only be done with two same index and radical")
113
+ throw new MathError("Add can only be done with two same index and radical")
113
114
  }
114
115
 
115
116
  this.factor.add(rt.factor)
@@ -133,7 +134,7 @@ export class Root implements IPiMathObject<Root>, IExpression<Root> {
133
134
  // set the index
134
135
  this.index = index
135
136
 
136
- // set the racial
137
+ // set the radical
137
138
  this.radical = new Fraction(radical)
138
139
 
139
140
  // set the factor if any
@@ -158,7 +159,7 @@ export class Root implements IPiMathObject<Root>, IExpression<Root> {
158
159
 
159
160
  set index(value: number) {
160
161
  if (!Number.isSafeInteger(value) || value <= 0) {
161
- throw new Error("Index must be a strictly positive integer.")
162
+ throw new InvalidArgumentError("Index must be a strictly positive integer.")
162
163
  }
163
164
  this.#index = value
164
165
  }
@@ -212,7 +213,7 @@ export class Root implements IPiMathObject<Root>, IExpression<Root> {
212
213
  return this
213
214
  }
214
215
 
215
- throw new Error('Multiply can only be done if radical or index as equals.')
216
+ throw new MathError('Multiply can only be done if radical or index as equals.')
216
217
  }
217
218
 
218
219
  one(): this {
@@ -334,7 +335,7 @@ export class Root implements IPiMathObject<Root>, IExpression<Root> {
334
335
  #parse_root(value: string): this {
335
336
  // Format: [factor]root([index])[radical] or [factor]root([index])([radical])
336
337
  const match = /^(.*?)root\((\d+)\)\(?([^)]+)/.exec(value)
337
- if (!match) throw new Error(`Invalid root format: "${value}"`)
338
+ if (!match) throw new ParseError(`Invalid root format: "${value}"`)
338
339
 
339
340
  const [, factor, index, radical] = match
340
341
  this.index = +index
package/src/errors.ts ADDED
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Typed error hierarchy for PiMath.
3
+ *
4
+ * All PiMath errors extend {@link PiMathError}, so a consumer can catch every
5
+ * library error at once with `catch (e) { if (e instanceof PiMathError) ... }`,
6
+ * or discriminate a specific kind with `instanceof ParseError`, etc.
7
+ *
8
+ * The original error (e.g. piexpression's ParseError) is chained through the
9
+ * standard ES2022 `cause` option.
10
+ */
11
+ export class PiMathError extends Error {
12
+ constructor(message: string, options?: { cause?: unknown }) {
13
+ super(message, options)
14
+ // Use the concrete subclass name (ParseError, MathError, ...).
15
+ this.name = new.target.name
16
+ }
17
+ }
18
+
19
+ /** The input string cannot be parsed into the target object. */
20
+ export class ParseError extends PiMathError {
21
+ }
22
+
23
+ /** Incompatible dimensions (matrix, vector, point, ...). */
24
+ export class DimensionError extends PiMathError {
25
+ }
26
+
27
+ /** Mathematically invalid operation on otherwise valid inputs. */
28
+ export class MathError extends PiMathError {
29
+ }
30
+
31
+ /** An argument is invalid (outside of string parsing). */
32
+ export class InvalidArgumentError extends PiMathError {
33
+ }
34
+
35
+ /** The called method is not implemented yet. */
36
+ export class NotImplementedError extends PiMathError {
37
+ }
38
+
39
+ /** An index is out of range. */
40
+ export class IndexError extends PiMathError {
41
+ }
42
+
43
+ /** An operation was attempted on an object in an invalid/uninitialized state. */
44
+ export class StateError extends PiMathError {
45
+ }
@@ -6,6 +6,7 @@
6
6
 
7
7
  import {Fraction} from "../coefficients"
8
8
  import type {InputValue} from "../pimath.interface"
9
+ import {DimensionError} from "../errors"
9
10
 
10
11
  export abstract class TupleN {
11
12
  #array: Fraction[] = []
@@ -72,7 +73,7 @@ export abstract class TupleN {
72
73
 
73
74
  setDimension(value = 2): this {
74
75
  if (value < 2) {
75
- throw new Error('Dimension must be at least 2')
76
+ throw new DimensionError('Dimension must be at least 2')
76
77
  }
77
78
 
78
79
  if (value < this.dimension) {
@@ -106,14 +107,14 @@ export abstract class TupleN {
106
107
 
107
108
  get z(): Fraction {
108
109
  if (this.dimension < 3) {
109
- throw new Error('Vector is not 3D')
110
+ throw new DimensionError('Vector is not 3D')
110
111
  }
111
112
  return this.#array[2]
112
113
  }
113
114
 
114
115
  set z(value: Fraction | number | string) {
115
116
  if (this.dimension < 3) {
116
- throw new Error('Vector is not 3D')
117
+ throw new DimensionError('Vector is not 3D')
117
118
  }
118
119
  this.#array[2] = new Fraction(value)
119
120
  this.#onChange?.()
@@ -1,6 +1,7 @@
1
1
  import {Fraction} from "../coefficients"
2
2
  import type {Vector} from "./vector"
3
3
  import type {Point} from "./point"
4
+ import {DimensionError} from "../errors"
4
5
 
5
6
  type V = Vector | Point
6
7
  export function areVectorsEquals(v1: V, v2: V): boolean {
@@ -39,12 +40,12 @@ export function determinantFromVectors(...values: V[]): Fraction {
39
40
  // TODO: Make it work for vectors of dimension n
40
41
  // Check if the vectors are in the same dimension
41
42
  if (values.some((value) => value.dimension !== values[0].dimension)) {
42
- throw new Error('All vectors must have the same dimension')
43
+ throw new DimensionError('All vectors must have the same dimension')
43
44
  }
44
45
 
45
46
  // Check if the vectors are in dimension 2 or 3 and that the number of values is correct
46
47
  if (values[0].dimension !== values.length ) {
47
- throw new Error(`The determinant of dimension ${values[0].dimension} must have the same number of vectors (${values.length} given)`)
48
+ throw new DimensionError(`The determinant of dimension ${values[0].dimension} must have the same number of vectors (${values.length} given)`)
48
49
  }
49
50
 
50
51
  // Calculate the determinant 2x2
@@ -10,6 +10,7 @@ import {type InputValue, type IPiMathObject, LinePropriety} from "../pimath.inte
10
10
  import {randomIntSym} from "../randomization/rndHelpers"
11
11
  import {Point} from "./point"
12
12
  import {Root} from "../coefficients/root"
13
+ import {ParseError} from "../errors"
13
14
 
14
15
  enum LINE_DISPLAY {
15
16
  CARTESIAN,
@@ -83,12 +84,13 @@ export class Line implements IPiMathObject<Line> {
83
84
 
84
85
  if (typeof values[0] === "string") {
85
86
  // It's a string - create an Equation from it.
87
+ // A malformed string throws (ParseError) instead of silently
88
+ // returning a half-built Line.
86
89
  try {
87
90
  const E = new Equation(values[0])
88
91
  return this.parse(E)
89
92
  } catch (e) {
90
- console.warn(e)
91
- return this
93
+ throw new ParseError(`Cannot parse "${values[0]}" as a Line`, {cause: e})
92
94
  }
93
95
  }
94
96
  }
@@ -6,6 +6,7 @@ import {Fraction} from "../coefficients/fraction"
6
6
  import {Polynom} from "../algebra/polynom"
7
7
  import {Monom} from "../algebra/monom"
8
8
  import {randomIntSym} from "../randomization/rndHelpers"
9
+ import {NotImplementedError} from "../errors"
9
10
  import {Vector} from "./vector"
10
11
  import {Point} from "./point"
11
12
  import {Line3Propriety} from "../pimath.interface"
@@ -134,7 +135,7 @@ export class Line3 {
134
135
 
135
136
  intersection = (line: Line3): { point: Vector, hasIntersection: boolean, isParallel: boolean, isSame: boolean } => {
136
137
 
137
- throw new Error('Method not implemented.')
138
+ throw new NotImplementedError('Method not implemented.')
138
139
  }
139
140
 
140
141
  // ------------------------------------------
@@ -144,19 +145,19 @@ export class Line3 {
144
145
 
145
146
  isParallelTo = (line: Line3): boolean => {
146
147
  // Do they have the isSame direction ?
147
- throw new Error('Method not implemented.')
148
+ throw new NotImplementedError('Method not implemented.')
148
149
  }
149
150
 
150
151
  isPerpendicularTo = (line: Line3): boolean => {
151
- throw new Error('Method not implemented.')
152
+ throw new NotImplementedError('Method not implemented.')
152
153
  }
153
154
 
154
155
  isSameAs = (line: Line3): boolean => {
155
- throw new Error('Method not implemented.')
156
+ throw new NotImplementedError('Method not implemented.')
156
157
  }
157
158
 
158
159
  isVertical = (): boolean => {
159
- throw new Error('Method not implemented.')
160
+ throw new NotImplementedError('Method not implemented.')
160
161
  }
161
162
 
162
163
  get point(): Point {
@@ -196,7 +197,7 @@ export class Line3 {
196
197
  // }
197
198
 
198
199
  simplify = (): this => {
199
- throw new Error('Method not implemented.')
200
+ throw new NotImplementedError('Method not implemented.')
200
201
  // const lcm = Numeric.lcm(this.#a.denominator, this.#b.denominator, this.#c.denominator),
201
202
  // gcd = Numeric.gcd(this.#a.numerator, this.#b.numerator, this.#c.numerator)
202
203
 
@@ -5,6 +5,7 @@ import {Line3} from "./line3"
5
5
  import {Point} from "./point"
6
6
  import {Vector} from "./vector"
7
7
  import type {Plane3Config} from "../pimath.interface"
8
+ import {DimensionError, NotImplementedError} from "../errors"
8
9
 
9
10
 
10
11
  export class Plane3 {
@@ -110,7 +111,7 @@ export class Plane3 {
110
111
  let direction: Vector
111
112
  if (value instanceof Vector) {
112
113
  if (value.dimension !== 3) {
113
- throw new Error('Vector is not 3D')
114
+ throw new DimensionError('Vector is not 3D')
114
115
  }
115
116
 
116
117
  direction = value
@@ -153,7 +154,7 @@ export class Plane3 {
153
154
  // Solve the asSystem:
154
155
  // p1 // p2 // z=0
155
156
  const pt = new Point(0, 0, 0)
156
- throw new Error('Intersection with plane not yet implemented !')
157
+ throw new NotImplementedError('Intersection with plane not yet implemented !')
157
158
  return new Line3(pt, direction)
158
159
  }
159
160
 
@@ -6,6 +6,7 @@
6
6
 
7
7
  import {Fraction} from "../coefficients"
8
8
  import type {InputValue} from "../pimath.interface"
9
+ import {DimensionError, InvalidArgumentError, ParseError} from "../errors"
9
10
  import {Root} from "../coefficients/root"
10
11
  import {TupleN} from "./TupleN"
11
12
  import type {Vector} from "./vector"
@@ -37,13 +38,13 @@ export class Point extends TupleN {
37
38
 
38
39
  if (values.length > 1) {
39
40
  if (values.some(x => x instanceof Point)) {
40
- throw new Error('Creating a point with multiple argument requires an input fraction')
41
+ throw new InvalidArgumentError('Creating a point with multiple argument requires an input fraction')
41
42
  }
42
43
 
43
44
  const nbs: Fraction[] = values.map(x => new Fraction(x as InputValue<Fraction>))
44
45
 
45
46
  if (nbs.some(x => x.isNaN())) {
46
- throw new Error('The given values are not a valid point string (a,b): ')
47
+ throw new ParseError('The given values are not a valid point string (a,b): ')
47
48
  }
48
49
 
49
50
  this.array = nbs
@@ -66,7 +67,7 @@ export class Point extends TupleN {
66
67
 
67
68
  distanceTo(B: Point): Root {
68
69
  if (this.dimension !== B.dimension) {
69
- throw new Error('The two points must have the same dimensions.')
70
+ throw new DimensionError('The two points must have the same dimensions.')
70
71
  }
71
72
 
72
73
  const AB = this.array
@@ -91,7 +92,7 @@ export class Point extends TupleN {
91
92
 
92
93
  middleOf(V1: Point, V2: Point): this {
93
94
  if (V1.dimension !== V2.dimension) {
94
- throw new Error('Vectors must be the same dimension')
95
+ throw new DimensionError('Vectors must be the same dimension')
95
96
  }
96
97
 
97
98
  this.array = []
@@ -2,6 +2,7 @@ import {Point} from "./point"
2
2
  import {Fraction} from "../coefficients"
3
3
  import {Equation, Polynom} from "../algebra"
4
4
  import type {InputValue} from "../pimath.interface"
5
+ import {StateError} from "../errors"
5
6
 
6
7
  enum SPHERE3_FORMAT {
7
8
  DEVELOPPED,
@@ -66,21 +67,21 @@ export class Sphere3 {
66
67
 
67
68
  get center(): Point {
68
69
  if (this.#center === undefined) {
69
- throw new Error('Sphere3 is undefined')
70
+ throw new StateError('Sphere3 is undefined')
70
71
  }
71
72
  return this.#center
72
73
  }
73
74
 
74
75
  get squareRadius(): Fraction {
75
76
  if (this.#squareRadius === undefined) {
76
- throw new Error('Sphere3 is undefined')
77
+ throw new StateError('Sphere3 is undefined')
77
78
  }
78
79
  return this.#squareRadius
79
80
  }
80
81
 
81
82
  get radius(): { tex: string, display: string, value: number } {
82
83
  if (this.#squareRadius === undefined) {
83
- throw new Error('Sphere3 is undefined')
84
+ throw new StateError('Sphere3 is undefined')
84
85
  }
85
86
 
86
87
  if (this.#squareRadius.isSquare()) {
@@ -100,7 +101,7 @@ export class Sphere3 {
100
101
 
101
102
  get equation(): Equation {
102
103
  if (this.#equation === undefined) {
103
- throw new Error('Sphere3 is undefined')
104
+ throw new StateError('Sphere3 is undefined')
104
105
  }
105
106
  return this.#equation
106
107
  }
@@ -133,7 +134,7 @@ export class Sphere3 {
133
134
 
134
135
  #output = (asTex: boolean): string => {
135
136
  if (this.#equation === undefined) {
136
- throw new Error('Sphere3 is undefined')
137
+ throw new StateError('Sphere3 is undefined')
137
138
  }
138
139
 
139
140
  if (this.#format === SPHERE3_FORMAT.DEVELOPPED) {
@@ -4,6 +4,7 @@ import {Vector} from "./vector"
4
4
  import {Point} from "./point"
5
5
  import type {InputValue, remarquableLines} from "../pimath.interface"
6
6
  import {Numeric} from "../numeric"
7
+ import {IndexError, InvalidArgumentError} from "../errors"
7
8
 
8
9
  type TRIANGLE_SIDES = 'AB' | 'AC' | 'BC'
9
10
 
@@ -62,7 +63,7 @@ export class Triangle {
62
63
  const v: Fraction[] = values.map((x: unknown) => new Fraction(x as string))
63
64
 
64
65
  if (v.some(x => x.isNaN())) {
65
- throw new Error('One of the values is not a valid number')
66
+ throw new InvalidArgumentError('One of the values is not a valid number')
66
67
  }
67
68
 
68
69
  return this.fromCoordinates(v[0], v[1], v[2], v[3], v[4], v[5])
@@ -436,7 +437,7 @@ export class Triangle {
436
437
  }
437
438
 
438
439
  if (d1 === undefined || d2 === undefined) {
439
- throw new Error(`The point ${pt} does not exist`)
440
+ throw new IndexError(`The point ${pt} does not exist`)
440
441
  }
441
442
 
442
443
  const director = internal
@@ -6,6 +6,7 @@ import type {InputValue, IPiMathObject} from "../pimath.interface"
6
6
  import {Fraction} from "../coefficients"
7
7
  import {Numeric} from "../numeric"
8
8
  import {areVectorsColinears, areVectorsEquals, dotProduct} from "./geomMath"
9
+ import {DimensionError, InvalidArgumentError} from "../errors"
9
10
  import {TupleN} from "./TupleN"
10
11
  import {type Point} from "./point"
11
12
 
@@ -25,7 +26,7 @@ export class Vector extends TupleN implements IPiMathObject<Vector> {
25
26
 
26
27
  public parse(...values: (Vector | Point)[] | InputValue<Fraction>[]): this {
27
28
  if (values.length === 0) {
28
- throw new Error(`Invalid value`)
29
+ throw new InvalidArgumentError(`Invalid value`)
29
30
  }
30
31
 
31
32
  if (values.length === 1) {
@@ -38,7 +39,7 @@ export class Vector extends TupleN implements IPiMathObject<Vector> {
38
39
  return this.fromString(values[0])
39
40
  }
40
41
 
41
- throw new Error(`Invalid value`)
42
+ throw new InvalidArgumentError(`Invalid value`)
42
43
  }
43
44
 
44
45
  // Two values are given
@@ -48,7 +49,7 @@ export class Vector extends TupleN implements IPiMathObject<Vector> {
48
49
  // The two values are vectors
49
50
  if (A instanceof TupleN && B instanceof TupleN) {
50
51
  if (A.dimension !== B.dimension) {
51
- throw new Error('Vectors must have the same dimension')
52
+ throw new DimensionError('Vectors must have the same dimension')
52
53
  }
53
54
 
54
55
  this.array = B.array.map((x, index) => x.clone().subtract(A.array[index]))
@@ -100,7 +101,7 @@ export class Vector extends TupleN implements IPiMathObject<Vector> {
100
101
 
101
102
  cross(value: Vector): Vector {
102
103
  if (this.dimension !== 3 || value.dimension !== 3) {
103
- throw new Error('Cross product can only be determined in 3D')
104
+ throw new DimensionError('Cross product can only be determined in 3D')
104
105
  }
105
106
 
106
107
  return new Vector(
@@ -171,7 +172,7 @@ export class Vector extends TupleN implements IPiMathObject<Vector> {
171
172
 
172
173
  normal = (): this => {
173
174
  if (this.dimension >= 3) {
174
- throw new Error('Normal vector can only be determined in 2D')
175
+ throw new DimensionError('Normal vector can only be determined in 2D')
175
176
  }
176
177
 
177
178
  const x = this.x.clone().opposite()