├── .eslintrc.cjs
├── .gitignore
├── CONTRIBUTING.md
├── LICENSE.md
├── README.md
├── babel.config.cjs
├── dist
├── index.d.ts
├── mz-math.esm.js
├── mz-math.esm.js.map
├── mz-math.min.js
├── mz-math.min.js.map
├── mz-math.node.cjs
└── mz-math.node.cjs.map
├── docs
├── CNAME
├── css
│ └── styles.1721034616071.css
├── favicon.ico
├── img
│ └── favicon
│ │ ├── android-chrome-192.png
│ │ ├── android-chrome-512.png
│ │ ├── apple-touch-icon.png
│ │ ├── browserconfig.xml
│ │ ├── favicon-128.png
│ │ ├── favicon-16.png
│ │ ├── favicon-256.png
│ │ ├── favicon-32.png
│ │ ├── favicon-48.png
│ │ ├── favicon-96.png
│ │ ├── favicon.ico
│ │ ├── favicon.svg
│ │ ├── manifest.json
│ │ └── mstile-150.png
├── index.html
├── js
│ ├── index.1721034616071.js
│ └── index.1721034616071.js.map
├── pages
│ ├── Check-if-value-is-number.html
│ ├── adjugate-matrix.html
│ ├── angle-between-vectors.html
│ ├── angles-distance.html
│ ├── animation.html
│ ├── append-or-prepend-column.html
│ ├── append-or-prepend-row.html
│ ├── arithmetic-sequence-sum.html
│ ├── bezier-curves.html
│ ├── bounding-box.html
│ ├── browser-usage.html
│ ├── check-if-ranges-overlap.html
│ ├── circle-movement.html
│ ├── circles-collision.html
│ ├── circumference.html
│ ├── color.html
│ ├── combinatorics.html
│ ├── convert-colors.html
│ ├── convert-range.html
│ ├── convert-string-to-number.html
│ ├── convex-polygons-collision.html
│ ├── cross-product.html
│ ├── degrees-and-radians.html
│ ├── distance-between-vectors.html
│ ├── divide-by-scalar.html
│ ├── divide-vector-by-scalar.html
│ ├── dot-product.html
│ ├── ellipse-movement.html
│ ├── extrema.html
│ ├── factorial.html
│ ├── general-case.html
│ ├── get-animation-data.html
│ ├── get-column.html
│ ├── get-linear-equation-by-2-points.html
│ ├── get-matrix-minor.html
│ ├── get-normal.html
│ ├── get-point-on-cubic-bezier-curve.html
│ ├── get-point-on-quadratic-bezier-curve.html
│ ├── get-random-boolean.html
│ ├── get-random-integer.html
│ ├── get-random-item-from-array.html
│ ├── get-random-number-in-range.html
│ ├── greatest-common-divisor.html
│ ├── inverse-matrix.html
│ ├── is-angle-between.html
│ ├── is-angle-in-circle-arc.html
│ ├── is-clockwise.html
│ ├── lerp.html
│ ├── linear-equation.html
│ ├── lissajous-curve.html
│ ├── matrix-deep-copy.html
│ ├── matrix-determinant.html
│ ├── matrix-equality.html
│ ├── matrix-initialization.html
│ ├── matrix-multiplication.html
│ ├── matrix-singularity.html
│ ├── matrix-subtraction.html
│ ├── matrix-sum.html
│ ├── matrix-to-CSS-transform.html
│ ├── matrix-transposition.html
│ ├── matrix.html
│ ├── modulo.html
│ ├── multiply-by-scalar.html
│ ├── multiply-matrix-by-vector.html
│ ├── multiply-vector-by-scalar.html
│ ├── natural-numbers-sequence-sum.html
│ ├── nodejs-usage.html
│ ├── normal.html
│ ├── normalize-vector.html
│ ├── percent-to-angle.html
│ ├── polar-to-cartesian.html
│ ├── polynomial.html
│ ├── quadratic-equation.html
│ ├── random-color.html
│ ├── random-id-or-GUID.html
│ ├── rectangles-collision.html
│ ├── reflection-matrix.html
│ ├── remove-row-or-column.html
│ ├── reset-matrix.html
│ ├── rotate-around-point.html
│ ├── rotation-matrix.html
│ ├── scale-and-stretch-matrix.html
│ ├── scale-around-point.html
│ ├── series.html
│ ├── set-decimal-places.html
│ ├── shearing-matrix.html
│ ├── shift-colors.html
│ ├── similar-colors.html
│ ├── sine-wave-movement.html
│ ├── square-in-circle.html
│ ├── system-of-linear-equations.html
│ ├── tangent.html
│ ├── temperature-conversion.html
│ ├── translation-matrix.html
│ ├── trigonometric-functions.html
│ ├── typescript-usage.html
│ ├── vector-angle.html
│ ├── vector-initialization.html
│ ├── vector-length.html
│ ├── vectors-equality.html
│ ├── vectors-subtraction.html
│ ├── vectors-sum.html
│ └── vectors.html
└── sitemap.txt
├── examples
├── bezier-curves
│ ├── bezier-cubic-curve-bbox.html
│ └── bezier-quadratic-curve-bbox.html
├── circular-movement
│ ├── circle-movement-1.html
│ ├── circle-movement-2.html
│ ├── circle-movement-3.html
│ ├── circle-movement-4.html
│ ├── circle-movement-mouse-1.html
│ ├── circle-movement-with-rotation.html
│ ├── ellipse-movement-2.html
│ └── ellipse-movement-3.html
├── css
│ ├── styles-1.css
│ ├── styles-2.css
│ ├── styles-3.css
│ ├── styles-4.css
│ └── styles-5.css
├── lissajous-curves
│ └── lissajous-curves-canvas.html
├── matrix-to-css-rotation.html
├── physics
│ ├── fireworks-2.html
│ ├── fireworks.html
│ └── throw.html
└── wave-movement
│ ├── wave-movement-1.html
│ └── wave-movement-2.html
├── jest.config.ts
├── package-lock.json
├── package.json
├── run
├── es6.js
├── esm.js
├── node.js
└── settings.js
├── src
├── docs
│ ├── client-side
│ │ ├── css
│ │ │ └── index.css
│ │ └── js
│ │ │ ├── dark-mode.ts
│ │ │ ├── index.tsx
│ │ │ └── menu
│ │ │ ├── mobile-menu.ts
│ │ │ └── side-menu.ts
│ ├── data
│ │ ├── config.json
│ │ ├── layouts
│ │ │ ├── page-layout.html
│ │ │ └── special-page-layout.html
│ │ ├── pages
│ │ │ ├── 10-main
│ │ │ │ ├── 1-typescript-usage.md
│ │ │ │ ├── 2-browser-usage.md
│ │ │ │ └── 3-nodejs-usage.md
│ │ │ ├── 100-color
│ │ │ │ ├── 1-color.md
│ │ │ │ ├── 2-random-color.md
│ │ │ │ ├── 3-convert-colors.md
│ │ │ │ ├── 4-shift-colors.md
│ │ │ │ └── 5-similar-colors.md
│ │ │ ├── 1000-other
│ │ │ │ ├── 1-set-decimal-places.md
│ │ │ │ ├── 10-series.md
│ │ │ │ ├── 11-greatest-common-divisor.md
│ │ │ │ ├── 2-convert-string-to-number.md
│ │ │ │ ├── 3-square-in-circle.md
│ │ │ │ ├── 4-modulo.md
│ │ │ │ ├── 5-convert-range.md
│ │ │ │ ├── 6-check-if-ranges-overlap.md
│ │ │ │ ├── 7-check-if-value-is-number.md
│ │ │ │ ├── 8-polar-to-cartesian.md
│ │ │ │ └── 9-temperature-conversion.md
│ │ │ ├── 105-linear-interpolation
│ │ │ │ ├── 1-lerp.md
│ │ │ │ └── 2-general-case.md
│ │ │ ├── 110-derivatives
│ │ │ │ ├── 1-polynomial.md
│ │ │ │ ├── 2-trigonometric-functions.md
│ │ │ │ └── 3-bezier-curves.md
│ │ │ ├── 120-collision-detection
│ │ │ │ ├── 1-rectangles-collision.md
│ │ │ │ ├── 2-circles-collision.md
│ │ │ │ └── 3-convex-polygons-collision.md
│ │ │ ├── 130-animation
│ │ │ │ ├── 1-animation.md
│ │ │ │ └── 2-get-animation-data.md
│ │ │ ├── 140-circle-and-ellipse
│ │ │ │ ├── 1-circumference.md
│ │ │ │ └── 2-is-angle-in-circle-arc.md
│ │ │ ├── 150-sequence
│ │ │ │ ├── 1-natural-numbers-sequence-sum.md
│ │ │ │ └── 2-arithmetic-sequence-sum.md
│ │ │ ├── 160-combinatorics
│ │ │ │ ├── 1-factorial.md
│ │ │ │ └── 2-combinatorics.md
│ │ │ ├── 20-vectors
│ │ │ │ ├── 1-vectors.md
│ │ │ │ ├── 10-distance-between-vectors.md
│ │ │ │ ├── 11-vector-initialization.md
│ │ │ │ ├── 12-vectors-equality.md
│ │ │ │ ├── 13-get-normal.md
│ │ │ │ ├── 2-vectors-sum.md
│ │ │ │ ├── 3-vectors-subtraction.md
│ │ │ │ ├── 4-multiply-vector-by-scalar.md
│ │ │ │ ├── 5-divide-vector-by-scalar.md
│ │ │ │ ├── 6-vector-length.md
│ │ │ │ ├── 7-normalize-vector.md
│ │ │ │ ├── 8-dot-product.md
│ │ │ │ └── 9-cross-product.md
│ │ │ ├── 30-matrix
│ │ │ │ ├── 1-matrix.md
│ │ │ │ ├── 10-inverse-matrix.md
│ │ │ │ ├── 11-matrix-singularity.md
│ │ │ │ ├── 12-adjugate-matrix.md
│ │ │ │ ├── 12-get-matrix-minor.md
│ │ │ │ ├── 2-matrix-sum.md
│ │ │ │ ├── 3-matrix-subtraction.md
│ │ │ │ ├── 4-multiply-by-scalar.md
│ │ │ │ ├── 5-divide-by-scalar.md
│ │ │ │ ├── 6-matrix-transposition.md
│ │ │ │ ├── 7-matrix-multiplication.md
│ │ │ │ ├── 8-multiply-matrix-by-vector.md
│ │ │ │ └── 9-matrix-determinant.md
│ │ │ ├── 40-matrix-manipulation
│ │ │ │ ├── 1-matrix-initialization.md
│ │ │ │ ├── 2-matrix-equality.md
│ │ │ │ ├── 3-matrix-deep-copy.md
│ │ │ │ ├── 4-append-or-prepend-row.md
│ │ │ │ ├── 5-append-or-prepend-column.md
│ │ │ │ ├── 6-remove-row-or-column.md
│ │ │ │ ├── 7-get-column.md
│ │ │ │ └── 8-reset-matrix.md
│ │ │ ├── 45-transformation-matrices
│ │ │ │ ├── 1-translation-matrix.md
│ │ │ │ ├── 2-rotation-matrix.md
│ │ │ │ ├── 3-rotate-around-point.md
│ │ │ │ ├── 4-scale-and-stretch-matrix.md
│ │ │ │ ├── 5-scale-around-point.md
│ │ │ │ ├── 6-reflection-matrix.md
│ │ │ │ ├── 7-shearing-matrix.md
│ │ │ │ └── 8-matrix-to-CSS-transform.md
│ │ │ ├── 50-angles
│ │ │ │ ├── 1-vector-angle.md
│ │ │ │ ├── 2-angle-between-vectors.md
│ │ │ │ ├── 3-degrees-and-radians.md
│ │ │ │ ├── 4-angles-distance.md
│ │ │ │ ├── 5-is-angle-between.md
│ │ │ │ ├── 6-is-clockwise.md
│ │ │ │ └── 7-percent-to-angle.md
│ │ │ ├── 60-random
│ │ │ │ ├── 1-get-random-number-in-range.md
│ │ │ │ ├── 2-get-random-integer.md
│ │ │ │ ├── 3-get-random-boolean.md
│ │ │ │ ├── 4-get-random-item-from-array.md
│ │ │ │ └── 5-random-id-or-GUID.md
│ │ │ ├── 70-bezier-curve
│ │ │ │ ├── 1-get-point-on-quadratic-bezier-curve.md
│ │ │ │ ├── 2-get-point-on-cubic-bezier-curve.md
│ │ │ │ ├── 3-tangent.md
│ │ │ │ ├── 4-normal.md
│ │ │ │ ├── 5-extrema.md
│ │ │ │ └── 6-bounding-box.md
│ │ │ ├── 80-equations
│ │ │ │ ├── 1-linear-equation.md
│ │ │ │ ├── 2-system-of-linear-equations.md
│ │ │ │ ├── 3-quadratic-equation.md
│ │ │ │ └── 4-get-linear-equation-by-2-points.md
│ │ │ ├── 90-path-movement
│ │ │ │ ├── 1-circle-movement.md
│ │ │ │ ├── 2-ellipse-movement.md
│ │ │ │ ├── 3-sine-wave-movement.md
│ │ │ │ └── 4-lissajous-curve.md
│ │ │ └── pages-config.json
│ │ └── special-pages
│ │ │ └── index.html
│ └── generator
│ │ ├── client-side
│ │ ├── css-provider.js
│ │ └── js-provider.js
│ │ ├── common-provider.js
│ │ ├── index.js
│ │ ├── markdown-config.js
│ │ └── render
│ │ ├── macros-provider.js
│ │ ├── pages-provider.js
│ │ ├── side-menu-provider.js
│ │ ├── sitemap-provider.js
│ │ └── special-pages-provider.js
├── index-esm.ts
├── index.ts
├── main
│ ├── angle.ts
│ ├── animation.ts
│ ├── bezier-curves
│ │ ├── bezier-curve.ts
│ │ └── bezier-formula-with-weights.svg
│ ├── circle-ellipse.ts
│ ├── collision-detection.ts
│ ├── color.ts
│ ├── combinatorics
│ │ ├── combinatorics.ts
│ │ └── factorial.ts
│ ├── convert.ts
│ ├── derivative.ts
│ ├── equations
│ │ ├── linear-equations.ts
│ │ └── quadratic-equations.ts
│ ├── format.ts
│ ├── id.ts
│ ├── linear-algebra
│ │ ├── matrix-transformations.ts
│ │ ├── matrix.ts
│ │ └── vector.ts
│ ├── linear-interpolation.ts
│ ├── ml.ts
│ ├── other.ts
│ ├── path-movement.ts
│ ├── physics.ts
│ ├── random.ts
│ ├── sequence.ts
│ ├── series.ts
│ ├── statistics.ts
│ └── temperature.ts
└── types.ts
├── test
├── angle.test.ts
├── bezier-curve.test.ts
├── browser
│ └── index.html
├── circle-ellipse.test.ts
├── collision-detection.test.ts
├── color.test.ts
├── combinatorics.test.ts
├── convert.test.ts
├── derivative.test.ts
├── equations.test.ts
├── factorial.test.ts
├── format.test.ts
├── linear-interpolation.test.ts
├── matrix-transformations.test.ts
├── matrix.test.ts
├── ml.test.ts
├── other.test.ts
├── sequence.test.ts
├── series.test.ts
├── statistics.test.ts
├── temperature.test.ts
└── verctor.test.ts
└── tsconfig.json
/.eslintrc.cjs:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | "env": {
3 | "browser": true,
4 | "es2021": true,
5 | "node": true,
6 | },
7 | "extends": [
8 | "eslint:recommended",
9 | "plugin:@typescript-eslint/eslint-recommended",
10 | "plugin:@typescript-eslint/recommended"
11 | ],
12 |
13 | "parser": "@typescript-eslint/parser",
14 | "parserOptions": {
15 | "ecmaVersion": "latest",
16 | "sourceType": "module"
17 | },
18 | "plugins": [
19 | "@typescript-eslint"
20 | ],
21 | "rules": {
22 | "@typescript-eslint/ban-ts-comment": "off",
23 | "@typescript-eslint/no-unused-vars": ["error", {argsIgnorePattern: "^_", destructuredArrayIgnorePattern: "^_"}]
24 | }
25 | }
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | TODO
2 |
3 | # Logs
4 | logs
5 | *.log
6 | npm-debug.log*
7 | yarn-debug.log*
8 | yarn-error.log*
9 | lerna-debug.log*
10 | .pnpm-debug.log*
11 |
12 | types/
13 |
14 | # Diagnostic reports (https://nodejs.org/api/report.html)
15 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
16 |
17 | # Runtime data
18 | pids
19 | *.pid
20 | *.seed
21 | *.pid.lock
22 |
23 | # Directory for instrumented libs generated by jscoverage/JSCover
24 | lib-cov
25 |
26 | # Coverage directory used by tools like istanbul
27 | coverage
28 | *.lcov
29 |
30 | # nyc test coverage
31 | .nyc_output
32 |
33 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
34 | .grunt
35 |
36 | # Bower dependency directory (https://bower.io/)
37 | bower_components
38 |
39 | # node-waf configuration
40 | .lock-wscript
41 |
42 | # Compiled binary addons (https://nodejs.org/api/addons.html)
43 | build/Release
44 |
45 | # Dependency directories
46 | node_modules/
47 | jspm_packages/
48 |
49 | # Snowpack dependency directory (https://snowpack.dev/)
50 | web_modules/
51 |
52 | # TypeScript cache
53 | *.tsbuildinfo
54 |
55 | # Optional npm cache directory
56 | .npm
57 |
58 | # Optional eslint cache
59 | .eslintcache
60 |
61 | # Optional stylelint cache
62 | .stylelintcache
63 |
64 | # Microbundle cache
65 | .rpt2_cache/
66 | .rts2_cache_cjs/
67 | .rts2_cache_es/
68 | .rts2_cache_umd/
69 |
70 | # Optional REPL history
71 | .node_repl_history
72 |
73 | # Output of 'npm pack'
74 | *.tgz
75 |
76 | # Yarn Integrity file
77 | .yarn-integrity
78 |
79 | # dotenv environment variable files
80 | #.env
81 | #.env.development.local
82 | #.env.test.local
83 | #.env.production.local
84 | #.env.local
85 |
86 | # parcel-bundler cache (https://parceljs.org/)
87 | .cache
88 | .parcel-cache
89 |
90 | # Next.static run output
91 | .next
92 | out
93 |
94 | # Nuxt.static run / generate output
95 | .nuxt
96 |
97 | # Gatsby files
98 | .cache/
99 | # Comment in the public line in if your project uses Gatsby and not Next.static
100 | # https://nextjs.org/blog/next-9-1#public-directory-support
101 | # public
102 |
103 | # vuepress run output
104 | .vuepress/dist
105 |
106 | # vuepress v2.x temp and cache directory
107 | .temp
108 | .cache
109 |
110 | # Docusaurus cache and generated files
111 | .docusaurus
112 |
113 | # Serverless directories
114 | .serverless/
115 |
116 | # FuseBox cache
117 | .fusebox/
118 |
119 | # DynamoDB Local files
120 | .dynamodb/
121 |
122 | # TernJS port file
123 | .tern-port
124 |
125 | # Stores VSCode versions used for testing VSCode extensions
126 | .vscode-test
127 |
128 | # yarn v2
129 | .yarn/cache
130 | .yarn/unplugged
131 | .yarn/build-state.yml
132 | .yarn/install-state.gz
133 | .pnp.*
134 |
135 | # jetbrains
136 | .idea
137 |
138 | # diff
139 | .DS_Store
140 | *.cache
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # CONTRIBUTING
2 |
3 | See [Contribution Guidelines here](https://github.com/mzusin/index/blob/main/CONTRIBUTING.md).
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | ## License
2 |
3 | The project has two types of licenses: open-source and commercial. In general, the project is free for non-commercial, trial and educational use, and paid for commercial use.
4 |
5 | ## Open source license
6 |
7 | The open source license can be used to create open source, trial and personal projects. The project uses the [GPLv3](https://www.gnu.org/licenses/gpl-3.0.html) open source license.
8 |
9 | Please note that releasing your application that uses this project under the [GPLv3](https://www.gnu.org/licenses/gpl-3.0.html) license, in turn, requires your application to be licensed under the GPLv3 license.
10 |
11 | ## Commercial license
12 |
13 | The commercial license should be used to create commercial products and applications, without the provisions of the [GPLv3](https://www.gnu.org/licenses/gpl-3.0.html) license. With the commercial license, your code is kept proprietary, to yourself. If you want to use this project to develop commercial websites, themes, projects, and applications, the commercial license is the way to go.
14 |
15 | - [Purchase commercial license here](https://payhip.com/b/SeBVQ)
16 | - [Read more about commercial license](https://github.com/mzusin/index/blob/main/LICENSE.md)
--------------------------------------------------------------------------------
/babel.config.cjs:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | [
4 | '@babel/preset-env',
5 | {
6 | targets: {
7 | node: 'current'
8 | }
9 | }
10 | ]
11 | ]
12 | };
--------------------------------------------------------------------------------
/docs/CNAME:
--------------------------------------------------------------------------------
1 | math.mzsoft.org
--------------------------------------------------------------------------------
/docs/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzusin/mz-math/2eeab90d17b4a42bf4f6c31120e2c00b77ec749a/docs/favicon.ico
--------------------------------------------------------------------------------
/docs/img/favicon/android-chrome-192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzusin/mz-math/2eeab90d17b4a42bf4f6c31120e2c00b77ec749a/docs/img/favicon/android-chrome-192.png
--------------------------------------------------------------------------------
/docs/img/favicon/android-chrome-512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzusin/mz-math/2eeab90d17b4a42bf4f6c31120e2c00b77ec749a/docs/img/favicon/android-chrome-512.png
--------------------------------------------------------------------------------
/docs/img/favicon/apple-touch-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzusin/mz-math/2eeab90d17b4a42bf4f6c31120e2c00b77ec749a/docs/img/favicon/apple-touch-icon.png
--------------------------------------------------------------------------------
/docs/img/favicon/browserconfig.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | #da532c
7 |
8 |
9 |
--------------------------------------------------------------------------------
/docs/img/favicon/favicon-128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzusin/mz-math/2eeab90d17b4a42bf4f6c31120e2c00b77ec749a/docs/img/favicon/favicon-128.png
--------------------------------------------------------------------------------
/docs/img/favicon/favicon-16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzusin/mz-math/2eeab90d17b4a42bf4f6c31120e2c00b77ec749a/docs/img/favicon/favicon-16.png
--------------------------------------------------------------------------------
/docs/img/favicon/favicon-256.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzusin/mz-math/2eeab90d17b4a42bf4f6c31120e2c00b77ec749a/docs/img/favicon/favicon-256.png
--------------------------------------------------------------------------------
/docs/img/favicon/favicon-32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzusin/mz-math/2eeab90d17b4a42bf4f6c31120e2c00b77ec749a/docs/img/favicon/favicon-32.png
--------------------------------------------------------------------------------
/docs/img/favicon/favicon-48.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzusin/mz-math/2eeab90d17b4a42bf4f6c31120e2c00b77ec749a/docs/img/favicon/favicon-48.png
--------------------------------------------------------------------------------
/docs/img/favicon/favicon-96.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzusin/mz-math/2eeab90d17b4a42bf4f6c31120e2c00b77ec749a/docs/img/favicon/favicon-96.png
--------------------------------------------------------------------------------
/docs/img/favicon/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzusin/mz-math/2eeab90d17b4a42bf4f6c31120e2c00b77ec749a/docs/img/favicon/favicon.ico
--------------------------------------------------------------------------------
/docs/img/favicon/favicon.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/docs/img/favicon/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "mzMath",
3 | "short_name": "mzMath",
4 | "icons": [
5 | {
6 | "src": "/img/favicons/android-chrome-192.png",
7 | "sizes": "192x192",
8 | "type": "image/png"
9 | },
10 | {
11 | "src": "/img/favicons/android-chrome-512.png",
12 | "sizes": "512x512",
13 | "type": "image/png"
14 | }
15 | ],
16 | "theme_color": "#ffffff",
17 | "background_color": "#ffffff",
18 | "display": "standalone"
19 | }
--------------------------------------------------------------------------------
/docs/img/favicon/mstile-150.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mzusin/mz-math/2eeab90d17b4a42bf4f6c31120e2c00b77ec749a/docs/img/favicon/mstile-150.png
--------------------------------------------------------------------------------
/examples/bezier-curves/bezier-cubic-curve-bbox.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Bezier Cubic Curve BBox
6 |
7 |
8 |
9 |
10 | Bezier Cubic Curve BBox
11 |
12 |
19 |
20 |
21 |
22 |
23 |
89 |
90 |
--------------------------------------------------------------------------------
/examples/bezier-curves/bezier-quadratic-curve-bbox.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Bezier Quadratic Curve BBox
6 |
7 |
8 |
9 |
10 | Bezier Quadratic Curve BBox
11 |
12 |
19 |
20 |
21 |
22 |
23 |
86 |
87 |
--------------------------------------------------------------------------------
/examples/circular-movement/circle-movement-2.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Circle Movement using "m2hToCSS" Function
6 |
7 |
8 |
9 |
10 | Circle Movement using "m2hToCSS" Function
11 |
12 |
19 |
20 |
21 |
22 |
23 |
24 |
89 |
90 |
--------------------------------------------------------------------------------
/examples/circular-movement/circle-movement-3.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Simple rotation using circle equation
6 |
7 |
8 |
9 |
10 | Simple rotation using circle equation
11 |
12 |
19 |
20 |
21 |
22 |
23 |
24 |
95 |
96 |
--------------------------------------------------------------------------------
/examples/circular-movement/circle-movement-mouse-1.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Circle movement after mouse
6 |
7 |
8 |
9 |
10 | Circle movement after mouse
11 |
12 |
13 |
14 |
21 |
22 |
23 |
24 |
25 |
26 |
51 |
52 |
--------------------------------------------------------------------------------
/examples/circular-movement/circle-movement-with-rotation.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Circle movement with rotation
6 |
7 |
8 |
9 |
10 | Circle movement with rotation
11 |
12 |
19 |
20 |
21 |
22 |
23 |
24 |
96 |
97 |
--------------------------------------------------------------------------------
/examples/circular-movement/ellipse-movement-2.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Ellipse movement using "m2hToCSS" Function
6 |
7 |
8 |
9 |
10 | Ellipse movement using "m2hToCSS" Function
11 |
12 |
19 |
20 |
21 |
22 |
23 |
24 |
89 |
90 |
--------------------------------------------------------------------------------
/examples/circular-movement/ellipse-movement-3.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Simple rotation using ellipse equation
6 |
7 |
8 |
9 |
10 | Simple rotation using ellipse equation
11 |
12 |
19 |
20 |
21 |
22 |
23 |
24 |
96 |
97 |
--------------------------------------------------------------------------------
/examples/css/styles-1.css:
--------------------------------------------------------------------------------
1 | html, body{
2 | padding: 0;
3 | margin: 0;
4 | }
5 |
6 | body{
7 | width: 100vw;
8 | height: 100vh;
9 | background: #232323;
10 | color: #efefef;
11 | display: flex;
12 | align-items: center;
13 | justify-content: center;
14 | }
15 |
16 | h1{
17 | position: absolute;
18 | top: 1rem;
19 | font-size: 1rem;
20 | font-weight: normal;
21 | }
22 |
23 | #center {
24 | width: 1rem;
25 | height: 1rem;
26 | background: red;
27 | position: absolute;
28 | top: 50%;
29 | left: 50%;
30 | border-radius: 100%;
31 | transform: translate(-0.5rem, -0.5rem);
32 | }
33 |
34 | #star{
35 | box-shadow: 0 0 1rem #fff;
36 | border-radius: 100%;
37 | }
--------------------------------------------------------------------------------
/examples/css/styles-2.css:
--------------------------------------------------------------------------------
1 | html, body{
2 | padding: 0;
3 | margin: 0;
4 | }
5 |
6 | body{
7 | width: 100vw;
8 | height: 100vh;
9 | background: #232323;
10 | color: #efefef;
11 | display: flex;
12 | align-items: center;
13 | justify-content: center;
14 | }
15 |
16 | h1{
17 | position: absolute;
18 | top: 1rem;
19 | font-size: 1rem;
20 | font-weight: normal;
21 | }
22 |
23 | #center {
24 | width: 1rem;
25 | height: 1rem;
26 | background: red;
27 | position: absolute;
28 | top: 50%;
29 | left: 50%;
30 | border-radius: 100%;
31 | transform: translate(-50%, -50%);
32 | }
33 |
34 | #star{
35 | box-shadow: 0 0 1rem #fff;
36 | border-radius: 100%;
37 | background: #000;
38 | transform: translate(-50%, -50%);
39 | }
40 |
41 | .circle{
42 | width: 270px;
43 | height: 270px;
44 | border: 5px solid #81b2d6;
45 | border-radius: 100%;
46 | }
--------------------------------------------------------------------------------
/examples/css/styles-3.css:
--------------------------------------------------------------------------------
1 | html, body{
2 | padding: 0;
3 | margin: 0;
4 | }
5 |
6 | body{
7 | width: 100vw;
8 | height: 100vh;
9 | background: #232323;
10 | color: #efefef;
11 | display: flex;
12 | align-items: center;
13 | justify-content: center;
14 | }
15 |
16 | h1{
17 | position: absolute;
18 | top: 0.5rem;
19 | font-size: 1rem;
20 | font-weight: normal;
21 | }
22 |
23 | canvas{
24 | border: 1px solid red;
25 | box-sizing: border-box;
26 | display: block;
27 | padding: 0;
28 | margin: 0;
29 | width: 800px;
30 | height: 800px;
31 | }
32 |
--------------------------------------------------------------------------------
/examples/css/styles-4.css:
--------------------------------------------------------------------------------
1 | html, body{
2 | padding: 0;
3 | margin: 0;
4 | }
5 |
6 | body{
7 | width: 100vw;
8 | height: 100vh;
9 | background: #232323;
10 | color: #efefef;
11 | display: flex;
12 | align-items: center;
13 | justify-content: center;
14 | }
15 |
16 | h1{
17 | position: absolute;
18 | top: 0.5rem;
19 | font-size: 1rem;
20 | font-weight: normal;
21 | }
22 |
23 | canvas{
24 | border: 1px solid #808080;
25 | box-sizing: border-box;
26 | display: block;
27 | padding: 0;
28 | margin: 0;
29 | width: 800px;
30 | height: 800px;
31 | }
32 |
--------------------------------------------------------------------------------
/examples/css/styles-5.css:
--------------------------------------------------------------------------------
1 | html, body{
2 | padding: 0;
3 | margin: 0;
4 | }
5 |
6 | body{
7 | width: 100vw;
8 | height: 100vh;
9 | display: flex;
10 | justify-content: center;
11 | }
12 |
13 | h1{
14 | top: 1rem;
15 | font-size: 1rem;
16 | font-weight: normal;
17 | }
18 |
19 | svg{
20 | border: 1px solid #b4b4b4;
21 | display: block;
22 | }
23 |
24 | #wrapper {
25 | margin: 3rem auto;
26 | }
--------------------------------------------------------------------------------
/examples/matrix-to-css-rotation.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Matrix to CSS matrix() function (rotation example)
6 |
7 |
8 |
9 |
10 |
11 |
18 |
19 |
20 |
21 |
22 |
23 |
81 |
82 |
--------------------------------------------------------------------------------
/examples/physics/fireworks.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Fireworks
6 |
7 |
8 |
9 |
10 | Fireworks
11 |
12 |
13 |
14 |
106 |
107 |
--------------------------------------------------------------------------------
/examples/physics/throw.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | A Throw
6 |
7 |
8 |
9 |
10 | A Throw
11 |
12 |
13 |
14 |
71 |
72 |
--------------------------------------------------------------------------------
/examples/wave-movement/wave-movement-1.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Sine Wave Movement
6 |
7 |
8 |
9 |
10 | Sine Wave Movement
11 |
12 |
19 |
20 |
21 |
22 |
60 |
61 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "mz-math",
3 | "version": "3.0.27",
4 | "description": "mzMath - a collection of TypeScript-based math helpers.",
5 | "main": "./dist/mz-math.min.js",
6 | "module": "./dist/mz-math.esm.js",
7 | "types": "./dist/index.d.ts",
8 | "exports": {
9 | "import": "./dist/mz-math.esm.js",
10 | "require": "./dist/mz-math.node.cjs",
11 | "default": "./dist/mz-math.esm.js"
12 | },
13 | "scripts": {
14 | "build:all": "npm run build:es6 & npm run build:node & npm run build:esm",
15 | "watch:all": "npm run watch:es6 & npm run watch:node & npm run watch:esm",
16 | "build:es6": "node run/es6.js",
17 | "watch:es6": "node run/es6.js -- watch",
18 | "build:node": "node run/node.js",
19 | "watch:node": "node run/node.js -- watch",
20 | "build:esm": "node run/esm.js",
21 | "watch:esm": "node run/esm.js -- watch",
22 | "test": "jest",
23 | "test:watch": "jest --watch",
24 | "eslint": "eslint ./src/**",
25 | "typescript-declarations": "tsc --emitDeclarationOnly",
26 | "docs:website": "http-server ./docs",
27 | "docs:build": "node ./src/docs/generator/index.js",
28 | "docs:watch": "nodemon ./src/docs/generator/index.js"
29 | },
30 | "type": "module",
31 | "keywords": [
32 | "math",
33 | "mathematics",
34 | "vector",
35 | "matrix",
36 | "angle",
37 | "linear algebra",
38 | "algebra",
39 | "random",
40 | "modulo",
41 | "range",
42 | "Bézier curve",
43 | "Bézier",
44 | "Bezier curve",
45 | "Bezier",
46 | "transformation matrix",
47 | "rotation matrix",
48 | "rotation",
49 | "scale matrix",
50 | "scale",
51 | "system of equations",
52 | "equation",
53 | "translation matrix",
54 | "reflection",
55 | "reflection matrix",
56 | "shearing",
57 | "shearing matrix",
58 | "css transform",
59 | "color",
60 | "derivatives",
61 | "lerp",
62 | "linear interpolation",
63 | "collision detection",
64 | "statistics",
65 | "combinatorics"
66 | ],
67 | "author": "Miriam Zusin ",
68 | "license": "SEE LICENSE IN LICENSE.md",
69 | "browserslist": [
70 | ">0.2%",
71 | "not dead",
72 | "not op_mini all"
73 | ],
74 | "repository": {
75 | "type": "git",
76 | "url": "https://github.com/mzusin/mz-math.git"
77 | },
78 | "devDependencies": {
79 | "@babel/preset-env": "^7.20.2",
80 | "@types/jest": "^29.2.3",
81 | "@typescript-eslint/eslint-plugin": "^5.43.0",
82 | "@typescript-eslint/parser": "^5.43.0",
83 | "esbuild": "^0.16.3",
84 | "eslint": "^8.27.0",
85 | "highlight.js": "^11.7.0",
86 | "jest": "^29.3.1",
87 | "markdown-documentation-maker": "^1.0.13",
88 | "mz-particles": "^1.0.5",
89 | "ts-jest": "^29.0.3",
90 | "ts-node": "^10.9.1"
91 | },
92 | "nodemonConfig": {
93 | "restartable": "rs",
94 | "ignore": [
95 | ".git",
96 | "node_modules/**/node_modules"
97 | ],
98 | "verbose": false,
99 | "watch": [
100 | "src/"
101 | ],
102 | "ext": "js,json,html,css,md,ts,tsx,glsl"
103 | }
104 | }
105 |
--------------------------------------------------------------------------------
/run/es6.js:
--------------------------------------------------------------------------------
1 | import esbuild from 'esbuild';
2 | import { settings } from './settings.js';
3 |
4 | const args = process.argv.slice(2);
5 | const watch = args.length > 1 && args[1].trim().toLowerCase() === 'watch';
6 |
7 | if(watch){
8 | // ------------- watch ---------------
9 | settings.watch = {
10 | onRebuild(error, result) {
11 |
12 | if (error){
13 | // console.error(error);
14 | }
15 | else {
16 | console.log('Succeeded.');
17 | }
18 | },
19 | };
20 | }
21 |
22 | esbuild
23 | .build(settings)
24 | .then(result => {
25 | console.log(watch ? 'Watching...' : 'Done.');
26 | })
27 | .catch(() => process.exit(1));
28 |
--------------------------------------------------------------------------------
/run/esm.js:
--------------------------------------------------------------------------------
1 | import esbuild from 'esbuild';
2 | import { settings } from './settings.js';
3 |
4 | const args = process.argv.slice(2);
5 | const watch = args.length > 1 && args[1].trim().toLowerCase() === 'watch';
6 |
7 | settings.platform = 'neutral';
8 | settings.format = 'esm';
9 | settings.entryPoints = ['./src/index-esm.ts'];
10 | settings.outfile = './dist/mz-math.esm.js';
11 |
12 | if(watch){
13 | // ------------- watch ---------------
14 | settings.watch = {
15 | onRebuild(error, result) {
16 |
17 | if (error){
18 | // console.error(error);
19 | }
20 | else {
21 | console.log('Succeeded.');
22 | }
23 | },
24 | };
25 | }
26 |
27 | esbuild
28 | .build(settings)
29 | .then(result => {
30 | console.log(watch ? 'Watching...' : 'Done.');
31 | })
32 | .catch(() => process.exit(1));
33 |
--------------------------------------------------------------------------------
/run/node.js:
--------------------------------------------------------------------------------
1 | import esbuild from 'esbuild';
2 | import { settings } from './settings.js';
3 |
4 | const args = process.argv.slice(2);
5 | const watch = args.length > 1 && args[1].trim().toLowerCase() === 'watch';
6 |
7 | settings.platform = 'node';
8 | settings.entryPoints = ['./src/index-esm.ts'];
9 | settings.outfile = './dist/mz-math.node.cjs';
10 |
11 | if(watch){
12 | // ------------- watch ---------------
13 | settings.watch = {
14 | onRebuild(error, result) {
15 |
16 | if (error){
17 | // console.error(error);
18 | }
19 | else {
20 | console.log('Succeeded.');
21 | }
22 | },
23 | };
24 | }
25 |
26 | esbuild
27 | .build(settings)
28 | .then(result => {
29 | console.log(watch ? 'Watching...' : 'Done.');
30 | })
31 | .catch(() => process.exit(1));
32 |
--------------------------------------------------------------------------------
/run/settings.js:
--------------------------------------------------------------------------------
1 | import fs from 'fs';
2 | import path from 'path';
3 |
4 | const packageJson = fs.readFileSync(path.join(process.cwd(), './package.json'), 'utf-8');
5 | let version = '1.0.0';
6 |
7 | try {
8 | const parsed = JSON.parse(packageJson);
9 | version = parsed.version;
10 | } catch (ex) {}
11 |
12 | export const settings = {
13 | entryPoints: ['./src/index.ts'],
14 | bundle: true,
15 | sourcemap: 'linked', // external
16 | minify: true,
17 | target: ['es6'],
18 | outfile: './dist/mz-math.min.js',
19 | banner: {
20 | js: `/*
21 | mzMath v${ version }
22 | A collection of TypeScript-based math helpers.
23 | https://github.com/mzusin/mz-math
24 | Licensed GPLv3 for open source use, or Commercial License for commercial use - https://github.com/mzusin/index/blob/main/LICENSE.md
25 | Copyright (c) 2023-present, Miriam Zusin
26 | */`,
27 | },
28 | };
--------------------------------------------------------------------------------
/src/docs/client-side/css/index.css:
--------------------------------------------------------------------------------
1 | /*!
2 | Theme: Tokyo-night-Dark
3 | origin: https://github.com/enkia/tokyo-night-vscode-theme
4 | Description: Original highlight.js style
5 | Author: (c) Henri Vandersleyen
6 | License: see project LICENSE
7 | Touched: 2022
8 | */
9 | pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs-comment,.hljs-meta{color:#565f89}.hljs-deletion,.hljs-doctag,.hljs-regexp,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-id,.hljs-selector-pseudo,.hljs-tag,.hljs-template-tag,.hljs-variable.language_{color:#f7768e}.hljs-link,.hljs-literal,.hljs-number,.hljs-params,.hljs-template-variable,.hljs-type,.hljs-variable{color:#ff9e64}.hljs-attribute,.hljs-built_in{color:#e0af68}.hljs-keyword,.hljs-property,.hljs-subst,.hljs-title,.hljs-title.class_,.hljs-title.class_.inherited__,.hljs-title.function_{color:#7dcfff}.hljs-selector-tag{color:#73daca}.hljs-addition,.hljs-bullet,.hljs-quote,.hljs-string,.hljs-symbol{color:#9ece6a}.hljs-code,.hljs-formula,.hljs-section{color:#7aa2f7}.hljs-attr,.hljs-char.escape_,.hljs-keyword,.hljs-name,.hljs-operator{color:#bb9af7}.hljs-punctuation{color:#c0caf5}.hljs{background:#1a1b26;color:#9aa5ce}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700}
10 |
11 | @tailwind base;
12 | @tailwind components;
13 |
14 | @media (prefers-reduced-motion: no-preference){
15 | :root {
16 | scroll-behavior: smooth;
17 | }
18 | }
19 |
20 | .dark {
21 | color-scheme: dark;
22 | }
23 |
24 | .hp-gradient {
25 | background: radial-gradient(#366d8c, #111927);
26 | }
27 |
28 | #hp-animation {
29 | pointer-events: none;
30 | }
31 |
32 | #hp-animation canvas {
33 | width: 100%;
34 | height: 100%;
35 | }
36 |
37 | .text-shadow {
38 | text-shadow: 0 0 1rem #081f2a;
39 | }
40 |
41 | @layer components {
42 | .w-350{
43 | width: 350px;
44 | }
45 |
46 | .w-100-350{
47 | width: calc(100% - 350px);
48 | }
49 |
50 | .w-800{
51 | width: 800px;
52 | }
53 |
54 | .side-menu{
55 | left: -100%;
56 | transition: left 0.5s ease;
57 | }
58 |
59 | .mobile-menu-opened .side-menu{
60 | left: 0;
61 | }
62 |
63 | .min-w-270{
64 | min-width: 270px;
65 | }
66 | }
67 |
68 | @tailwind utilities;
--------------------------------------------------------------------------------
/src/docs/client-side/js/dark-mode.ts:
--------------------------------------------------------------------------------
1 | const MODE_STORAGE_KEY = 'mode';
2 |
3 | export const handleDarkLightModes = () => {
4 |
5 | const mode = window.localStorage.getItem(MODE_STORAGE_KEY) || 'light';
6 | document.documentElement.classList.toggle('dark', mode === 'dark');
7 |
8 | const $moveToDarkBtn = document.getElementById('move-to-dark-mode-btn') as HTMLButtonElement;
9 | const $moveToLightBtn = document.getElementById('move-to-light-mode-btn') as HTMLButtonElement;
10 |
11 | const moveToDark = () => {
12 | document.documentElement.classList.add('dark');
13 | $moveToDarkBtn.classList.add('hidden');
14 | $moveToLightBtn.classList.remove('hidden');
15 | window.localStorage.setItem(MODE_STORAGE_KEY, 'dark');
16 | };
17 |
18 | const moveToLight = () => {
19 | document.documentElement.classList.remove('dark');
20 | $moveToLightBtn.classList.add('hidden');
21 | $moveToDarkBtn.classList.remove('hidden');
22 | window.localStorage.setItem(MODE_STORAGE_KEY, 'light');
23 | };
24 |
25 | if(mode === 'dark'){
26 | moveToDark();
27 | }
28 | else{
29 | moveToLight();
30 | }
31 |
32 | $moveToDarkBtn?.addEventListener('click', moveToDark);
33 | $moveToLightBtn?.addEventListener('click', moveToLight);
34 | };
35 |
--------------------------------------------------------------------------------
/src/docs/client-side/js/index.tsx:
--------------------------------------------------------------------------------
1 | import { initMenuCollapsible, initMenuScroll } from './menu/side-menu';
2 | import { initMobileMenu } from './menu/mobile-menu';
3 | import { handleDarkLightModes } from './dark-mode';
4 | // import hljs from 'highlight.js';
5 | import particles from 'mz-particles';
6 |
7 | const initAnimation = () => {
8 | const $placeholder = document.getElementById('hp-animation');
9 | if(!$placeholder) return;
10 |
11 | particles({
12 | $placeholder,
13 | particlesNumber: 100,
14 |
15 | minSize: 10,
16 | maxSize: 30,
17 |
18 | particlesColors: [
19 | '#366d8c', '#368c8c', '#fffc00', '#92fae7',
20 | '#5daed2', '#366d8c'
21 | ],
22 | connectionColor: '#7fb2b7',
23 |
24 | // stars -------------
25 | svgPathData: [
26 | 'm14.5 21.75-8.52289 4.48075 1.62773-9.49038-6.89516-6.72112 9.52888-1.38462L14.5 0l4.26144 8.63463 9.52888 1.38462-6.89516 6.72112 1.62773 9.49038z',
27 | 'M14.5 21.75 4.24695 24.75305 7.25 14.5 4.24695 4.24695 14.5 7.25l10.25305-3.00305L21.75 14.5l3.00305 10.25305z',
28 | 'm14.5 21.75-5.54891 6.14625.42239-8.26973-8.26973.42239L7.25 14.5 1.10375 8.95109l8.26973.42239-.42239-8.26973L14.5 7.25l5.54891-6.14625-.42239 8.26973 8.26973-.42239L21.75 14.5l6.14625 5.54891-8.26973-.42239.42239 8.26973z',
29 | ],
30 |
31 | // effects ------------
32 | rotate: true,
33 | // fadeInOut: true,
34 |
35 | // scale effect -------
36 | scaleInOut: true,
37 | maxScale: 1.2,
38 | minScale: 0.7,
39 | scaleStep: 0.005,
40 | });
41 | };
42 |
43 | const init = () => {
44 | const $special = document.getElementById('special-page');
45 | if($special) {
46 | initAnimation();
47 |
48 | /*if(hljs){
49 | hljs.highlightAll();
50 | }*/
51 | return;
52 | }
53 |
54 | initMobileMenu();
55 | initMenuScroll();
56 | initMenuCollapsible();
57 | handleDarkLightModes();
58 | };
59 |
60 | document.addEventListener('DOMContentLoaded', () => {
61 | init();
62 | });
63 |
64 | export {};
65 |
--------------------------------------------------------------------------------
/src/docs/client-side/js/menu/mobile-menu.ts:
--------------------------------------------------------------------------------
1 | export const initMobileMenu = () => {
2 | const $btn = document.getElementById('mobile-menu-btn');
3 | if(!$btn) return;
4 |
5 | $btn.addEventListener('click', (evt) => {
6 | evt.stopPropagation();
7 | document.body.classList.toggle('mobile-menu-opened');
8 | });
9 |
10 | document.body.addEventListener('click', () => {
11 | document.body.classList.remove('mobile-menu-opened');
12 | });
13 |
14 | const $sideMenu = document.getElementById('side-menu');
15 | if(!$sideMenu) return;
16 |
17 | $sideMenu.addEventListener('click', (evt) => {
18 | evt.stopPropagation();
19 | });
20 |
21 | const $close = document.getElementById('mobile-menu-close-btn');
22 | if(!$close) return;
23 |
24 | $close.addEventListener('click', () => {
25 | document.body.classList.remove('mobile-menu-opened');
26 | });
27 | };
28 |
--------------------------------------------------------------------------------
/src/docs/client-side/js/menu/side-menu.ts:
--------------------------------------------------------------------------------
1 | const COLLAPSIBLE_STORAGE_KEY = 'side-menu';
2 |
3 | interface ICollapsible {
4 | id: string;
5 | opened: boolean;
6 | }
7 |
8 | export const initMenuScroll = () => {
9 | const $menu = document.querySelector('.side-menu');
10 | if(!$menu) return;
11 |
12 | const path = window.location.pathname;
13 | const $link = $menu.querySelector(`a[href='${ path }']`);
14 | if(!$link) return;
15 |
16 | $link.scrollIntoView({
17 | block: 'center',
18 | });
19 | };
20 |
21 | const getStateFromStorage = (): ICollapsible[] => {
22 | const data = window.localStorage.getItem(COLLAPSIBLE_STORAGE_KEY);
23 | if(!data) return [];
24 |
25 | let menu: ICollapsible[] = [];
26 |
27 | try{
28 | menu = JSON.parse(data) || [];
29 | }
30 | catch(ex){
31 | // ...
32 | }
33 |
34 | return menu;
35 | };
36 |
37 | const saveStateToStorage = () => {
38 | const $titles = document.querySelectorAll('.side-menu [data-collapsible-title]');
39 | const menu: ICollapsible[] = [];
40 |
41 | for(const $title of $titles){
42 | const id = $title.getAttribute('data-id') || '';
43 | if(!id) continue;
44 |
45 | const opened = $title.getAttribute('data-opened') === 'true';
46 |
47 | menu.push({
48 | id,
49 | opened
50 | });
51 | }
52 |
53 | window.localStorage.setItem(COLLAPSIBLE_STORAGE_KEY, JSON.stringify(menu));
54 | };
55 |
56 | const restoreCollapsible = () => {
57 | const menu = getStateFromStorage();
58 | if(!Array.isArray(menu)) return;
59 |
60 | for(const menuItem of menu){
61 | const $title = document.querySelector(`.side-menu [data-id="${ menuItem.id }"]`) as HTMLElement;
62 | if(!$title) continue;
63 |
64 | toggle($title, menuItem.opened, false);
65 | }
66 | };
67 |
68 | const toggle = ($title: HTMLElement, opened: boolean, saveToStorage: boolean) => {
69 |
70 | $title.setAttribute('data-opened', opened.toString());
71 |
72 | const $arrow = $title.querySelector('[data-arrow]');
73 | if(!$arrow) return;
74 |
75 | $arrow.classList.toggle('rotate-90', opened);
76 | $title.nextElementSibling?.classList.toggle('hidden', !opened);
77 |
78 | if(saveToStorage){
79 | saveStateToStorage();
80 | }
81 | };
82 |
83 | export const initMenuCollapsible = () => {
84 | const $titles = document.querySelectorAll('.side-menu [data-collapsible-title]') as NodeListOf;
85 |
86 | for(const $title of $titles){
87 |
88 | $title.addEventListener('click', () => {
89 | const isOpened = $title.getAttribute('data-opened') === 'true';
90 | toggle($title, !isOpened, true);
91 | });
92 | }
93 |
94 | // try to restore collapsible state on page load
95 | restoreCollapsible();
96 | };
--------------------------------------------------------------------------------
/src/docs/data/config.json:
--------------------------------------------------------------------------------
1 | {
2 | "website": {
3 | "name": "mzMath",
4 | "url": "https://math.mzsoft.org"
5 | },
6 | "social": {
7 | "github": "https://github.com/mzusin/mz-math",
8 | "email": "miriam.zusin@gmail.com"
9 | },
10 | "analytics": {
11 | "gtag": ""
12 | }
13 | }
--------------------------------------------------------------------------------
/src/docs/data/layouts/special-page-layout.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {% website-name %}
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 | {% page-content %}
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/src/docs/data/pages/10-main/1-typescript-usage.md:
--------------------------------------------------------------------------------
1 | ## TypeScript Usage
2 |
3 | To use the library with TypeScript, you need to install the module from npm:
4 |
5 | ```shell
6 | npm install mz-math
7 | ```
8 |
9 | Or using Yarn:
10 |
11 | ```shell
12 | yarn add mz-math
13 | ```
14 |
15 | The import any function like **v2Sum**:
16 | ```js
17 | import { v2Sum, Vector2 } from 'mz-math';
18 |
19 | const v1: Vector2 = [1, 2];
20 | const v2: Vector2 = [3, 4];
21 | const sum = v2Sum(v1, v2); // [4, 6]
22 | ```
--------------------------------------------------------------------------------
/src/docs/data/pages/10-main/2-browser-usage.md:
--------------------------------------------------------------------------------
1 | ## Browser Usage
2 |
3 | The library can also be used directly in browsers without TypeScript. First, download the [mz-math.min.js](https://github.com/mzusin/mz-math/blob/main/dist/mz-math.min.js) file from the GitHub repository. Then use the **mzMath** global namespace to call any API or function.
4 |
5 | ```html
6 |
7 |
11 | ```
12 |
13 | The library is also available on the [jsDelivr CND](https://cdn.jsdelivr.net/npm/mz-math/dist/mz-math.min.js):
14 |
15 | ```html
16 |
17 |
21 | ```
--------------------------------------------------------------------------------
/src/docs/data/pages/10-main/3-nodejs-usage.md:
--------------------------------------------------------------------------------
1 | ## Node.js Usage
2 |
3 | The library can also be used in Node.js.
4 |
5 | ```shell
6 | npm install mz-math
7 | ```
8 |
9 | Or using Yarn:
10 |
11 | ```shell
12 | yarn add mz-svg
13 | ```
14 |
15 | Call any mzMath API or function:
16 |
17 | ```js
18 | const { setDecimalPlaces } = require('mz-math');
19 |
20 | const rounded = setDecimalPlaces(Math.PI, 2);
21 | console.log(rounded);
22 | ```
23 |
--------------------------------------------------------------------------------
/src/docs/data/pages/100-color/1-color.md:
--------------------------------------------------------------------------------
1 | # Color
2 |
3 | The library contains several color helper functions. It works with the following color types:
4 |
5 | ```js
6 | import { HSLColor, RGBColor, LABColor } from 'mz-math';
7 |
8 | // [hue, saturation, lightness]
9 | const hslColor: HSLColor = [0, 0, 0]; // [0-360, 0-100, 0-100]
10 |
11 | // [r, g, b]
12 | const rgbColor: RGBColor = [255, 255, 255]; // [0, 255, 0, 255, 0, 255]
13 |
14 | // [l, a, b]
15 | const labColor: LABColor = [100, 0, 0];
16 | ```
17 |
--------------------------------------------------------------------------------
/src/docs/data/pages/100-color/2-random-color.md:
--------------------------------------------------------------------------------
1 | # Get random color
2 |
3 | ```js
4 | import {
5 | HSLColor, RGBColor, getRandomHexColor,
6 | getRandomRGBColor, getRandomHSLColor,
7 | getRandomHSLColorWithHue, getRandomHSLColorWithSaturation,
8 | getRandomHSLColorWithinRanges, getRandomGrayscaleHSLColor
9 | } from 'mz-math';
10 |
11 | // get random HEX color
12 | const hexColor: string = getRandomHexColor();
13 |
14 | // get random RGB color
15 | const rgbColor: RGBColor = getRandomRGBColor();
16 |
17 | // get random HSL color
18 | const hslColor1: HSLColor = getRandomHSLColor();
19 |
20 | // get random HSL color with the specified hue
21 | const hslColor2: HSLColor = getRandomHSLColorWithHue(300); // hue = 300
22 |
23 | // get random HSL color with the specified saturation
24 | const hslColor2: HSLColor = getRandomHSLColorWithSaturation(50); // saturation = 50
25 |
26 | // get random HSL color with the specified lightness
27 | const hslColor3: HSLColor = getRandomHSLColorWithLightness(50); // lightness = 50
28 |
29 | // get random HSL color with the specified ranges:
30 | // hue: [10, 20], saturation: [0, 100], lightness: [30, 50]
31 | const hslColor4: HSLColor = getRandomHSLColorWithinRanges(
32 | 10, 20, // hue range
33 | 0, 100, // saturation range
34 | 30, 50, // lightness range
35 | );
36 |
37 | // get random gray color
38 | const hslColor5: HSLColor = getRandomGrayscaleHSLColor();
39 | ```
--------------------------------------------------------------------------------
/src/docs/data/pages/100-color/3-convert-colors.md:
--------------------------------------------------------------------------------
1 | # Convert Colors
2 |
3 | ```js
4 | import {
5 | HSLColor, RGBColor, LABColor,
6 | hslToRgb, rgbToHsl,
7 | hslToHex, rgbToHex, hexToRgb,
8 | rgbToLab, labToRgb,
9 | } from 'mz-math';
10 |
11 | const decimalPlaces = 2; // optional
12 |
13 | // convert RGB color to HSL color
14 | const hslColor: HSLColor = rgbToHsl([255, 0, 0], decimalPlaces); // [0, 100, 50] - red
15 |
16 | // convert HSL color to RGB color
17 | const rgbColor: RGBColor = hslToRgb([100, 100, 100], decimalPlaces);
18 |
19 | // convert HSL color to hex
20 | const hex: string = hslToHex([10, 10, 10]); // #1c1817
21 |
22 | // convert RGB color to hex
23 | const hex: string = rgbToHex([235, 64, 52]); // #eb4034
24 |
25 | // convert HEX color to RGB
26 | const rgbColor: RGBColor = hexToRgb('#eb4034'); // [235, 64, 52]
27 |
28 | // convert RGB color to LAB
29 | const labColor: LABColor = rgbToLab([255, 255, 255], decimalPlaces); // [100, 0, 0]
30 |
31 | // convert LAB color to RGB
32 | const rgbColor: RGBColor = labToRgb([100, 0, 0], decimalPlaces); // [255, 255, 255]
33 | ```
--------------------------------------------------------------------------------
/src/docs/data/pages/100-color/4-shift-colors.md:
--------------------------------------------------------------------------------
1 | # Shift colors
2 |
3 | ```js
4 | import { HSLColor, getShiftedHue, getShiftedSaturation, getShiftedLightness } from 'mz-math';
5 |
6 | // shift hue in [0, 0, 39] by -10 degrees
7 | const hslColor1: HSLColor = getShiftedHue([0, 0, 39], -10); // [350, 0, 39]
8 |
9 | // shift saturation in [0, 0, 39] by 10
10 | const hslColor2: HSLColor = getShiftedSaturation([0, 100, 39], 10); // [0, 10, 39]
11 |
12 | // shift lightness in [0, 0, 39] by 10
13 | const hslColor3: HSLColor = getShiftedLightness([0, 0, 39], 10); // [10, 0, 39]
14 | ```
15 |
--------------------------------------------------------------------------------
/src/docs/data/pages/100-color/5-similar-colors.md:
--------------------------------------------------------------------------------
1 | # Similar Colors
2 |
3 | ```js
4 | import { getColorsDelta, RGBColor } from 'mz-math';
5 |
6 | const decimalPlaces = 2; // optional
7 |
8 | const rgb1: RGBColor = [255, 0, 0];
9 | const rgb2: RGBColor = [255, 0, 0];
10 |
11 | const delta: number = getColorsDelta(rgb1, rgb2, decimalPlaces);
12 | ```
13 |
14 |
15 | **Result**
16 |
17 | | Value | Description |
18 | |---------|----------------------------------------|
19 | | <= 1.0 | Not perceptible by human eyes. |
20 | | 1 - 2 | Perceptible through close observation. |
21 | | 2 - 10 | Perceptible at a glance. |
22 | | 11 - 49 | Colors are more similar than opposite |
23 | | 100 | Colors are exact opposite |
24 |
25 |
26 | [Source - RGB-LAB Repo](https://github.com/antimatter15/rgb-lab)
--------------------------------------------------------------------------------
/src/docs/data/pages/1000-other/1-set-decimal-places.md:
--------------------------------------------------------------------------------
1 | # Set Decimal Places
2 |
3 | This helper allows to format a number to show a selected number of decimal places.
4 |
5 | ```js
6 | import { setDecimalPlaces } from 'mz-math';
7 |
8 | const res = setDecimalPlaces(1.2345, 2); // 1.23
9 | const res = setDecimalPlaces(1.2399, 2); // 1.24
10 | const res = setDecimalPlaces(1.2399, 0); // 1
11 | ```
12 |
13 | The result of this function is a number (not a string), so sometimes fewer decimal places will be displayed after rounding:
14 |
15 | ```js
16 | const res = setDecimalPlaces(1.239999, 4); // 1.2400 = 1.24
17 | ```
18 |
--------------------------------------------------------------------------------
/src/docs/data/pages/1000-other/10-series.md:
--------------------------------------------------------------------------------
1 | # Series
2 |
3 | ```js
4 | import { naturalNumbersSum1ToN } from 'mz-math';
5 |
6 | // 1 + 2 + 3
7 | const sum = naturalNumbersSum1ToN(3); // 6;
8 | ```
9 |
10 | ```js
11 | import { naturalNumbersSumMToN } from 'mz-math';
12 |
13 | // 5 + 6 + 7
14 | const sum = naturalNumbersSumMToN(5, 7); // 18
15 | ```
16 |
--------------------------------------------------------------------------------
/src/docs/data/pages/1000-other/11-greatest-common-divisor.md:
--------------------------------------------------------------------------------
1 | # Greatest common divisor (GCD)
2 |
3 | ```js
4 | import { gcd } from 'mz-math';
5 |
6 | const res1 = gcd(18, 6); // 6;
7 | const res2 = gcd(18, -6); // 6;
8 | ```
9 |
--------------------------------------------------------------------------------
/src/docs/data/pages/1000-other/2-convert-string-to-number.md:
--------------------------------------------------------------------------------
1 | # Convert string to number
2 |
3 | This function converts a numeric string to a number. If the string is not a number, it returns the provided default value.
4 |
5 | ```js
6 | import { stringToNumber } from 'mz-math';
7 |
8 | const res = stringToNumber('10.1234', 10); // 10.1234
9 | const res = stringToNumber(undefined, 10); // 10
10 | const res = stringToNumber(null, 10); // 10
11 | const res = stringToNumber('aaa', 10); // 10
12 | ```
13 |
--------------------------------------------------------------------------------
/src/docs/data/pages/1000-other/3-square-in-circle.md:
--------------------------------------------------------------------------------
1 | # Square in circle
2 |
3 | Get the side of a square inscribed in a circle of a given radius:
4 |
5 | ```js
6 | import { getSquareInCircleSide } from 'mz-math';
7 |
8 | const circleRadius = 10;
9 | const decimalPlaces = 2; // optional
10 |
11 | const squareSide = getSquareInCircleSide(10); // 14.14
12 | ```
--------------------------------------------------------------------------------
/src/docs/data/pages/1000-other/4-modulo.md:
--------------------------------------------------------------------------------
1 | # Modulo
2 |
3 | Calculate the modulo for positive or negative numbers.
4 |
5 | ```js
6 | import { mod } from 'mz-math';
7 |
8 | const res1 = mod(-21, 4); // 3
9 | const res2 = mod(7, 3); // 1
10 | ```
--------------------------------------------------------------------------------
/src/docs/data/pages/1000-other/5-convert-range.md:
--------------------------------------------------------------------------------
1 | # Convert range
2 |
3 | Converting a number from the range [a,b] to the range [c,d].
4 |
5 | ```js
6 | import { convertRange } from 'mz-math';
7 |
8 | // convert the value 0.5 from the range [0,1] to the range [100,200]
9 | const res = convertRange(0.5, 0, 1, 100, 200); // 150
10 | ```
11 |
--------------------------------------------------------------------------------
/src/docs/data/pages/1000-other/6-check-if-ranges-overlap.md:
--------------------------------------------------------------------------------
1 | # Check if two ranges overlap
2 |
3 | ```js
4 | import { doRangesOverlap } from 'mz-math';
5 |
6 | // [0,1] and [100,200] don't overlap
7 | const res1 = doRangesOverlap(0, 1, 100, 200); // false
8 |
9 | // [0,1] and [0.5, 1.5] overlap
10 | const res2 = doRangesOverlap(0, 1, 0.5, 1.5); // true
11 | ```
12 |
--------------------------------------------------------------------------------
/src/docs/data/pages/1000-other/7-check-if-value-is-number.md:
--------------------------------------------------------------------------------
1 | # Check if value can be converted to number
2 |
3 | ```js
4 | import { isNumber } from 'mz-math';
5 |
6 | const res = isNumber('12'); // true
7 | const res = isNumber(12.5); // true
8 | const res = isNumber('0'); // true
9 | const res = isNumber(0); // true
10 |
11 | const res = isNumber('aaa'); // false
12 | const res = isNumber(null); // false
13 | const res = isNumber(undefined); // false
14 | const res = isNumber(Infinity); // false
15 | ```
16 |
--------------------------------------------------------------------------------
/src/docs/data/pages/1000-other/8-polar-to-cartesian.md:
--------------------------------------------------------------------------------
1 | # Conversion between polar & cartesian coordinates
2 |
3 | ```js
4 | import { polarToCartesian, Vector2 } from 'mz-math';
5 |
6 | const center: Vector2 = [0, 0];
7 | const radii: Vector2 = [10, 20];
8 | const angleInRad = Math.PI / 4;
9 | const decimalPlaces = 2; // optional
10 |
11 | const res: Vector2 = polarToCartesian(center, radii, angleInRad, decimalPlaces); // 7.07, 14.14
12 | ```
13 |
--------------------------------------------------------------------------------
/src/docs/data/pages/1000-other/9-temperature-conversion.md:
--------------------------------------------------------------------------------
1 | # Temperature Conversions
2 |
3 | These functions allow conversion between different temperature scales. They accept a temperature value in one scale and return the equivalent temperature in another scale, with optional rounding to a specified number of decimal places.
4 |
5 | ```js
6 | import { celsiusToFahrenheit } from 'mz-math';
7 |
8 | const fahrenheit = celsiusToFahrenheit(0); // 32
9 |
10 | const fahrenheitRoundedTo2 = celsiusToFahrenheit(32.698034, 2); // 90.86;
11 | ```
12 |
13 | ```js
14 | import { celsiusToKelvin } from 'mz-math';
15 |
16 | const kelvin = celsiusToKelvin(-273.15); // 0
17 | ```
18 |
19 | ```js
20 | import { fahrenheitToCelsius } from 'mz-math';
21 |
22 | const celsius = fahrenheitToCelsius(32); // 0
23 | ```
24 |
25 | ```js
26 | import { fahrenheitToKelvin } from 'mz-math';
27 |
28 | const kelvin = fahrenheitToKelvin(32); // 273.15
29 | ```
30 |
31 | ```js
32 | import { kelvinToCelsius } from 'mz-math';
33 |
34 | const celsius = kelvinToCelsius(273.15); // 0
35 | ```
36 |
37 | ```js
38 | import { kelvinToFahrenheit } from 'mz-math';
39 |
40 | const fahrenheit = kelvinToFahrenheit(273.15); // 32
41 | ```
42 |
--------------------------------------------------------------------------------
/src/docs/data/pages/105-linear-interpolation/1-lerp.md:
--------------------------------------------------------------------------------
1 | # Lerp
2 |
3 | Lerp function performs a linear interpolation in the given range.
4 | Here **x** is a value that linearly interpolates between the **start** parameter and the **end** parameter.
5 |
6 | ```js
7 | import { lerp } from 'mz-math';
8 |
9 | const x = 5;
10 | const start = 0;
11 | const end = 100;
12 | const decimalPlaces = 2; // optional
13 |
14 | const result = lerp(x, start, end, decimalPlaces); // 500
15 | ```
16 |
17 | There are also versions of the lerp function for working with vectors of numbers:
18 |
19 | **2D Vector**
20 |
21 | ```js
22 | import { v2Lerp, Vector2 } from 'mz-math';
23 |
24 | const x = 15;
25 | const start: Vector2 = [0, 100];
26 | const end: Vector2 = [50, 1000];
27 | const decimalPlaces = 2; // optional
28 |
29 | const result: Vector2 = v2Lerp(x, start, end, decimalPlaces);
30 | ```
31 |
32 | **3D Vector**
33 |
34 | ```js
35 | import { v3Lerp, Vector3 } from 'mz-math';
36 |
37 | const x = 15;
38 | const start: Vector3 = [0, 100, 500];
39 | const end: Vector3 = [50, 400, 900];
40 | const decimalPlaces = 2; // optional
41 |
42 | const result: Vector3 = v3Lerp(x, start, end, decimalPlaces);
43 | ```
44 |
45 | **General Case**
46 |
47 | ```js
48 | import { vLerp, Vector } from 'mz-math';
49 |
50 | const x = 15;
51 | const start: Vector = [0, 100, 500, 1500];
52 | const end: Vector = [50, 400, 900, 2000];
53 | const decimalPlaces = 2; // optional
54 |
55 | const result: Vector = vLerp(x, start, end, decimalPlaces);
56 | ```
57 |
58 | There are also versions of the lerp function for working with matrices of numbers:
59 |
60 | **2D Matrix**
61 |
62 | ```js
63 | import { m2Lerp, Matrix2 } from 'mz-math';
64 |
65 | const x = 15;
66 | const start: Matrix2 = [
67 | [1, 2],
68 | [3, 4],
69 | ];
70 | const end: Matrix2 = [
71 | [100, 200],
72 | [300, 400],
73 | ];
74 | const decimalPlaces = 2; // optional
75 |
76 | const result: Matrix2 = m2Lerp(x, start, end, decimalPlaces);
77 | ```
78 |
79 | **3D Matrix**
80 |
81 | ```js
82 | import { m3Lerp, Matrix3 } from 'mz-math';
83 |
84 | const x = 15;
85 | const start: Matrix3 = [
86 | [1, 2, 3],
87 | [4, 5, 6],
88 | ];
89 | const end: Matrix3 = [
90 | [100, 200, 300],
91 | [400, 500, 600],
92 | ];
93 | const decimalPlaces = 2; // optional
94 |
95 | const result: Matrix3 = m3Lerp(x, start, end, decimalPlaces);
96 | ```
97 |
98 | **General Case**
99 |
100 | ```js
101 | import { mLerp, Matrix } from 'mz-math';
102 |
103 | const x = 25;
104 | const start: Matrix = [
105 | [1, 2, 3, 4],
106 | [4, 5, 6, 12],
107 | ];
108 | const end: Matrix = [
109 | [100, 200, 300, 800],
110 | [400, 500, 600, 1200],
111 | ];
112 | const decimalPlaces = 2; // optional
113 |
114 | const result: Matrix = mLerp(x, start, end, decimalPlaces);
115 | ```
--------------------------------------------------------------------------------
/src/docs/data/pages/105-linear-interpolation/2-general-case.md:
--------------------------------------------------------------------------------
1 | # General linear interpolation
2 |
3 | The **linearInterpolation()** function calculates linear interpolation using the following formula: `Y = ((X - X1) * (Y2 - Y1) / (X2 - X1)) + Y1`.
4 |
5 | ```js
6 | import { linearInterpolation, Vector2 } from 'mz-math';
7 |
8 | const x = 25;
9 | const start: Vector2 = [10, 50];
10 | const end: Vector2 = [100, 350];
11 | const decimalPlaces = 2; // optional
12 |
13 | const result = linearInterpolation(x, start, end, decimalPlaces);
14 | ```
15 |
--------------------------------------------------------------------------------
/src/docs/data/pages/110-derivatives/1-polynomial.md:
--------------------------------------------------------------------------------
1 | # Derivatives of Polynomials
2 |
3 | To take derivatives of a polynomial, you can use **dxPolynomial()** function.
4 | The polynomial is represented as an array, where each element is [coefficient, power]. For example, **y = 3x+2** is represented as **[[3, 1], [2, 0]]**.
5 |
6 | ```js
7 | import { dxPolynomial } from 'mz-math';
8 |
9 | const x = 10;
10 |
11 | // y = 3x+2
12 | const polynomial = [[3, 1], [2, 0]];
13 |
14 | const decimalPlaces = 2; // optional
15 |
16 | const result = dxPolynomial(x, polynomial, decimalPlaces);
17 | ```
--------------------------------------------------------------------------------
/src/docs/data/pages/110-derivatives/2-trigonometric-functions.md:
--------------------------------------------------------------------------------
1 | # Derivatives of trigonometric functions
2 |
3 | **Sine Function**
4 |
5 | ```js
6 | import { dxSin } from 'mz-math';
7 |
8 | const decimalPlaces = 2; // optional
9 | const result = dxSin(Math.PI, decimalPlaces); // -1
10 | ```
11 |
12 | **Cosine Function**
13 |
14 | ```js
15 | import { dxCos } from 'mz-math';
16 |
17 | const decimalPlaces = 2; // optional
18 | const result = dxCos(Math.PI/2, decimalPlaces); // -1
19 | ```
20 |
21 | **Tangent Function**
22 |
23 | ```js
24 | import { dxTan } from 'mz-math';
25 |
26 | const decimalPlaces = 2; // optional
27 | const result = dxTan(Math.PI, decimalPlaces); // 1
28 | ```
29 |
30 | **Cotangent Function**
31 |
32 | ```js
33 | import { dxCot } from 'mz-math';
34 |
35 | const decimalPlaces = 2; // optional
36 | const result = dxCot(Math.PI/2, decimalPlaces); // -1
37 | ```
38 |
39 | **ArcSine Function**
40 |
41 | ```js
42 | import { dxArcSin } from 'mz-math';
43 |
44 | const decimalPlaces = 2; // optional
45 | const result = dxArcSin(Math.PI/4, decimalPlaces); // 1.62
46 | ```
47 |
48 | **ArcCosine Function**
49 |
50 | ```js
51 | import { dxArcCos } from 'mz-math';
52 |
53 | const decimalPlaces = 2; // optional
54 | const result = dxArcCos(Math.PI/4, decimalPlaces); // -1.62
55 | ```
56 |
57 | **ArcTangent Function**
58 |
59 | ```js
60 | import { dxArcTan } from 'mz-math';
61 |
62 | const decimalPlaces = 2; // optional
63 | const result = dxArcTan(Math.PI/4, decimalPlaces); // 0.62
64 | ```
65 |
66 | **ArcCotangent Function**
67 |
68 | ```js
69 | import { dxArcCot } from 'mz-math';
70 |
71 | const decimalPlaces = 2; // optional
72 | const result = dxArcCot(Math.PI/4, decimalPlaces); // -0.62
73 | ```
--------------------------------------------------------------------------------
/src/docs/data/pages/110-derivatives/3-bezier-curves.md:
--------------------------------------------------------------------------------
1 | # Derivatives of Bézier Curves
2 |
3 | To take derivatives of a quadratic Bézier Curve, you can use **dxV2QuadraticBezierCurve()** or **dxV3QuadraticBezierCurve()** functions.
4 |
5 | ```js
6 | import { dxV2QuadraticBezierCurve, Vector2 } from 'mz-math';
7 |
8 | const t = 0.6; // mast be in range [0, 1]
9 | const startControlPoint: Vector2 = [150, 550];
10 | const centerControlPoint: Vector2 = [400, 300];
11 | const endControlPoint: Vector2 = [50, 550];
12 | const decimalPlaces = 2; // optional
13 |
14 | const result: Vector2 = dxV2QuadraticBezierCurve(
15 | t,
16 | startControlPoint,
17 | centerControlPoint,
18 | endControlPoint,
19 | decimalPlaces
20 | );
21 | ```
22 |
23 | ```js
24 | import { dxV3QuadraticBezierCurve, Vector3 } from 'mz-math';
25 |
26 | const t = 0.6; // mast be in range [0, 1]
27 | const startControlPoint: Vector3 = [150, 550, 0];
28 | const centerControlPoint: Vector3 = [400, 300, 0];
29 | const endControlPoint: Vector3 = [50, 550, 0];
30 | const decimalPlaces = 2; // optional
31 |
32 | const result: Vector3 = dxV3QuadraticBezierCurve(
33 | t,
34 | startControlPoint,
35 | centerControlPoint,
36 | endControlPoint,
37 | decimalPlaces
38 | );
39 | ```
40 |
41 | To take derivatives of a cubic Bézier Curve, you can use **dxV2CubicBezierCurve()** or **dxV3CubicBezierCurve()** functions.
42 |
43 | ```js
44 | import { dxV2CubicBezierCurve, Vector2 } from 'mz-math';
45 |
46 | const t = 0.6; // mast be in range [0, 1]
47 | const startControlPoint: Vector2 = [100, 200];
48 | const center1ControlPoint: Vector2 = [100, 50];
49 | const center2ControlPoint: Vector2 = [200, 150];
50 | const endControlPoint: Vector2 = [300, 250];
51 | const decimalPlaces = 2; // optional
52 |
53 | const result: Vector2 = dxV2CubicBezierCurve(
54 | t,
55 | startControlPoint,
56 | center1ControlPoint,
57 | center2ControlPoint,
58 | endControlPoint,
59 | decimalPlaces
60 | );
61 | ```
62 |
63 | ```js
64 | import { dxV3CubicBezierCurve, Vector3 } from 'mz-math';
65 |
66 | const t = 0.6; // mast be in range [0, 1]
67 | const startControlPoint: Vector3 = [100, 200, 0];
68 | const center1ControlPoint: Vector3 = [100, 50, 0];
69 | const center2ControlPoint: Vector3 = [200, 150, 0];
70 | const endControlPoint: Vector3 = [300, 250, 0];
71 | const decimalPlaces = 2; // optional
72 |
73 | const result: Vector3 = dxV3CubicBezierCurve(
74 | t,
75 | startControlPoint,
76 | center1ControlPoint,
77 | center2ControlPoint,
78 | endControlPoint,
79 | decimalPlaces
80 | );
81 | ```
--------------------------------------------------------------------------------
/src/docs/data/pages/120-collision-detection/1-rectangles-collision.md:
--------------------------------------------------------------------------------
1 | # Rectangles Collision
2 |
3 | This function **rectCollide()** returns true if the rectangles collide.
4 |
5 | ```ts
6 | import { rectCollide } from 'mz-math';
7 |
8 | const rect1 = { x: 0, y: 0, w: 10, h: 10 };
9 | const rect2 = { x: 5, y: 5, w: 10, h: 10 };
10 |
11 | const isCollide = rectCollide(rect1, rect2); // true
12 | ```
13 |
14 | **IRect** TypeScript interface is defined as follows:
15 |
16 | ```ts
17 | export interface IRect {
18 | x: number;
19 | y: number;
20 | w: number;
21 | h: number;
22 | }
23 | ```
--------------------------------------------------------------------------------
/src/docs/data/pages/120-collision-detection/2-circles-collision.md:
--------------------------------------------------------------------------------
1 | # Circles Collision
2 |
3 | This function **circleCollide()** returns true if the circles collide.
4 |
5 | ```ts
6 | import { circleCollide } from 'mz-math';
7 |
8 | const circle1 = { cx: 0, cy: 0, r: 10 };
9 | const circle2 = { cx: 20, cy: 20, r: 5 };
10 |
11 | const isCollide = circleCollide(rect1, rect2); // false
12 | ```
13 |
14 | **ICircle** TypeScript interface is defined as follows:
15 |
16 | ```ts
17 | export interface ICircle {
18 | cx: number;
19 | cy: number;
20 | r: number;
21 | }
22 | ```
--------------------------------------------------------------------------------
/src/docs/data/pages/120-collision-detection/3-convex-polygons-collision.md:
--------------------------------------------------------------------------------
1 | # Convex Polygons Collision
2 |
3 | This function **convexPolygonsCollide()** returns true if the convex polygons collide. It implements Separating Axis Theorem (SAT).
4 |
5 | ```ts
6 | import { convexPolygonsCollide } from 'mz-math';
7 |
8 | const poly1: Vector2[] = [[0, 0], [10, 0], [5, 10]];
9 | const poly2: Vector2[] = [[5, 5], [15, 5], [10, 15]];
10 |
11 | const isCollide = convexPolygonsCollide(poly1, poly2); // true
12 | ```
13 |
14 | **IPolygon** type is defined as follows:
15 |
16 | ```ts
17 | export type IPolygon = Vector2[];
18 | ```
--------------------------------------------------------------------------------
/src/docs/data/pages/130-animation/1-animation.md:
--------------------------------------------------------------------------------
1 | # Animation
2 |
3 | The library contains an animation API that can control the animation flow. Basic usage:
4 |
5 | ```ts
6 | import { animate, IAnimationResult } from 'mz-math';
7 |
8 | const api: IAnimationResult = animate({
9 |
10 | // A function to be called on each animation frame.
11 | // It receives an object of type IAnimationResult.
12 | callback: (result: IAnimationResult) => {
13 | // DO ANY RENDERING LOGIC HERE
14 | },
15 |
16 | // Optional property.
17 | // The duration of the animation in milliseconds.
18 | // If not provided, the animation will continue indefinitely.
19 | duration: 1000,
20 |
21 | // Optional property.
22 | // If true, the animation will restart whenever
23 | // the size of the document body changes. Default is false.
24 | restartOnResize: true,
25 |
26 | // Optional property.
27 | resizeCallback: (_entries: ResizeObserverEntry[], _observer: ResizeObserver) => {
28 | // Do something on resize
29 | }
30 | });
31 |
32 | // Starts the animation.
33 | api.start();
34 |
35 | /*
36 | // Stops the animation.
37 | api.stop();
38 |
39 | // Pauses the animation.
40 | api.pause();
41 |
42 | // Resumes the animation from where it was paused.
43 | api.resume();
44 |
45 | // Restarts the animation from the beginning.
46 | api.restart();
47 | */
48 | ```
49 |
50 |
51 | The **IAnimationResult** interface defines the methods and properties returned by the animate function.
52 |
53 | ```ts
54 | export interface IAnimationResult {
55 | start: () => void;
56 | stop: () => void;
57 | pause: () => void;
58 | resume: () => void;
59 | restart: () => void;
60 | isAnimating: () => boolean;
61 | getStartTime: () => number|undefined;
62 | getElapsedTime: () => number|undefined;
63 | getPercent: () => number|undefined;
64 | getResizeObserver: () => ResizeObserver|undefined;
65 | }
66 | ```
--------------------------------------------------------------------------------
/src/docs/data/pages/130-animation/2-get-animation-data.md:
--------------------------------------------------------------------------------
1 | # Get Animation Data
2 |
3 | The animation API has various helpers for getting information about the current animation.
4 |
5 | ```ts
6 | // Returns true if the animation is currently running, false otherwise.
7 | const animating: boolean = api.isAnimating();
8 | ```
9 |
10 | ```ts
11 | // Returns the timestamp (in milliseconds) when the animation was started.
12 | const animating: number = api.getStartTime();
13 | ```
14 |
15 | ```ts
16 | // Returns the time elapsed (in milliseconds) since the animation was started.
17 | const animating: number = api.getElapsedTime();
18 | ```
19 |
20 | ```ts
21 | // Returns the percentage of the animation that has been completed (0 to 100).
22 | // Returns undefined if the duration is infinite, or if the animation hasn't started yet.
23 | const percent: number = api.getPercent();
24 | ```
25 |
26 | ```ts
27 | // Returns the ResizeObserver used by the animation to detect changes in the size of the document body.
28 | // Returns undefined if restartOnResize property is false.
29 | const observer: ResizeObserve = api.getResizeObserver();
30 | ```
31 |
32 |
--------------------------------------------------------------------------------
/src/docs/data/pages/140-circle-and-ellipse/1-circumference.md:
--------------------------------------------------------------------------------
1 | # Get Circle & Ellipse Circumference
2 |
3 | **Get Circle Circumference**
4 |
5 | ```js
6 | import { getCircleCircumference } from 'mz-math';
7 |
8 | const radius = 10;
9 | const decimalPlaces = 2; // optional
10 |
11 | const circumference = getCircleCircumference(radius, decimalPlaces); // 62.83
12 | ```
13 |
14 | **Get Ellipse Circumference**
15 |
16 | ```js
17 | import { getEllipseCircumference } from 'mz-math';
18 |
19 | const radius1 = 10;
20 | const radius1 = 20;
21 | const decimalPlaces = 2; // optional
22 |
23 | const circumference = getEllipseCircumference(radius1, radius2, decimalPlaces); // 99.35
24 | ```
--------------------------------------------------------------------------------
/src/docs/data/pages/140-circle-and-ellipse/2-is-angle-in-circle-arc.md:
--------------------------------------------------------------------------------
1 | # Get Circle & Ellipse Circumference
2 |
3 | The isAngleInCircleArc() function checks whether a given angle falls within a circular arc defined by a start angle and an end angle. It considers the possibility of the arc crossing the 360-degree mark and handles it accordingly.
4 |
5 | ```js
6 | import { isAngleInCircleArc } from 'mz-math';
7 |
8 | const startAngleDeg = 0;
9 | const endAngleDeg = 90;
10 | const currentDegrees = 45;
11 |
12 | const isInAcr = isAngleInCircleArc(startAngleDeg, endAngleDeg, currentDegrees); // true
13 | ```
14 |
15 | ```js
16 | import { isAngleInCircleArc } from 'mz-math';
17 |
18 | const startAngleDeg = 0;
19 | const endAngleDeg = 90;
20 | const currentDegrees = 180;
21 |
22 | const isInAcr = isAngleInCircleArc(startAngleDeg, endAngleDeg, currentDegrees); // false
23 | ```
24 |
--------------------------------------------------------------------------------
/src/docs/data/pages/150-sequence/1-natural-numbers-sequence-sum.md:
--------------------------------------------------------------------------------
1 | # Natural Numbers Sequence Sum
2 |
3 | ```js
4 | import { arithmeticSequenceSum } from 'mz-math';
5 |
6 | const sum = arithmeticSequenceSum(5); // 15
7 | ```
8 |
--------------------------------------------------------------------------------
/src/docs/data/pages/150-sequence/2-arithmetic-sequence-sum.md:
--------------------------------------------------------------------------------
1 | # Arithmetic Sequence Sum
2 |
3 | ```js
4 | import { naturalNumbersSequenceSum } from 'mz-math';
5 |
6 | // n = the number of terms to be added
7 | const n = 4;
8 |
9 | // a = the first term in the sequence
10 | const a = 2;
11 |
12 | // d = the constant value between terms
13 | const d = 2;
14 |
15 | // 2 + 4 + 6 + 8
16 | const sum = naturalNumbersSequenceSum(n, a, d); // 20
17 | ```
18 |
--------------------------------------------------------------------------------
/src/docs/data/pages/160-combinatorics/1-factorial.md:
--------------------------------------------------------------------------------
1 | # Factorial
2 |
3 | ```js
4 | import { factorial } from 'mz-math';
5 |
6 | const res1 = factorial(5); // 1*2*3*4*5 = 120
7 | const res2 = factorial(5, 3); // 3*4*5 = 60
8 | ```
--------------------------------------------------------------------------------
/src/docs/data/pages/160-combinatorics/2-combinatorics.md:
--------------------------------------------------------------------------------
1 | # Combinatorics
2 |
3 | ```js
4 | import {
5 | permutationsWithRepetition,
6 | permutationsWithoutRepetition,
7 | combinationsWithoutRepetition,
8 | combinationsWithRepetition,
9 | } from 'mz-math';
10 |
11 | const res1 = permutationsWithRepetition(3, 2); // 9
12 | const res2 = permutationsWithoutRepetition(4, 4); // 24
13 | const res3 = combinationsWithoutRepetition(16, 3); // 560
14 | const res4 = combinationsWithRepetition(5, 3); // 35
15 | ```
--------------------------------------------------------------------------------
/src/docs/data/pages/20-vectors/1-vectors.md:
--------------------------------------------------------------------------------
1 | # Vectors
2 |
3 | There are the following types of vectors:
4 | **Vector2** for a 2D vector, **Vector3** for a 3D vector, and **Vector** for the general case.
5 |
6 | ```js
7 | import { Vector2, Vector3, Vector4, Vector } from 'mz-math';
8 |
9 | const v2: Vector2 = [1, 2];
10 | const v3: Vector3 = [1, 2, 3];
11 | const v4: Vector4 = [1, 2, 3, 4];
12 |
13 | const v5: Vector = [1, 2, 3, 4, 5];
14 | const v6: Vector = [1, 2, 3, 4, 5, 6];
15 | ```
--------------------------------------------------------------------------------
/src/docs/data/pages/20-vectors/10-distance-between-vectors.md:
--------------------------------------------------------------------------------
1 | ## Get distance between 2 vectors
2 |
3 | **2D vectors**
4 |
5 | ```js
6 | import { v2Distance, Vector2 } from 'mz-math';
7 |
8 | const v1: Vector2 = [1, 2];
9 | const v2: Vector2 = [4, 5];
10 | const distance = v2Distance(v1, v2);
11 | ```
12 |
13 | **3D vectors**
14 |
15 | ```js
16 | import { v3Distance, Vector2 } from 'mz-math';
17 |
18 | const v1: Vector2 = [1, 2, 3];
19 | const v2: Vector2 = [4, 5, 6];
20 | const distance = v3Distance(v1, v2);
21 | ```
22 |
23 | **General case**
24 |
25 | ```js
26 | import { vDistance, Vector } from 'mz-math';
27 |
28 | const v1: Vector = [1, 2, 3];
29 | const v2: Vector = [4, 5, 6];
30 | const distance = vDistance(v1, v2);
31 | ```
32 |
--------------------------------------------------------------------------------
/src/docs/data/pages/20-vectors/11-vector-initialization.md:
--------------------------------------------------------------------------------
1 | ## Vector Initialization Helpers
2 |
3 | There are helpers for creating v2, v3 and vN vectors with a default value. If no default value is specified, it will be zero.
4 |
5 | ```js
6 | import { v2, v3, v4, vN } from 'mz-math';
7 |
8 | const v2 = v2(); // [0, 0]
9 | const v2_10 = v2(10); // [10, 10]
10 |
11 | const v3 = v3(); // [0, 0, 0]
12 | const v3_10 = v3(10); // [10, 10, 10]
13 |
14 | const v4 = v4(); // [0, 0, 0, 0]
15 | const v4_10 = v4(10); // [10, 10, 10, 10]
16 |
17 | const v5 = vN(5); // [0, 0, 0, 0, 0]
18 | const v5_10 = vN(5, 10); // [10, 10, 10, 10, 10]
19 | ```
20 |
21 | **Initialize vector using polar coordinates**
22 |
23 | ```js
24 | import { Vector2 } from 'mz-math';
25 |
26 | const distance = 10;
27 | const angleRad = Math.PI/4;
28 | const v2: Vector2 = v2FromPolarCoords(distance, angleRad);
29 | ```
--------------------------------------------------------------------------------
/src/docs/data/pages/20-vectors/12-vectors-equality.md:
--------------------------------------------------------------------------------
1 | ## Check if 2 vectors are equal
2 |
3 | It's possible to perform a deep comparison of two vectors using the **vEqual** function:
4 |
5 | ```js
6 | import { vEqual } from 'mz-math';
7 |
8 | const res1 = vEqual([1, 0], [1, 0]); // true
9 | const res2 = vEqual([1, 0], [0, 1]); // false
10 | const res3 = vEqual([0, 0, 0], [0, 0]); // false
11 | ```
--------------------------------------------------------------------------------
/src/docs/data/pages/20-vectors/13-get-normal.md:
--------------------------------------------------------------------------------
1 | ## Get Vector Normal
2 |
3 | ```js
4 | import { v2GetNormal, Vector2 } from 'mz-math';
5 |
6 | const vector1: Vector2 = [10, 20];
7 | const vector2: Vector2 = [20, 30];
8 | const decimalPlaces = 2; // optional
9 |
10 | const res: Vector2 = v2GetNormal(vector1, vector2, decimalPlaces); // [-10, 10]
11 | ```
12 |
--------------------------------------------------------------------------------
/src/docs/data/pages/20-vectors/2-vectors-sum.md:
--------------------------------------------------------------------------------
1 | ## Vectors Sum
2 |
3 | The following functions are used to add vectors: **v2Sum** for a 2D vector, **v3Sum** for a 3D vector, and **vSum** for the general case. Each function receives an optional **decimalPlaces** parameter.
4 |
5 | **2D Vector**
6 | ```js
7 | import { v2Sum, Vector2 } from 'mz-math';
8 |
9 | const sum1 = v2Sum([1, 2], [3, 4]); // [4, 6]
10 |
11 | const vector1: Vector2 = [3.12456, 4.56734];
12 | const vector2: Vector2 = [5.12323, 6.001234];
13 | const sum2 = v2Sum(vector1, vector2, 2); // [8.25, 10.57]
14 | ```
15 |
16 | **3D Vector**
17 | ```js
18 | import { v3Sum, Vector3 } from 'mz-math';
19 |
20 | const sum1 = v3Sum([1, 2, 3], [3, 4, 4]); // [4, 6, 7]
21 |
22 | const vector1: Vector3 = [3.2345, 4.0013234, 5.2523453];
23 | const vector2: Vector3 = [6.111, 7.222, 8.333];
24 | const sum2 = v3Sum(vector1, vector2, 2); // [9.35, 11.22, 13.59]
25 | ```
26 |
27 | **General Case**
28 | ```js
29 | import { vSum, Vector } from 'mz-math';
30 |
31 | const v1: Vector = [1, 2, 3, 4];
32 | const v2: Vector = [5, 6, 7, 8];
33 | const sum = vSum(v1, v2); // [6, 8, 10, 12];
34 | ```
--------------------------------------------------------------------------------
/src/docs/data/pages/20-vectors/3-vectors-subtraction.md:
--------------------------------------------------------------------------------
1 | ## Vectors Subtraction
2 |
3 | The following functions are used to add vectors: **v2Sub** for a 2D vector, **v3Sub** for a 3D vector, and **vSub** for the general case. Each function receives an optional **decimalPlaces** parameter.
4 |
5 | **2D Vector**
6 | ```js
7 | import { v2Sub, Vector2 } from 'mz-math';
8 |
9 | const sub1 = v2Sub([1, 2], [3, 4]); // [-2, -2]
10 |
11 | const vector1: Vector2 = [-1.125324, -2.23453245];
12 | const vector2: Vector2 = [3.2345, 4.3574365];
13 | const sub2 = v2Sub(vector1, vector2, 2); // [-4.36, -6.59]
14 | ```
15 |
16 | **3D Vector**
17 | ```js
18 | import { v3Sub, Vector3 } from 'mz-math';
19 |
20 | const sub1 = v3Sub([1, 2, 3], [3, 4, 4]); // [-2, -2, -1]
21 |
22 | const vector1: Vector3 = [1.12754, 2.999345, 3.34653456];
23 | const vector2: Vector3 = [7.352345, 8.35734, 9.2345];
24 | const sub2 = v3Sub(vector1, vector2, 2); // [-6.22, -5.36, -5.89]
25 | ```
26 |
27 | **General Case**
28 | ```js
29 | import { vSub, Vector } from 'mz-math';
30 |
31 | const v1: Vector = [1, 2, 3, 4];
32 | const v2: Vector = [5, 6, 7, 8];
33 | const sum = vSub(v1, v2); // [-4, -4, -4, -4]
34 | ```
35 |
--------------------------------------------------------------------------------
/src/docs/data/pages/20-vectors/4-multiply-vector-by-scalar.md:
--------------------------------------------------------------------------------
1 | ## Multiply vector by scalar
2 |
3 | The following functions are used to multiply a vector by a scalar: **v2MulScalar** for a 2D vector, **v3MulScalar** for a 3D vector, and **vMulScalar** for the general case. Each function receives an optional **decimalPlaces** parameter.
4 |
5 | **2D Vector**
6 | ```js
7 | import { v2MulScalar } from 'mz-math';
8 |
9 | const res = v2MulScalar([1, 2], 2); // [2, 4]
10 | const res = v2MulScalar([1, 2], 0.5); // [0.5, 1]
11 | const res = v2MulScalar([1, 2], Math.PI); // [3.141592653589793, 6.283185307179586]
12 | const res = v2MulScalar([1, 2], Math.PI, 2); // [3.14, 6.28]
13 | ```
14 |
15 | **3D Vector**
16 | ```js
17 | import { v3MulScalar } from 'mz-math';
18 |
19 | const res = v3MulScalar([1, 2, 3], 2); // [2, 4, 6]
20 | const res = v3MulScalar([1, 2, 3], 0.5); // [0.5, 1, 1.5]
21 | const res = v3MulScalar([1, 2, 3], Math.PI); // [3.141592653589793, 6.283185307179586, 9.42477796076938]
22 | const res = v3MulScalar([1, 2, 3], Math.PI, 2); // [3.14, 6.28, 9.42]
23 | ```
24 |
25 | **General Case**
26 | ```js
27 | import { vMulScalar } from 'mz-math';
28 |
29 | const res = v3MulScalar([1, 2, 3, 4], 2); // [2, 4, 6, 8]
30 | ```
31 |
--------------------------------------------------------------------------------
/src/docs/data/pages/20-vectors/5-divide-vector-by-scalar.md:
--------------------------------------------------------------------------------
1 | ## Divide vector by scalar
2 |
3 | The following functions are used to divide a vector by a scalar: **v2DivideScalar** for a 2D vector, **v3DivideScalar** for a 3D vector, and **vDivideScalar** for the general case. Each function receives an optional **decimalPlaces** parameter.
4 |
5 | **2D Vector**
6 | ```js
7 | import { v2DivideScalar } from 'mz-math';
8 |
9 | const res = v2DivideScalar([1, 2], 2); // [0.5, 1]
10 | const res = v2DivideScalar([1, 2], 0.5); // [2, 4]
11 | const res = v2DivideScalar([1, 2], Math.PI); // [0.3183098861837907, 0.6366197723675814]
12 | const res = v2DivideScalar([1, 2], Math.PI, 2); // [0.32, 0.64]
13 | ```
14 |
15 | **3D Vector**
16 | ```js
17 | import { v3DivideScalar } from 'mz-math';
18 |
19 | const res = v3DivideScalar([1, 2, 3], 2); // [0.5, 1, 1.5]
20 | const res = v3DivideScalar([1, 2, 3], 0.5); // [2, 4, 6]
21 | const res = v3DivideScalar([1, 2, 3], Math.PI); // [0.3183098861837907, 0.6366197723675814, 0.954929658551372]
22 | const res = v3DivideScalar([1, 2, 3], Math.PI, 2); // [0.32, 0.64, 0.95]
23 | ```
24 |
25 | **General Case**
26 | ```js
27 | import { vDivideScalar } from 'mz-math';
28 |
29 | const res = vDivideScalar([1, 2, 3, 4], 2); // [0.5, 1, 1.5, 2]
30 | ```
--------------------------------------------------------------------------------
/src/docs/data/pages/20-vectors/6-vector-length.md:
--------------------------------------------------------------------------------
1 | ## Get Vector Length
2 |
3 | Vector length can be found using the **v2Length**, **v3Length**, and **vLength** functions. Each function receives an optional **decimalPlaces** parameter.
4 |
5 | ```js
6 | import { v2Length, v3Length, vLength } from 'mz-math';
7 |
8 | // 2D vector
9 | const len1 = v2Length([1, 2]); // 2.23606797749979
10 | const len2 = v2Length([1, 2], 2); // 2.24
11 |
12 | // 3D vector
13 | const len3 = v3Length([1, 2, 3]); // 3.7416573867739413
14 | const len4 = v3Length([1, 2, 3], 2); // 3.74
15 |
16 | // General case
17 | const len5 = vLength([1, 2, 3, 4]); // 5.477225575051661
18 | const len6 = vLength([1, 2, 3, 4], 2); // 5.48
19 | ```
20 |
21 | ## Set Vector Length
22 |
23 | It's possible to update vector length using **v2SetLength** function. The function receives an optional **decimalPlaces** parameter.
24 |
25 | ```js
26 | import { v2SetLength } from 'mz-math';
27 |
28 | const res1 = v2SetLength([1, 2], 10); // [4.4721359549995805, 8.94427190999916]
29 | const res2 = v2SetLength([1, 2], 10, 2); // [4.47, 8.94]
30 | ```
31 |
--------------------------------------------------------------------------------
/src/docs/data/pages/20-vectors/7-normalize-vector.md:
--------------------------------------------------------------------------------
1 | ## Normalized Vector (Unit Vector)
2 |
3 | It's possible to normalize vectors using the **v2Normalize**, **v3Normalize**, and **vNormalize** functions. Each function receives an optional **decimalPlaces** parameter.
4 |
5 | ```js
6 | import { v2Normalize, v3Normalize, vNormalize } from 'mz-math';
7 |
8 | // 2D vector
9 | const res1 = v2Normalize([10, 20]); // [0.4472135954999579, 0.8944271909999159]
10 | const res2 = v2Normalize([10, 20], 2); // [0.45, 0.89]
11 |
12 | // 3D vector
13 | const res3 = v3Normalize([10, 20, 30]); // [0.2672612419124244, 0.5345224838248488, 0.8017837257372731]
14 | const res4 = v3Normalize([10, 20, 30], 2); // [0.27, 0.53, 0.8]
15 |
16 | // General case
17 | const res5 = vNormalize([10, 20, 30, 40]); // [0.18257418583505536, 0.3651483716701107, 0.5477225575051661, 0.7302967433402214]
18 | const res6 = vNormalize([10, 20, 30, 40], 2); // [0.18, 0.37, 0.55, 0.73]
19 | ```
20 |
--------------------------------------------------------------------------------
/src/docs/data/pages/20-vectors/8-dot-product.md:
--------------------------------------------------------------------------------
1 | ## Vectors Dot Product
2 |
3 | It's possible to calculate vector dot product using the **v2DotProduct**, **v3DotProduct**, and **vDotProduct** functions. Each function receives an optional **decimalPlaces** parameter.
4 |
5 | ```js
6 | import { v2DotProduct, v3DotProduct, vDotProduct } from 'mz-math';
7 |
8 | // 2D vector
9 | const res1 = v2DotProduct([1, 2], [3, 4]); // 11
10 | const res2 = v2DotProduct([1.1234, 2.35678], [3.1265, 4.91355], 2); // 15.09
11 |
12 | // 3D vector
13 | const res3 = v3DotProduct([1, 2, 3], [4, 5, 6]); // 32
14 | const res4 = v3DotProduct([1.73845, 2.88465, 3.000111], [4.1163, 5.5501, 6.120777], 2); // 41.53
15 |
16 | // General case
17 | const res5 = vDotProduct([1, 2, 3, 4], [5, 6, 7, 8]); // 70
18 | const res6 = vDotProduct([1.123, 2.123, 3.123, 4.123], [5.123, 6.123, 7.123, 8.123], 1); // 74.5
19 | ```
--------------------------------------------------------------------------------
/src/docs/data/pages/20-vectors/9-cross-product.md:
--------------------------------------------------------------------------------
1 | ## Vectors Cross Product
2 |
3 | ```js
4 | import { v3CrossProduct, Vector3 } from 'mz-math';
5 |
6 | const v1: Vector3 = [1, 2, 3];
7 | const v2: Vector3 = [4, 5, 6];
8 | const res1 = v3CrossProduct(v1, v2); // [-3, 6, -3]
9 |
10 | const v3: Vector3 = [1.1143, 2.1205, 3.57294];
11 | const v4: Vector3 = [4.8294, 5.0001111, 6.48634];
12 | // round to 2 decimal places after the dot
13 | const res2 = v3CrossProduct(v3, v4, 2); // [-4.11, 10.03, -4.67]
14 | ```
15 |
--------------------------------------------------------------------------------
/src/docs/data/pages/30-matrix/1-matrix.md:
--------------------------------------------------------------------------------
1 | # Matrix
2 |
3 | There are the following types of matrices:
4 | **Matrix2**, **Matrix3**, and **Matrix** for the general case.
5 |
6 | **Matrix2**
7 |
8 | ```js
9 | import { Matrix2 } from 'mz-math';
10 |
11 | const m2: Matrix2 = [
12 | [1, 2],
13 | ];
14 |
15 | const m2: Matrix2 = [
16 | [1, 2],
17 | [3, 4],
18 | ];
19 |
20 | // or
21 |
22 | const m2: Matrix2 = [
23 | [1, 2],
24 | [3, 4],
25 | [5, 6],
26 | ];
27 |
28 | // etc...
29 | ```
30 |
31 | **Matrix3**
32 |
33 | ```js
34 | import { Matrix3 } from 'mz-math';
35 |
36 | const m3: Matrix3 = [
37 | [1, 2, 3],
38 | ];
39 |
40 | // or
41 |
42 | const m3: Matrix3 = [
43 | [1, 2, 3],
44 | [4, 5, 6],
45 | ];
46 |
47 | // or
48 |
49 | const m3: Matrix3 = [
50 | [1, 2, 3],
51 | [4, 5, 6],
52 | [7, 8, 9],
53 | ];
54 |
55 | // etc...
56 | ```
57 |
58 | **Matrix4**
59 |
60 | ```js
61 | import { Matrix4 } from 'mz-math';
62 |
63 | const m4: Matrix4 = [
64 | [1, 2, 3, 4],
65 | ];
66 |
67 | // or
68 |
69 | const m4: Matrix4 = [
70 | [1, 2, 3, 4],
71 | [5, 6, 7, 8],
72 | ];
73 |
74 | // or
75 |
76 | const m4: Matrix4 = [
77 | [1, 2, 3, 4],
78 | [5, 6, 7, 8],
79 | [9, 10, 11, 12],
80 | [13, 14, 15, 16],
81 | ];
82 |
83 | // etc...
84 | ```
85 |
86 | The generic **Matrix** type is used for all other cases:
87 |
88 | ```js
89 | import { Matrix } from 'mz-math';
90 |
91 | const m: Matrix = [
92 | [1, 2, 3, 4, 5],
93 | [1, 2, 3, 4, 5],
94 | [1, 2, 3, 4, 5],
95 | [1, 2, 3, 4, 5],
96 | [1, 2, 3, 4, 5],
97 | ];
98 | ```
--------------------------------------------------------------------------------
/src/docs/data/pages/30-matrix/10-inverse-matrix.md:
--------------------------------------------------------------------------------
1 | # Inverse Matrix
2 |
3 | To inverse matrices, you can use the **m2Inverse**, **m3Inverse**, or **mInverse** functions. Each function supports an optional **decimalPlaces** parameter. If matrix is not invertible, the functions return **null**.
4 |
5 | **2x2 matrix**
6 |
7 | ```js
8 | import { Matrix2, m2Inverse } from 'mz-math';
9 |
10 | const m2x2: Matrix2 = [
11 | [3, 5],
12 | [-7, 2],
13 | ];
14 |
15 | const inverted: Matrix2|null = m2Inverse(m2x2, 3); // round to 3 decimal places
16 | /*
17 | [
18 | [0.049, -0.122],
19 | [0.171, 0.073],
20 | ]
21 | */
22 | ```
23 |
24 | **3x3 matrix**
25 |
26 | ```js
27 | import { Matrix3, m3Inverse } from 'mz-math';
28 |
29 | const m3x3: Matrix3 = [
30 | [-1, -2, 2],
31 | [2, 1, 1],
32 | [3, 4, 5]
33 | ];
34 |
35 | const inverted: Matrix3|null = m3Inverse(m3x3, 2); // round to 2 decimal places
36 | /*
37 | [
38 | [0.04, 0.78, -0.17],
39 | [-0.30, -0.48, 0.22],
40 | [0.22, -0.09, 0.13]
41 | ]
42 | */
43 | ```
44 |
45 | **3x3 matrix or above**
46 |
47 | ```js
48 | import { Matrix, mInverse } from 'mz-math';
49 |
50 | const m4x4: Matrix = [
51 | [1, 1, 1, -1],
52 | [1, 1, -1, 1],
53 | [1, -1, 1, 1],
54 | [-1, 1, 1, 1],
55 | ];
56 |
57 | const inverted: Matrix|null = mInverse(m4x4);
58 | /*
59 | [
60 | [0.25, 0.25, 0.25, -0.25],
61 | [0.25, 0.25, -0.25, 0.25],
62 | [0.25, -0.25, 0.25, 0.25],
63 | [-0.25, 0.25, 0.25, 0.25],
64 | ]
65 | */
66 | ```
67 |
--------------------------------------------------------------------------------
/src/docs/data/pages/30-matrix/11-matrix-singularity.md:
--------------------------------------------------------------------------------
1 | # Check if matrix is singular
2 |
3 | ```js
4 | import { Matrix, isSingularMatrix } from 'mz-math';
5 |
6 | const m: Matrix = [
7 | [3, 5],
8 | [-7, 2],
9 | ];
10 |
11 | const isSingular = isSingularMatrix(m); // false
12 | ```
13 |
14 | ```js
15 | import { Matrix, isSingularMatrix } from 'mz-math';
16 |
17 | const m: Matrix = [
18 | [2, 4, 6],
19 | [2, 0, 2],
20 | [6, 8, 14],
21 | ];
22 |
23 | const isSingular = isSingularMatrix(m); // true
24 | ```
25 |
--------------------------------------------------------------------------------
/src/docs/data/pages/30-matrix/12-adjugate-matrix.md:
--------------------------------------------------------------------------------
1 | # Adjugate Matrix
2 |
3 | To adjugate matrices, you can use the **m2Adjugate**, **m3Adjugate**, or **mAdjugate** functions. Each function supports an optional **decimalPlaces** parameter. If matrix can't be adjugated, the functions return **null**.
4 |
5 | **2x2 matrix**
6 |
7 | ```js
8 | import { Matrix2, m2Adjugate } from 'mz-math';
9 |
10 | const m2x2: Matrix2 = [
11 | [3, 5],
12 | [-7, 2],
13 | ];
14 |
15 | const adj: Matrix2 | null = m2Adjugate(m2x2);
16 |
17 | /*
18 | [
19 | [2, -5],
20 | [7, 3],
21 | ]
22 | */
23 | ```
24 |
25 | **3x3 matrix**
26 |
27 | ```js
28 | import { Matrix3, m3Adjugate } from 'mz-math';
29 |
30 | const m3x3: Matrix3 = [
31 | [3, 5, 1],
32 | [-7, 2, 5],
33 | [1, 2, 3],
34 | ];
35 |
36 | const adj: Matrix3 | null = m3Adjugate(m3x3);
37 |
38 | /*
39 | [
40 | [-4, -13, 23],
41 | [26, 8, -22],
42 | [-16, -1, 41],
43 | ]
44 | */
45 | ```
46 |
47 | **4x4 matrix or above**
48 |
49 | ```js
50 | import { Matrix, mAdjugate } from 'mz-math';
51 |
52 | const m4x4: Matrix = [
53 | [1, 1, 1, -1],
54 | [1, 1, -1, 1],
55 | [1, -1, 1, 1],
56 | [-1, 1, 1, 1],
57 | ];
58 |
59 | const adj: Matrix | null = mAdjugate(m4x4);
60 |
61 | /*
62 | [
63 | [-4, -4, -4, 4],
64 | [-4, -4, 4, -4],
65 | [-4, 4, -4, -4],
66 | [4, -4, -4, -4],
67 | ]
68 | */
69 | ```
70 |
--------------------------------------------------------------------------------
/src/docs/data/pages/30-matrix/12-get-matrix-minor.md:
--------------------------------------------------------------------------------
1 | # Get Matrix Minor
2 |
3 | ```js
4 | import { Matrix, mMinor } from 'mz-math';
5 |
6 | const m: Matrix = [
7 | [4, 3, 2, 2],
8 | [0, 1, -3, 3],
9 | [0, -1, 3, 3],
10 | [0, 3, 1, 1],
11 | ];
12 |
13 | // get minor for the row = 0 and column = 0
14 | const minor: Matrix = mMinor(m, 0, 0); // -60
15 | ```
--------------------------------------------------------------------------------
/src/docs/data/pages/30-matrix/2-matrix-sum.md:
--------------------------------------------------------------------------------
1 | # Matrix Sum
2 |
3 | The following functions are used to add matrices: **m2Sum** for a 2D matrices, **m3Sum** for a 3D matrices, and **mSum** for the general case. Each function receives an optional **decimalPlaces** parameter.
4 |
5 | **2D Matrix**
6 |
7 | ```js
8 | import { m2Sum, Matrix2 } from 'mz-math';
9 |
10 | const matrix1: Matrix2 = [
11 | [1, 2],
12 | [3, 4],
13 | ];
14 |
15 | const matrix2: Matrix2 = [
16 | [5, 6],
17 | [7, 8],
18 | ];
19 |
20 | const sum = m2Sum(matrix1, matrix2);
21 | /*
22 | [
23 | [6, 8],
24 | [10, 12],
25 | ]
26 | */
27 | ```
28 |
29 | **3D Matrix**
30 | ```js
31 | import { m3Sum, Matrix3 } from 'mz-math';
32 |
33 | const matrix1: Matrix3 = [
34 | [1, 2, 10],
35 | [3, 4, 20],
36 | ];
37 |
38 | const matrix2: Matrix3 = [
39 | [5, 6, 30],
40 | [7, 8, 40],
41 | ];
42 |
43 | const sum = m3Sum(matrix1, matrix2);
44 | /*
45 | [
46 | [6, 8, 40],
47 | [10, 12, 60],
48 | ]
49 | */
50 | ```
51 |
52 | **General Case**
53 | ```js
54 | import { mSum, Matrix } from 'mz-math';
55 |
56 | const matrix1: Matrix = [
57 | [1, 2, 3, 4],
58 | [5, 6, 7, 8],
59 | ];
60 |
61 | const matrix2: Matrix = [
62 | [9, 10, 11, 12],
63 | [13, 14, 15, 16],
64 | ];
65 |
66 | const sum = mSum(matrix1, matrix2);
67 | /*
68 | [
69 | [10, 12, 14, 16],
70 | [18, 20, 22, 24],
71 | ]
72 | */
73 | ```
--------------------------------------------------------------------------------
/src/docs/data/pages/30-matrix/3-matrix-subtraction.md:
--------------------------------------------------------------------------------
1 | # Matrix Subtraction
2 |
3 | The following functions are used to subtract matrices: **m2Sub** for a 2D matrices, **m3Sub** for a 3D matrices, and **mSub** for the general case. Each function receives an optional **decimalPlaces** parameter.
4 |
5 | **2D Matrix**
6 | ```js
7 | import { m2Sub, Matrix2 } from 'mz-math';
8 |
9 | const matrix1: Matrix2 = [
10 | [1, 2],
11 | [3, 4],
12 | ];
13 |
14 | const matrix2: Matrix2 = [
15 | [5, 6],
16 | [7, 8],
17 | ];
18 |
19 | const sub = m2Sub(matrix1, matrix2);
20 | /*
21 | [
22 | [-4, -4],
23 | [-4, -4],
24 | ]
25 | */
26 | ```
27 |
28 | **3D Matrix**
29 | ```js
30 | import { m2Sub, Matrix3 } from 'mz-math';
31 |
32 | const matrix1: Matrix3 = [
33 | [1, 2, 10],
34 | [3, 4, 20],
35 | ];
36 |
37 | const matrix2: Matrix3 = [
38 | [5, 6, 30],
39 | [7, 8, 40],
40 | ];
41 |
42 | const sub = m2Sub(matrix1, matrix2);
43 | /*
44 | [
45 | [-4, -4, -20],
46 | [-4, -4, -20],
47 | ]
48 | */
49 | ```
50 |
51 | **General Case**
52 |
53 | ```js
54 | import { mSub, Matrix } from 'mz-math';
55 |
56 | const matrix1: Matrix = [
57 | [1, 2, 3, 4],
58 | [5, 6, 7, 8],
59 | ];
60 |
61 | const matrix2: Matrix = [
62 | [9, 10, 11, 12],
63 | [13, 14, 15, 16],
64 | ];
65 |
66 | const sum = mSub(matrix1, matrix2);
67 | /*
68 | [
69 | [-8, -8, -8, -8],
70 | [-8, -8, -8, -8],
71 | ]
72 | */
73 | ```
--------------------------------------------------------------------------------
/src/docs/data/pages/30-matrix/4-multiply-by-scalar.md:
--------------------------------------------------------------------------------
1 | # Multiply matrix by scalar
2 |
3 | You can multiply a matrix by a scalar using the **m2MulScalar**, **m3MulScalar**, or **mMulScalar** functions. Each function receives an optional **decimalPlaces** parameter.
4 |
5 | **2D Matrix**
6 |
7 | ```js
8 | import { m2MulScalar, Matrix2 } from 'mz-math';
9 |
10 | const m2: Matrix2 = [
11 | [1, 2],
12 | [3, 4],
13 | ];
14 |
15 | const res = m2MulScalar(m2, 5);
16 | /*
17 | [
18 | [5, 10],
19 | [15, 20],
20 | ]
21 | */
22 | ```
23 |
24 | ```js
25 | import { m2MulScalar, Matrix2 } from 'mz-math';
26 |
27 | const m2: Matrix2 = [
28 | [1.12345, 12.66746776],
29 | [15.74432, -12.345345],
30 | ];
31 |
32 | const res = m2MulScalar(m2, 10, 2); // 2 decimal places
33 | /*
34 | [
35 | [11.23, 126.67],
36 | [157.44, -123.45],
37 | ]
38 | */
39 | ```
40 |
41 | **3D Matrix**
42 |
43 | ```js
44 | import { m3MulScalar, Matrix3 } from 'mz-math';
45 |
46 | const m3: Matrix3 = [
47 | [1, 2, 3],
48 | [4, 5, 6],
49 | ];
50 |
51 | const res = m3MulScalar(m3, 2);
52 | /*
53 | [
54 | [2, 4, 6],
55 | [8, 10, 12],
56 | ]
57 | */
58 | ```
59 |
60 | ```js
61 | import { m3MulScalar, Matrix3 } from 'mz-math';
62 |
63 | const m3: Matrix3 = [
64 | [1, 2, 3],
65 | [4, 5, 6],
66 | ];
67 |
68 | const res = m3MulScalar(m3, 1.5123123, 1); // 1 decimal place
69 | /*
70 | [
71 | [1.5, 3, 4.5],
72 | [6, 7.6, 9.1],
73 | ]
74 | */
75 | ```
76 |
--------------------------------------------------------------------------------
/src/docs/data/pages/30-matrix/5-divide-by-scalar.md:
--------------------------------------------------------------------------------
1 | # Divide matrix by scalar
2 |
3 | You can multiply a matrix by a scalar using the **m2DivideScalar**, **m3DivideScalar**, or **mDivideScalar** functions. Each function receives an optional **decimalPlaces** parameter.
4 |
5 | **2D Matrix**
6 |
7 | ```js
8 | import { m2DivideScalar, Matrix2 } from 'mz-math';
9 |
10 | const m2: Matrix2 = [
11 | [1, 2],
12 | [3, 4],
13 | ];
14 |
15 | const res = m2DivideScalar(m2, 5);
16 | /*
17 | [
18 | [0.2, 0.4],
19 | [0.6, 0.8],
20 | ]
21 | */
22 | ```
23 |
24 | ```js
25 | import { m2DivideScalar, Matrix2 } from 'mz-math';
26 |
27 | const m2: Matrix2 = [
28 | [1.12345, 12.66746776],
29 | [15.74432, -12.345345],
30 | ];
31 |
32 | const res = m2DivideScalar(m2, 10, 2); // 2 decimal places
33 | /*
34 | [
35 | [0.01, 0.13],
36 | [0.16, -0.12],,
37 | ]
38 | */
39 | ```
40 |
41 | **3D Matrix**
42 |
43 | ```js
44 | import { m3DivideScalar, Matrix3 } from 'mz-math';
45 |
46 | const m3: Matrix3 = [
47 | [1, 2, 3],
48 | [4, 5, 6],
49 | ];
50 |
51 | const res = m3DivideScalar(m3, 2);
52 | /*
53 | [
54 | [0.5, 1, 1.5],
55 | [2, 2.5, 3],
56 | ]
57 | */
58 | ```
59 |
60 | ```js
61 | import { m3DivideScalar, Matrix3 } from 'mz-math';
62 |
63 | const m3: Matrix3 = [
64 | [1, 2, 3],
65 | [4, 5, 6],
66 | ];
67 |
68 | const res = m3DivideScalar(m3, 1.5123123, 1); // 1 decimal place
69 | /*
70 | [
71 | [0.7, 1.3, 2],
72 | [2.6, 3.3, 4],
73 | ]
74 | */
75 | ```
76 |
77 | **General Case**
78 |
79 | ```js
80 | import { mDivideScalar, Matrix } from 'mz-math';
81 |
82 | const matrix: Matrix = [
83 | [1, 2, 3, 4],
84 | [5, 6, 7, 8],
85 | ];
86 |
87 | const res = mDivideScalar(matrix, 5);
88 | /*
89 | [
90 | [0.2, 0.4, 0.6, 0.8],
91 | [1, 1.2, 1.4, 1.6],
92 | ]
93 | */
94 | ```
95 |
--------------------------------------------------------------------------------
/src/docs/data/pages/30-matrix/6-matrix-transposition.md:
--------------------------------------------------------------------------------
1 | # Matrix Transposition
2 |
3 | You can transpose a matrix using the **m2Transpose**, **m3Transpose**, or **mTranspose** functions.
4 |
5 | **2D Matrix**
6 |
7 | ```js
8 | import { m2Transpose, Matrix2 } from 'mz-math';
9 |
10 | const m2: Matrix2 = [
11 | [-1, 5],
12 | [Math.PI, 3],
13 | ];
14 |
15 | const res = m2Transpose(m2);
16 | /*
17 | [
18 | [-1, Math.PI],
19 | [5, 3],
20 | ]
21 | */
22 | ```
23 |
24 | **3D Matrix**
25 |
26 | ```js
27 | import { m3Transpose, Matrix3 } from 'mz-math';
28 |
29 | const m3: Matrix3 = [
30 | [1, 3, 7],
31 | [-2, 0, 5],
32 | ];
33 |
34 | const res = m3Transpose(m3);
35 | /*
36 | [
37 | [1, -2],
38 | [3, 0],
39 | [7, 5],
40 | ]
41 | */
42 | ```
43 |
44 | **General Case**
45 |
46 | ```js
47 | import { mTranspose, Matrix } from 'mz-math';
48 |
49 | const matrix: Matrix = [
50 | [1, 2, 3, 4],
51 | [5, 6, 7, 8],
52 | ];
53 |
54 | const res = mTranspose(matrix);
55 | /*
56 | [
57 | [1, 5],
58 | [2, 6],
59 | [3, 7],
60 | [4, 8],
61 | ]
62 | */
63 | ```
64 |
--------------------------------------------------------------------------------
/src/docs/data/pages/30-matrix/7-matrix-multiplication.md:
--------------------------------------------------------------------------------
1 | # Matrix Multiplication
2 |
3 | You can multiply matrices using the **mMul** function. The function receives an optional **decimalPlaces** parameter.
4 |
5 | ```js
6 | import { mMul, Matrix3, Matrix2 } from 'mz-math';
7 |
8 | const matrix1: Matrix3 = [
9 | [0, 3, 5],
10 | [5, 5, 2],
11 | ];
12 |
13 | const matrix2: Matrix2 = [
14 | [3, 4],
15 | [3, -2],
16 | [4, -2],
17 | ];
18 |
19 | const res = mMul(matrix1, matrix2);
20 |
21 | /*
22 | [
23 | [29, -16],
24 | [38, 6],
25 | ]
26 | */
27 | ```
28 |
29 | ```js
30 | import { mMul, Matrix2 } from 'mz-math';
31 |
32 | const matrix1: Matrix2 = [
33 | [2.092345, -2.2345234],
34 | [5.56745, 3.235479],
35 | ];
36 |
37 | const matrix2: Matrix2 = [
38 | [-1.46874567, 4.23453245],
39 | [7.234505, -6.93245],
40 | ];
41 |
42 | const res = mMul(matrix1, matrix2, 2); // round to 2 decimal places
43 |
44 | /*
45 | [
46 | [-19.24, 24.35],
47 | [15.23, 1.15],
48 | ]
49 | */
50 | ```
51 |
--------------------------------------------------------------------------------
/src/docs/data/pages/30-matrix/8-multiply-matrix-by-vector.md:
--------------------------------------------------------------------------------
1 | # Multiply matrix by vector
2 |
3 | You can multiply matrix by vector using the **mMulVector** function. The function receives an optional **decimalPlaces** parameter.
4 |
5 | ```js
6 | import { mMulVector, Matrix3 } from 'mz-math';
7 |
8 | const matrix: Matrix3 = [
9 | [0, 3, 5],
10 | [5, 5, 2],
11 | ];
12 |
13 | const vector: Vector3 = [3, 4, 3];
14 |
15 | const res = mMulVector(matrix, vector); // [27, 41]
16 | ```
--------------------------------------------------------------------------------
/src/docs/data/pages/30-matrix/9-matrix-determinant.md:
--------------------------------------------------------------------------------
1 | # Matrix Determinant
2 |
3 | The determinant can be calculated for any square matrix using the **m2Determinant** function for a 2x2 matrix, using the **m3Determinant** function for a 3x3 matrix, or using **mDeterminant** for the general case.
4 |
5 | Calculating the determinant for a 2x2 matrix:
6 |
7 | ```js
8 | import { Matrix2, m2Determinant } from 'mz-math';
9 |
10 | const m2x2: Matrix2 = [
11 | [5, 3],
12 | [-1, 4],
13 | ];
14 |
15 | const d = m2Determinant(m2x2); // 23
16 | ```
17 |
18 | Calculating the determinant for a 3x3 matrix:
19 |
20 | ```js
21 | import { Matrix3, m3Determinant } from 'mz-math';
22 |
23 | const m3x3: Matrix3 = [
24 | [4, -1, 1],
25 | [4, 5, 3],
26 | [-2, 0, 0],
27 | ];
28 |
29 | const d = m3Determinant(m3x3); // 16
30 | ```
31 |
32 | Calculating the determinant for a 4x4 matrix or above:
33 |
34 | ```js
35 | import { Matrix, mDeterminant } from 'mz-math';
36 |
37 | const m4x4: Matrix = [
38 | [4, 3, 2, 2],
39 | [0, 1, -3, 3],
40 | [0, -1, 3, 3],
41 | [0, 3, 1, 1]
42 | ];
43 |
44 | const d = mDeterminant(m4x4); // -240
45 | ```
--------------------------------------------------------------------------------
/src/docs/data/pages/40-matrix-manipulation/1-matrix-initialization.md:
--------------------------------------------------------------------------------
1 | ## Matrix Initialization Helpers
2 |
3 | ### m2x2, m3x3, and mNxM
4 |
5 | There are helpers for creating **m2x2**, **m3x3**, and **mNxM** matrices with a default value. If no default value is specified, it will be zero.
6 |
7 | ```js
8 | import { m2x2, m3x3, m4x4, mNxM } from 'mz-math';
9 |
10 | const mat2x2 = m2x2();
11 | /*
12 | [
13 | [0, 0],
14 | [0, 0],
15 | ]
16 | */
17 |
18 | const mat2x2_10 = m2x2(10);
19 | /*
20 | [
21 | [10, 10],
22 | [10, 10],
23 | ]
24 | */
25 |
26 | const mat3x3 = m3x3();
27 | /*
28 | [
29 | [0, 0, 0],
30 | [0, 0, 0],
31 | [0, 0, 0],
32 | ]
33 | */
34 |
35 | const mat3x3_20 = m3x3(20);
36 | /*
37 | [
38 | [20, 20, 20],
39 | [20, 20, 20],
40 | [20, 20, 20],
41 | ]
42 | */
43 |
44 | const mat4x4_5 = m5x5(5);
45 | /*
46 | [
47 | [5, 5, 5, 5],
48 | [5, 5, 5, 5],
49 | [5, 5, 5, 5],
50 | [5, 5, 5, 5],
51 | ]
52 | */
53 |
54 | const matNxM = mNxM(1, 5);
55 | /*
56 | [
57 | [0, 0, 0, 0, 0],
58 | ]
59 | */
60 |
61 | const matNxM = mNxM(2, 3, 1);
62 | /*
63 | [
64 | [1, 1, 1],
65 | [1, 1, 1],
66 | ]
67 | */
68 |
69 | ```
70 |
71 | ### Identity Matrix
72 |
73 | There are helpers for creating identity matrices: **identity2**, **identity3**, and **identityN**.
74 |
75 | ```js
76 | import { identity2, identity3, identity4, identityN } from 'mz-math';
77 |
78 | const idt2 = identity2();
79 | /*
80 | [
81 | [1, 0],
82 | [0, 1],
83 | ]
84 | */
85 |
86 | const idt3 = identity3();
87 | /*
88 | [
89 | [1, 0, 0],
90 | [0, 1, 0],
91 | [0, 0, 1],
92 | ]
93 | */
94 |
95 | const idt4 = identity4();
96 | /*
97 | [
98 | [1, 0, 0, 0],
99 | [0, 1, 0, 0],
100 | [0, 0, 1, 0],
101 | [0, 0, 0, 1],
102 | ]
103 | */
104 |
105 | const idt5 = identityN(5);
106 | /*
107 | [
108 | [1, 0, 0, 0, 0],
109 | [0, 1, 0, 0, 0],
110 | [0, 0, 1, 0, 0],
111 | [0, 0, 0, 1, 0],
112 | [0, 0, 0, 0, 1],
113 | ]
114 | */
115 |
116 | ```
117 |
--------------------------------------------------------------------------------
/src/docs/data/pages/40-matrix-manipulation/2-matrix-equality.md:
--------------------------------------------------------------------------------
1 | # Check if two matrices are equal
2 |
3 | It's possible to perform a deep comparison of two matrices using the **mEqual** function:
4 |
5 | ```js
6 | import { mEqual } from 'mz-math';
7 |
8 | const res1 = mEqual(
9 | [
10 | [0, 0],
11 | [0, 0],
12 | ],
13 | [
14 | [0, 0],
15 | [0, 0],
16 | ]); // true
17 |
18 | const res2 = mEqual(
19 | [
20 | [1, 0],
21 | [0, 0],
22 | ],
23 | [
24 | [0, 0],
25 | [0, 1],
26 | ]); // false
27 | ```
--------------------------------------------------------------------------------
/src/docs/data/pages/40-matrix-manipulation/3-matrix-deep-copy.md:
--------------------------------------------------------------------------------
1 | # Matrix Deep Copy
2 |
3 | There are 3 function for matrices deep copy: **m2DeepCopy** for 2D matrices, **m3DeepCopy** for 3D matrices, and **mDeepCopy** for the general case:
4 |
5 | ```js
6 | import { Matrix2, m2DeepCopy } from 'mz-math';
7 |
8 | const m2: Matrix2 = [
9 | [3, 5],
10 | [-7, 2],
11 | ];
12 | const copyM2 = m2DeepCopy(m2);
13 | ```
14 |
15 | ```js
16 | import { Matrix3, m3DeepCopy } from 'mz-math';
17 |
18 | const m2: Matrix3 = [
19 | [3, 5, 1],
20 | [-7, 2, 6],
21 | ];
22 | const copyM3 = m2DeepCopy(m3);
23 | ```
24 |
25 | ```js
26 | import { Matrix, mDeepCopy } from 'mz-math';
27 |
28 | const m: Matrix = [
29 | [1, 0, 1, 2, 4],
30 | [1, 7, 8, 6, 12],
31 | ];
32 | const copy = mDeepCopy(m);
33 | ```
--------------------------------------------------------------------------------
/src/docs/data/pages/40-matrix-manipulation/4-append-or-prepend-row.md:
--------------------------------------------------------------------------------
1 | # Append or prepend a row to a matrix
2 |
3 | ```js
4 | import { Matrix2, Vector2, m2AppendRow, m2PrependRow } from 'mz-math';
5 |
6 | const m2: Matrix2 = [
7 | [3, 5],
8 | [-7, 2],
9 | ];
10 | const v2: Vector2 = [3, 4];
11 | const res1 = m2AppendRow(m2, v2);
12 | /*
13 | [
14 | [3, 5],
15 | [-7, 2],
16 | [3, 4]
17 | ]
18 | */
19 |
20 | const res2 = m2PrependRow(m2, v2);
21 | /*
22 | [
23 | [3, 4],
24 | [3, 5],
25 | [-7, 2],
26 | ]
27 | */
28 | ```
29 |
30 | ```js
31 | import { Matrix3, Vector3, m3AppendRow, m3PrependRow } from 'mz-math';
32 |
33 | const m3: Matrix3 = [
34 | [1, 2, 3],
35 | [4, 5, 6],
36 | ];
37 | const v3: Vector3 = [7, 8, 9];
38 | const res1 = m3AppendRow(m3, v3);
39 | /*
40 | [
41 | [1, 2, 3],
42 | [4, 5, 6],
43 | [7, 8, 9],
44 | ]
45 | */
46 | const res2 = m3PrependRow(m3, v3);
47 | /*
48 | [
49 | [7, 8, 9],
50 | [1, 2, 3],
51 | [4, 5, 6],
52 | ]
53 | */
54 | ```
55 |
56 | ```js
57 | import { Matrix, Vector, mAppendRow, mPrependRow } from 'mz-math';
58 |
59 | const m: Matrix = [
60 | [1, 2, 3, 4],
61 | [5, 6, 7, 8],
62 | ];
63 | const v: Vector = [9, 10, 11, 12];
64 | const res1 = mAppendRow(m, v);
65 | /*
66 | [
67 | [1, 2, 3, 4],
68 | [5, 6, 7, 8],
69 | [9, 10, 11, 12],
70 | ]
71 | */
72 | const res2 = mPrependRow(m, v);
73 | /*
74 | [
75 | [9, 10, 11, 12],
76 | [1, 2, 3, 4],
77 | [5, 6, 7, 8],
78 | ]
79 | */
80 | ```
--------------------------------------------------------------------------------
/src/docs/data/pages/40-matrix-manipulation/5-append-or-prepend-column.md:
--------------------------------------------------------------------------------
1 | # Append or prepend a column to a matrix
2 |
3 | ```js
4 | import { Matrix, Vector, mAppendCol, mPrependCol } from 'mz-math';
5 |
6 | const m: Matrix = [
7 | [1, 2, 3, 4],
8 | [5, 6, 7, 8],
9 | ];
10 | const v: Vector = [9, 10];
11 | const res1 = mAppendCol(m, v);
12 | /*
13 | [
14 | [1, 2, 3, 4, 9],
15 | [5, 6, 7, 8, 10],
16 | ]
17 | */
18 | const res2 = mPrependCol(m, v);
19 | /*
20 | [
21 | [9, 1, 2, 3, 4],
22 | [10, 5, 6, 7, 8],
23 | ]
24 | */
25 | ```
--------------------------------------------------------------------------------
/src/docs/data/pages/40-matrix-manipulation/6-remove-row-or-column.md:
--------------------------------------------------------------------------------
1 | # Remove row or column from matrix
2 |
3 | **Delete last row**
4 |
5 | ```js
6 | import { mDelLastRow } from 'mz-math';
7 |
8 | const res = mDelLastRow(
9 | [
10 | [3, 5],
11 | [-7, 2],
12 | ]
13 | );
14 | /*
15 | [
16 | [3, 5],
17 | ]
18 | */
19 | ```
20 |
21 | **Delete first row**
22 |
23 | ```js
24 | import { mDelFirstRow } from 'mz-math';
25 |
26 | const res = mDelFirstRow(
27 | [
28 | [3, 5],
29 | [-7, 2],
30 | ]
31 | );
32 | /*
33 | [
34 | [-7, 2],
35 | ]
36 | */
37 | ```
38 |
39 | **Delete last column**
40 |
41 | ```js
42 | import { mDelLastColumn } from 'mz-math';
43 |
44 | const res = mDelLastColumn(
45 | [
46 | [3, 5],
47 | [-7, 2],
48 | ]
49 | );
50 | /*
51 | [
52 | [3],
53 | [-7],
54 | ]
55 | */
56 | ```
57 |
58 | **Delete first column**
59 |
60 | ```js
61 | import { mDelFirstColumn } from 'mz-math';
62 |
63 | const res = mDelFirstColumn(
64 | [
65 | [3, 5],
66 | [-7, 2],
67 | ]
68 | );
69 | /*
70 | [
71 | [5],
72 | [2],
73 | ]
74 | */
75 | ```
76 |
--------------------------------------------------------------------------------
/src/docs/data/pages/40-matrix-manipulation/7-get-column.md:
--------------------------------------------------------------------------------
1 | # Get column from matrix
2 |
3 | ```js
4 | import { Matrix, mGetFirstColumn, mGetLastColumn, mGetColumn } from 'mz-math';
5 |
6 | const m: Matrix = [
7 | [1, 0, 1, 1],
8 | [1, 0, 1, 1],
9 | [0, 0, 1, 1],
10 | [0, 0, 1, -1],
11 | ];
12 |
13 | const firstColumn = mGetFirstColumn(m); // [1, 1, 0, 0]
14 | const lastColumn = mGetLastColumn(m); // [1, 1, 1, -1]
15 | const col2 = mGetColumn(m, 2); // [1, 1, 1, 1] - column at index 2
16 | ```
--------------------------------------------------------------------------------
/src/docs/data/pages/40-matrix-manipulation/8-reset-matrix.md:
--------------------------------------------------------------------------------
1 | # Reset matrix with a default value
2 |
3 | It is possible to reset all matrix values with some default value. If no default value is specified, it will be **zero**.
4 |
5 | **2D Matrix**
6 |
7 | ```js
8 | import { Matrix2, m2Reset } from 'mz-math';
9 |
10 | const m2: Matrix2 = [
11 | [1, 2],
12 | [3, 4],
13 | ];
14 |
15 | const res = m2Reset(m2);
16 | /*
17 | [
18 | [0, 0],
19 | [0, 0],
20 | ]
21 | */
22 | ```
23 |
24 | ```js
25 | import { Matrix2, m2Reset } from 'mz-math';
26 |
27 | const m2: Matrix2 = [
28 | [1, 2],
29 | [3, 4],
30 | ];
31 |
32 | const res = m2Reset(m2, 10);
33 | /*
34 | [
35 | [10, 10],
36 | [10, 10],
37 | ]
38 | */
39 | ```
40 |
41 | **3D Matrix**
42 |
43 | ```js
44 | import { Matrix3, m3Reset } from 'mz-math';
45 |
46 | const m3: Matrix3 = [
47 | [1, 2, 3],
48 | [4, 5, 6],
49 | ];
50 |
51 | const res = m3Reset(m3);
52 | /*
53 | [
54 | [0, 0, 0],
55 | [0, 0, 0],
56 | ]
57 | */
58 | ```
59 |
60 | ```js
61 | import { Matrix3, m3Reset } from 'mz-math';
62 |
63 | const m3: Matrix3 = [
64 | [1, 2, 3],
65 | [4, 5, 6],
66 | ];
67 |
68 | const res = m3Reset(m3, 1.5);
69 | /*
70 | [
71 | [1.5, 1.5, 1.5],
72 | [1.5, 1.5, 1.5],
73 | ]
74 | */
75 | ```
76 |
77 | **General Case**
78 |
79 | ```js
80 | import { Matrix, m3Reset } from 'mz-math';
81 |
82 | const m: Matrix = [
83 | [1, 2, 3, 4, 5],
84 | [6, 7, 8, 9, 10],
85 | ];
86 |
87 | const res = m3Reset(m);
88 | /*
89 | [
90 | [0, 0, 0, 0, 0],
91 | [0, 0, 0, 0, 0],
92 | ]
93 | */
94 | ```
95 |
96 | ```js
97 | import { Matrix, m3Reset } from 'mz-math';
98 |
99 | const m: Matrix = [
100 | [1, 2, 3, 4, 5],
101 | [6, 7, 8, 9, 10],
102 | ];
103 |
104 | const res = m3Reset(m, 50);
105 | /*
106 | [
107 | [50, 50, 50, 50, 50],
108 | [50, 50, 50, 50, 50],
109 | ]
110 | */
111 | ```
112 |
--------------------------------------------------------------------------------
/src/docs/data/pages/45-transformation-matrices/1-translation-matrix.md:
--------------------------------------------------------------------------------
1 | # Translation Matrix
2 |
3 | It's possible to get a translation matrix using the functions below. Each function supports an optional **decimalPlaces** parameter.
4 |
5 | **Translation in non-homogeneous coordinates**
6 |
7 | ```js
8 | import { m2Translation, m3Translation, Matrix2, Matrix3 } from 'mz-math';
9 |
10 | // translation matrix for the position [10, 20]
11 | const mat1: Matrix2 = m2Translation([10, 20]);
12 |
13 | /*
14 | [
15 | [1, 0],
16 | [0, 1],
17 | [10, 20],
18 | ];
19 | */
20 |
21 | // translation matrix for the position [10, 20, 30]
22 | const mat2: Matrix3 = m3Translation([10, 20, 30]);
23 |
24 | /*
25 | [
26 | [1, 0, 0],
27 | [0, 1, 0],
28 | [0, 0, 1],
29 | [10, 20, 30],
30 | ];
31 | */
32 | ```
33 |
34 | **Translation in homogeneous coordinates**
35 |
36 | ```js
37 | import { m2TranslationH, m3TranslationH, Matrix3, Matrix4 } from 'mz-math';
38 |
39 | // translation matrix for the position [10, 20] in homogeneous coordinates.
40 | const mat1: Matrix3 = m2TranslationH([10, 20, 1]);
41 |
42 | /*
43 | [
44 | [1, 0, 10],
45 | [0, 1, 20],
46 | [0, 0, 1],
47 | ];
48 | */
49 |
50 | // translation matrix for the position [10, 20, 30] in homogeneous coordinates.
51 | const mat2: Matrix4 = m3TranslationH([10, 20, 30, 1]);
52 |
53 | /*
54 | [
55 | [1, 0, 0, 10],
56 | [0, 1, 0, 20],
57 | [0, 0, 1, 30],
58 | [0, 0, 0, 1],
59 | ];
60 | */
61 | ```
--------------------------------------------------------------------------------
/src/docs/data/pages/45-transformation-matrices/3-rotate-around-point.md:
--------------------------------------------------------------------------------
1 | # Rotate Around Point
2 |
3 | It's possible to rotate a point [x, y] (in homogeneous coordinates) around the given origin as follows:
4 |
5 | ```js
6 | import { Vector3, m2RotateAroundPointH, m2RotationAroundPointH } from 'mz-math';
7 |
8 | const angle = Math.PI/4; // radians
9 | const transformOrigin = [100, 100, 1]; // in homogeneous coordinates
10 | const point: Vector3 = [150, 150, 1]; // [x, y, 1]
11 | const isClockwise = true; // optional
12 | const decimalPlaces = 2; // optional
13 |
14 | // get the new position after rotation
15 | const pos: Vector3 = m2RotateAroundPointH(
16 | angle,
17 | transformOrigin,
18 | point,
19 | isClockwise,
20 | decimalPlaces
21 | );
22 |
23 | // it's also possible to get the appropriate rotation matrix
24 | const mat3: Matrix3 = m2RotationAroundPointH(
25 | angle,
26 | transformOrigin,
27 | isClockwise,
28 | decimalPlaces
29 | );
30 | ```
31 |
32 | [Circle Movement Example](https://github.com/mzusin/mz-math/blob/main/examples/circular-movement/circle-movement-1.html)
33 |
--------------------------------------------------------------------------------
/src/docs/data/pages/45-transformation-matrices/5-scale-around-point.md:
--------------------------------------------------------------------------------
1 | # Scale around an arbitrary pivot point P
2 |
3 | It's possible to scale a point [x, y] (in homogeneous coordinates) around the given pivot point as follows:
4 |
5 | ```js
6 | import { Vector3, m2ScaleAtPointH, m2ScaleAtPointHMatrix } from 'mz-math';
7 |
8 | const scaleVector: Vector3 = [2, 4, 1]; // in homogeneous coordinates
9 | const transformOrigin = [100, 100, 1]; // in homogeneous coordinates
10 | const point: Vector3 = [150, 150, 1]; // [x, y, 1]
11 | const decimalPlaces = 2; // optional
12 |
13 | // get the new vector after the scale
14 | const res: Vector3 = m2ScaleAtPointH(
15 | scaleVector,
16 | transformOrigin,
17 | point,
18 | decimalPlaces
19 | );
20 |
21 | // it's also possible to get the appropriate scale matrix
22 | const mat3: Matrix3 = m2ScaleAtPointHMatrix(
23 | scaleVector,
24 | transformOrigin,
25 | decimalPlaces
26 | );
27 | ```
--------------------------------------------------------------------------------
/src/docs/data/pages/45-transformation-matrices/7-shearing-matrix.md:
--------------------------------------------------------------------------------
1 | # Shearing Matrix
2 |
3 | **2D shearing matrix**
4 |
5 | ```js
6 | import { m2ShearingX, m2ShearingY, Matrix2 } from 'mz-math';
7 |
8 | // shearing in x-axis, with y-axis fixed with (1,0) moving to (1, factor)
9 | const factor = 5;
10 | const mat1: Matrix2 = m2ShearingX(factor);
11 | /*
12 | [
13 | [1, 0],
14 | [5, 1],
15 | ];
16 | */
17 |
18 | // shearing in y-axis, with x-axis fixed with (0,1) moving to (factor, 1)
19 | const factor = 5;
20 | const mat2: Matrix2 = m2ShearingY(factor);
21 | /*
22 | [
23 | [1, 5],
24 | [0, 1],
25 | ];
26 | */
27 | ```
--------------------------------------------------------------------------------
/src/docs/data/pages/45-transformation-matrices/8-matrix-to-CSS-transform.md:
--------------------------------------------------------------------------------
1 | # Matrix to CSS transform
2 |
3 | The functions below help to convert the matrix to the following CSS functions: [matrix()](https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function/matrix) and [matrix3d()](https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function/matrix3d).
4 |
5 | ```js
6 | import { Matrix3, m2hToCSS } from 'mz-math';
7 |
8 | // 2d matrix in homogeneous coordinates
9 | const mat: Matrix3 = [
10 | [1, 2, 0],
11 | [3, 4, 0],
12 | [0, 0, 1],
13 | ];
14 | const str1 = m2hToCSS(mat); // matrix(1, 3, 2, 4, 0, 4)
15 | ```
16 |
17 | It can be used as:
18 |
19 | ```css
20 | .box{
21 | transform: matrix(1, 3, 2, 4, 0, 4);
22 | }
23 | ```
24 |
25 | [matrix3d()](https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function/matrix3d) representation:
26 |
27 | ```js
28 | import { Matrix3, m2hToCSS3d } from 'mz-math';
29 |
30 | // 2d matrix in homogeneous coordinates
31 | const mat: Matrix3 = [
32 | [1, 2, 0],
33 | [3, 4, 0],
34 | [0, 0, 1],
35 | ];
36 | const str1 = m2hToCSS3d(mat); // matrix3d(1, 3, 0, 0, 2, 4, 0, 0, 0, 0, 1, 0, 0, 4, 0, 1)
37 | ```
38 |
39 | Non-homogeneous coordinates version:
40 |
41 | ```js
42 | import { Matrix2, m2ToCSS } from 'mz-math';
43 |
44 | // 2d matrix in homogeneous coordinates
45 | const mat: Matrix2 = [
46 | [1, 2],
47 | [3, 4],
48 | ];
49 | const str1 = m2ToCSS(mat); // matrix(1, 3, 2, 4, 0, 0)
50 | ```
51 |
52 | 3D matrix in homogeneous coordinates:
53 |
54 | ```js
55 | import { Matrix4, m3hToCSS3d } from 'mz-math';
56 |
57 | // 2d matrix in homogeneous coordinates
58 | const mat: Matrix4 = [
59 | [1, 0, 0, 10],
60 | [0, 1, 0, 20],
61 | [0, 0, 1, 30],
62 | [0, 0, 0, 1],
63 | ];
64 | const str1 = m3hToCSS3d(mat);
65 | /*
66 | matrix3d(
67 | 1, 0, 0, 10,
68 | 0, 1, 0, 20,
69 | 0, 0, 1, 30,
70 | 0, 0, 0, 1
71 | )
72 | */
73 | ```
74 |
75 | [Matrix to CSS transform example (rotation)](https://github.com/mzusin/mz-math/blob/main/examples/matrix-to-css-rotation.html)
--------------------------------------------------------------------------------
/src/docs/data/pages/50-angles/1-vector-angle.md:
--------------------------------------------------------------------------------
1 | ## Get vector angle
2 |
3 | The **getV2Angle** function returns the angle **in radians** between the positive x-axis and the ray from (0, 0) to the vector (x, y). It supports an optional **decimalPlaces** parameter. Each function returns a result in the range [0, Math.PI].
4 |
5 | ```js
6 | import { getV2Angle } from 'mz-math';
7 |
8 | const angle1 = getV2Angle([10, 20]); // 1.1071487177940904 radians
9 | const angle2 = getV2Angle([10, 20], 2); // 1.11 radians
10 | ```
11 |
12 | ## Set vector angle
13 |
14 | If a 2D vector is given, change it to have the new angle (in radians). This function supports an optional **decimalPlaces** parameter.
15 |
16 | ```js
17 | import { setV2Angle } from 'mz-math';
18 |
19 | const updatedVector1 = setV2Angle([10, 20], 1.22); // [7.684152489413291, 20.99889998355732]
20 | const updatedVector2 = setV2Angle([10, 20], 1.22, 2); // [7.68, 21]
21 | ```
22 |
23 | ## getV2AngleInEllipse()
24 |
25 | ```js
26 | import { getV2AngleInEllipse } from 'mz-math';
27 |
28 | const v2: Vector2 = [10, 20];
29 | const radii: Vector2 = [100, 200];
30 | const decimalPlaces = 2; // optional
31 |
32 | const angle = getV2AngleInEllipse(v2, radii, decimalPlaces); // 0.79 radians
33 | ```
34 |
35 |
--------------------------------------------------------------------------------
/src/docs/data/pages/50-angles/2-angle-between-vectors.md:
--------------------------------------------------------------------------------
1 | # Get angle between two vectors
2 |
3 | The following functions can be used to find the angle between two vectors. Each function returns a result in the range [0, Math.PI].
4 |
5 | **2D vectors:**
6 |
7 | ```js
8 | import { getV2AngleBetween, Vector2 } from 'mz-math';
9 |
10 | const vector1: Vector2 = [10, 20];
11 | const vector2: Vector2 = [100, 150];
12 | const decimalPlaces = 2; // optional
13 | const angle = getV2AngleBetween(vector1, vector2, decimalPlaces);
14 | ```
15 |
16 | **3D vectors:**
17 |
18 | ```js
19 | import { getV3AngleBetween, Vector3 } from 'mz-math';
20 |
21 | const vector1: Vector3 = [10, 20, 1];
22 | const vector2: Vector3 = [100, 150, 1];
23 | const decimalPlaces = 2; // optional
24 | const angle = getV3AngleBetween(vector1, vector2, decimalPlaces);
25 | ```
26 |
27 | **General case:**
28 |
29 | ```js
30 | import { getVNAngleBetween, Vector } from 'mz-math';
31 |
32 | const vector1: Vector = [10, 20, 1];
33 | const vector2: Vector = [100, 150, 1];
34 | const decimalPlaces = 2; // optional
35 | const angle = getVNAngleBetween(vector1, vector2, decimalPlaces);
36 | ```
37 |
--------------------------------------------------------------------------------
/src/docs/data/pages/50-angles/3-degrees-and-radians.md:
--------------------------------------------------------------------------------
1 | ## Degrees to radians
2 |
3 | ```js
4 | import { degreesToRadians } from 'mz-math';
5 |
6 | const res1 = degreesToRadians(90); // 1.5707963267948966
7 | const res2 = degreesToRadians(90, 2); // 1.57
8 | ```
9 |
10 | ## Radians to degrees
11 |
12 | ```js
13 | import { radiansToDegrees } from 'mz-math';
14 |
15 | const res = radiansToDegrees(1.5708); // 90.00021045914971
16 | const res = radiansToDegrees(1.5708, 0); // 90
17 | const res = radiansToDegrees(3.14159, 3); // 180
18 | const res = radiansToDegrees(4.71239, 3); // 270
19 | ```
20 |
--------------------------------------------------------------------------------
/src/docs/data/pages/50-angles/4-angles-distance.md:
--------------------------------------------------------------------------------
1 | ## Get Angles Distance
2 |
3 | The getAnglesDistance() function calculates the distance between two angles, considering a start angle as the reference. It returns the shortest distance between the angles, taking into account both clockwise and counterclockwise directions.
4 |
5 | ```js
6 | import { getAnglesDistance } from 'mz-math';
7 |
8 | const distance1 = getAnglesDistance(0, 90); // 90 degrees
9 | const distance2 = getAnglesDistance(270, 90); // 180 degrees
10 | ```
11 |
12 | The function signature is:
13 | ```ts
14 | const getAnglesDistance: (angle1Deg: number, angle2Deg: number, startAngleDeg?: number, decimalPlaces?: number) => number;
15 | ```
16 |
17 | - **angle1Deg** (number): The first angle in degrees.
18 | - **angle2Deg** (number): The second angle in degrees.
19 | - **startAngleDeg** (number, optional): The start angle in degrees. The default value is 0.
20 | - **decimalPlaces** (number, optional): The number of decimal places to round the result. The default value is Infinity (no rounding).
21 |
22 |
23 | ## Angles Subtraction (Angular Distance)
24 |
25 | The getAnglesSub() function calculates the absolute difference between two angles, considering them as subtractions, and returns the result. It determines the shortest angular distance between the two angles, considering angles within the range of 0 to 360 degrees.
26 |
27 | ```js
28 | import { getAnglesSub } from 'mz-math';
29 |
30 | const angleDegrees1 = 315;
31 | const angleDegrees2 = 0;
32 | const decimalPlaces = 2; // optional
33 |
34 | const angle1 = getAnglesSub(angleDegrees1, angleDegrees2, decimalPlaces); // 45 degrees
35 | ```
36 |
37 | The function signature:
38 |
39 | ```ts
40 | const getAnglesSub: (angleDegrees1: number, angleDegrees2: number, decimalPlaces?: number) => number;
41 | ```
42 |
43 | - **angleDegrees1** (number): The first angle in degrees.
44 | - **angleDegrees2** (number): The second angle in degrees.
45 | - **decimalPlaces** (number, optional): The number of decimal places to round the result. The default value is Infinity (no rounding).
46 |
47 |
--------------------------------------------------------------------------------
/src/docs/data/pages/50-angles/5-is-angle-between.md:
--------------------------------------------------------------------------------
1 | ## Is angle between two other angles?
2 |
3 | This function checks if the given angle is between two other angles (inclusive). Angles are in degrees.
4 |
5 | ```js
6 | import { isAngleBetween } from 'mz-math';
7 |
8 | const isBetween1 = isAngleBetween(45, 0, 90); // true
9 | const isBetween2 = isAngleBetween(180, 0, 90); // false
10 | ```
11 |
12 |
--------------------------------------------------------------------------------
/src/docs/data/pages/50-angles/6-is-clockwise.md:
--------------------------------------------------------------------------------
1 | ## Is angle rotation clockwise?
2 |
3 | The isClockwise() function determines whether a given pair of angles represents a clockwise rotation or not, considering a start angle as the reference.
4 |
5 | ```js
6 | import { isClockwise } from 'mz-math';
7 |
8 | const isClockwise1 = isClockwise(0, 90); // true
9 | const isClockwise2 = isClockwise(90, 0); // false
10 | const isClockwise3 = isClockwise(90, 270, 270); // false
11 | ```
12 |
13 | The function signature is:
14 |
15 | ```ts
16 | const isClockwise: (angle1Deg: number, angle2Deg: number, startAngleDeg?: number) => boolean;
17 | ```
18 |
19 | - **angle1Deg** (number): The first angle in degrees.
20 | - **angle2Deg** (number): The second angle in degrees.
21 | - **startAngleDeg** (number, optional): The start angle in degrees. The default value is 0.
22 |
23 |
--------------------------------------------------------------------------------
/src/docs/data/pages/50-angles/7-percent-to-angle.md:
--------------------------------------------------------------------------------
1 | ## Convert Percent to Angle (in circle)
2 |
3 | The percentToAngle() function calculates the angle corresponding to a given percentage value within a specified range of start and end angles. It considers a circle start angle as a reference and returns the resulting angle based on whether the rotation is clockwise or counterclockwise.
4 |
5 | ```js
6 | import { percentToAngle } from 'mz-math';
7 |
8 | const angle1 = percentToAngle(0, 0, 90); // 0 degrees
9 | const angle2 = percentToAngle(percentToAngle(50, 0, 90)); // 45 degrees
10 | const angle3 = percentToAngle(percentToAngle(100, 0, 90)); // 90 degrees
11 | ```
12 |
13 | The function signature is:
14 | ```ts
15 | const percentToAngle: (percent: number, startAngleDeg: number, endAngleDeg: number, circleStartAngle?: number) => number;
16 | ```
17 |
18 | - **percent** (number): The percentage value between 0 and 100.
19 | - **startAngleDeg** (number): The starting angle in degrees.
20 | - **endAngleDeg** (number): The ending angle in degrees.
21 | - **circleStartAngle** (number, optional): The circle start angle in degrees. The default value is 0.
22 |
23 |
--------------------------------------------------------------------------------
/src/docs/data/pages/60-random/1-get-random-number-in-range.md:
--------------------------------------------------------------------------------
1 | # Get random number in range
2 |
3 | This function returns a random number in the range [min, max]. It supports an optional **decimalPlaces** parameter.
4 |
5 | ```js
6 | import { getRandom } from 'mz-math';
7 |
8 | const res1 = getRandom(10, 100); // 93.57877355999018
9 | const res2 = getRandom(10, 100, 2); // 80.28
10 | ```
--------------------------------------------------------------------------------
/src/docs/data/pages/60-random/2-get-random-integer.md:
--------------------------------------------------------------------------------
1 | # Get random integer
2 |
3 | This function returns a random integer number in the range [min, max].
4 |
5 | ```js
6 | import { getRandomInt } from 'mz-math';
7 |
8 | const res = getRandomInt(0, 100); // 63
9 | ```
--------------------------------------------------------------------------------
/src/docs/data/pages/60-random/3-get-random-boolean.md:
--------------------------------------------------------------------------------
1 | # Get random boolean value
2 |
3 | ```js
4 | import { getRandomBoolean } from 'mz-math';
5 |
6 | const res = getRandomBoolean(); // true or false
7 | ```
8 |
--------------------------------------------------------------------------------
/src/docs/data/pages/60-random/4-get-random-item-from-array.md:
--------------------------------------------------------------------------------
1 | # Get random item from array
2 |
3 | ```js
4 | import { getRandomItemFromArray } from 'mz-math';
5 |
6 | const item1 = getRandomItemFromArray([1,2,3,4,5]); // 2
7 | const item2 = getRandomItemFromArray(['a', 'b', 'c']); // 'a'
8 | const item3 = getRandomItemFromArray([{ test: 1 }, { test: 2 }, { test: 3 }]); // { test: 3 }
9 | ```
10 |
--------------------------------------------------------------------------------
/src/docs/data/pages/60-random/5-random-id-or-GUID.md:
--------------------------------------------------------------------------------
1 | # Random ID or GUID
2 |
3 | ```js
4 | import { guid, newId } from 'mz-math';
5 |
6 | const res1 = newId(); // a string like 'df4unio1opulby2uqh4'
7 | const res2 = guid(); // a guid like '932ade5e-c515-4807-ac01-73b20ab3fb66'
8 | ```
9 |
--------------------------------------------------------------------------------
/src/docs/data/pages/70-bezier-curve/1-get-point-on-quadratic-bezier-curve.md:
--------------------------------------------------------------------------------
1 | # Get a point on a quadratic Bézier curve
2 |
3 | Get a point on a quadratic Bézier curve as a function of time, where t is in the range [0, 1].
4 |
5 | **2D Vector**
6 |
7 | ```js
8 | import { v2QuadraticBezierCurve } from 'mz-math';
9 |
10 | const decimalPlaces = 2; // optional
11 |
12 | const v2 = v2QuadraticBezierCurve(
13 | 0.5,
14 | [0, 100],
15 | [50, 0],
16 | [100, 100],
17 | decimalPlaces
18 | ); // [50, 50]
19 |
20 | const v2 = v2QuadraticBezierCurve(
21 | 0,
22 | [0, 100],
23 | [50, 0],
24 | [100, 100],
25 | decimalPlaces
26 | ); // [0, 100]
27 |
28 | const v2 = v2QuadraticBezierCurve(
29 | 1,
30 | [0, 100],
31 | [50, 0],
32 | [100, 100],
33 | decimalPlaces
34 | ); // [100, 100]
35 | ```
36 |
37 | **3D Vector**
38 |
39 | ```js
40 | import { v3QuadraticBezierCurve } from 'mz-math';
41 |
42 | const decimalPlaces = 2; // optional
43 |
44 | const v3 = v3QuadraticBezierCurve(
45 | 0.5,
46 | [0, 100, 0],
47 | [50, 0, 0],
48 | [100, 100, 0],
49 | decimalPlaces
50 | ); // [50, 50, 0]
51 |
52 | const v3 = v3QuadraticBezierCurve(
53 | 0,
54 | [0, 100, 0],
55 | [50, 0, 0],
56 | [100, 100, 0],
57 | decimalPlaces
58 | ); // [0, 100, 0]
59 |
60 | const v3 = v3QuadraticBezierCurve(
61 | 1,
62 | [0, 100, 0],
63 | [50, 0, 0],
64 | [100, 100, 0],
65 | decimalPlaces
66 | ); // [100, 100, 0]
67 | ```
68 |
69 |
70 |
--------------------------------------------------------------------------------
/src/docs/data/pages/70-bezier-curve/2-get-point-on-cubic-bezier-curve.md:
--------------------------------------------------------------------------------
1 | # Get a point on a cubic Bézier curve
2 |
3 | Get a point on a cubic Bézier curve as a function of time, where t is in the range [0, 1].
4 |
5 | **2D Vector**
6 |
7 | ```js
8 | import { v2CubicBezierCurve } from 'mz-math';
9 |
10 | const decimalPlaces = 2; // optional
11 |
12 | const v2 = v2CubicBezierCurve(
13 | 0.5,
14 | [0, 100],
15 | [0, 0],
16 | [100, 0],
17 | [100, 100],
18 | decimalPlaces
19 | ); // [50, 25]
20 |
21 | const v2 = v2CubicBezierCurve(
22 | 0,
23 | [0, 100],
24 | [0, 0],
25 | [100, 0],
26 | [100, 100],
27 | decimalPlaces
28 | ); // [0, 100]
29 |
30 | const v2 = v2CubicBezierCurve(
31 | 1,
32 | [0, 100],
33 | [0, 0],
34 | [100, 0],
35 | [100, 100],
36 | decimalPlaces
37 | ); // [100, 100]
38 | ```
39 |
40 | **3D Vector**
41 |
42 | ```js
43 | import { v3CubicBezierCurve } from 'mz-math';
44 |
45 | const decimalPlaces = 2; // optional
46 |
47 | const v3 = v3CubicBezierCurve(
48 | 0.5,
49 | [0, 100, 0],
50 | [0, 0, 0],
51 | [100, 0, 0],
52 | [100, 100, 0],
53 | decimalPlaces
54 | ); // [50, 25, 0]
55 |
56 | const v3 = v3CubicBezierCurve(
57 | 0,
58 | [0, 100, 0],
59 | [0, 0, 0],
60 | [100, 0, 0],
61 | [100, 100, 0],
62 | decimalPlaces
63 | ); // [0, 100, 0]
64 |
65 | const v3 = v3CubicBezierCurve(
66 | 1,
67 | [0, 100, 0],
68 | [0, 0, 0],
69 | [100, 0, 0],
70 | [100, 100, 0],
71 | decimalPlaces
72 | ); // [100, 100, 0]
73 | ```
--------------------------------------------------------------------------------
/src/docs/data/pages/70-bezier-curve/3-tangent.md:
--------------------------------------------------------------------------------
1 | # Bezier Curve Tangent Vector
2 |
3 | **Cubic Bézier curve tangent for 2D Vector**
4 |
5 | ```js
6 | import { v2CubicBezierCurveTangent, Vector2 } from 'mz-math';
7 |
8 | const t = 0.6; // mast be in range [0, 1]
9 | const startControlPoint: Vector2 = [100, 200];
10 | const center1ControlPoint: Vector2 = [100, 50];
11 | const center2ControlPoint: Vector2 = [200, 150];
12 | const endControlPoint: Vector2 = [300, 250];
13 | const decimalPlaces = 2; // optional
14 |
15 | const result: Vector2 = v2CubicBezierCurveTangent(
16 | t,
17 | startControlPoint,
18 | center1ControlPoint,
19 | center2ControlPoint,
20 | endControlPoint,
21 | decimalPlaces
22 | );
23 | ```
24 |
25 | **Cubic Bézier curve tangent for 3D Vector**
26 |
27 | ```js
28 | import { v3CubicBezierCurveTangent, Vector2 } from 'mz-math';
29 |
30 | const t = 0.6; // mast be in range [0, 1]
31 | const startControlPoint: Vector3 = [100, 200, 0];
32 | const center1ControlPoint: Vector3 = [100, 50, 0];
33 | const center2ControlPoint: Vector3 = [200, 150, 0];
34 | const endControlPoint: Vector3 = [300, 250, 0];
35 | const decimalPlaces = 2; // optional
36 |
37 | const result: Vector3 = v3CubicBezierCurveTangent(
38 | t,
39 | startControlPoint,
40 | center1ControlPoint,
41 | center2ControlPoint,
42 | endControlPoint,
43 | decimalPlaces
44 | );
45 | ```
46 |
47 | **Quadratic Bézier curve tangent for 2D Vector**
48 |
49 | ```js
50 | import { dxV2QuadraticBezierCurve, Vector2 } from 'mz-math';
51 |
52 | const t = 0.6; // mast be in range [0, 1]
53 | const startControlPoint: Vector2 = [150, 550];
54 | const centerControlPoint: Vector2 = [400, 300];
55 | const endControlPoint: Vector2 = [50, 550];
56 | const decimalPlaces = 2; // optional
57 |
58 | const result: Vector2 = dxV2QuadraticBezierCurve(
59 | t,
60 | startControlPoint,
61 | centerControlPoint,
62 | endControlPoint,
63 | decimalPlaces
64 | );
65 | ```
66 |
67 | **Quadratic Bézier curve tangent for 3D Vector**
68 |
69 | ```js
70 | import { dxV3QuadraticBezierCurve, Vector3 } from 'mz-math';
71 |
72 | const t = 0.6; // mast be in range [0, 1]
73 | const startControlPoint: Vector3 = [150, 550, 0];
74 | const centerControlPoint: Vector3 = [400, 300, 0];
75 | const endControlPoint: Vector3 = [50, 550, 0];
76 | const decimalPlaces = 2; // optional
77 |
78 | const result: Vector3 = dxV3QuadraticBezierCurve(
79 | t,
80 | startControlPoint,
81 | centerControlPoint,
82 | endControlPoint,
83 | decimalPlaces
84 | );
85 | ```
86 |
--------------------------------------------------------------------------------
/src/docs/data/pages/70-bezier-curve/4-normal.md:
--------------------------------------------------------------------------------
1 | # Bezier Curve Normal Vector
2 |
3 | **Cubic Bézier curve normal**
4 |
5 | ```js
6 | import { v2CubicBezierCurveNormal, Vector2 } from 'mz-math';
7 |
8 | const t = 0.6; // mast be in range [0, 1]
9 | const startControlPoint: Vector2 = [100, 200];
10 | const center1ControlPoint: Vector2 = [100, 50];
11 | const center2ControlPoint: Vector2 = [200, 150];
12 | const endControlPoint: Vector2 = [300, 250];
13 | const decimalPlaces = 2; // optional
14 |
15 | const result: Vector2 = v2CubicBezierCurveNormal(
16 | t,
17 | startControlPoint,
18 | center1ControlPoint,
19 | center2ControlPoint,
20 | endControlPoint,
21 | decimalPlaces
22 | );
23 | ```
24 |
25 | **Quadratic Bézier curve normal**
26 |
27 | ```js
28 | import { v2QuadraticBezierCurveNormal, Vector2 } from 'mz-math';
29 |
30 | const t = 0.6; // mast be in range [0, 1]
31 | const startControlPoint: Vector2 = [150, 550];
32 | const centerControlPoint: Vector2 = [400, 300];
33 | const endControlPoint: Vector2 = [50, 550];
34 | const decimalPlaces = 2; // optional
35 |
36 | const result: Vector2 = v2QuadraticBezierCurveNormal(
37 | t,
38 | startControlPoint,
39 | centerControlPoint,
40 | endControlPoint,
41 | decimalPlaces
42 | );
43 | ```
44 |
--------------------------------------------------------------------------------
/src/docs/data/pages/70-bezier-curve/5-extrema.md:
--------------------------------------------------------------------------------
1 | # Bezier Curve Extrema
2 |
3 | **Cubic Bézier Extrema**
4 |
5 | ```js
6 | import { v2QuadraticBezierCurveExtrema, Vector2, Vector } from 'mz-math';
7 |
8 | const startControlPoint: Vector2 = [100, 200];
9 | const center1ControlPoint: Vector2 = [100, 50];
10 | const center2ControlPoint: Vector2 = [200, 150];
11 | const endControlPoint: Vector2 = [300, 250];
12 | const decimalPlaces = 2; // optional
13 |
14 | const result: Vector = v2QuadraticBezierCurveExtrema(
15 | startControlPoint,
16 | center1ControlPoint,
17 | center2ControlPoint,
18 | endControlPoint,
19 | decimalPlaces
20 | );
21 | ```
22 |
23 | **Quadratic Bézier Extrema**
24 |
25 | ```js
26 | import { v2CubicBezierCurveExtrema, Vector2 } from 'mz-math';
27 |
28 | const startControlPoint: Vector2 = [150, 550];
29 | const centerControlPoint: Vector2 = [400, 300];
30 | const endControlPoint: Vector2 = [50, 550];
31 | const decimalPlaces = 2; // optional
32 |
33 | const result: Vector2|null = v2CubicBezierCurveExtrema(
34 | startControlPoint,
35 | centerControlPoint,
36 | endControlPoint,
37 | decimalPlaces
38 | );
39 | ```
40 |
--------------------------------------------------------------------------------
/src/docs/data/pages/70-bezier-curve/6-bounding-box.md:
--------------------------------------------------------------------------------
1 | # Bezier Curve Bounding Box
2 |
3 | **Cubic Bézier Bounding Box**
4 |
5 | ```js
6 | import { v2CubicBezierBBox, Vector2 } from 'mz-math';
7 |
8 | const startControlPoint: Vector2 = [100, 200];
9 | const center1ControlPoint: Vector2 = [100, 50];
10 | const center2ControlPoint: Vector2 = [200, 150];
11 | const endControlPoint: Vector2 = [300, 250];
12 | const decimalPlaces = 2; // optional
13 |
14 | const result: IBBox = v2CubicBezierBBox(
15 | startControlPoint,
16 | center1ControlPoint,
17 | center2ControlPoint,
18 | endControlPoint,
19 | decimalPlaces
20 | );
21 | ```
22 |
23 | **Quadratic Bézier Bounding Box**
24 |
25 | ```js
26 | import { v2QuadraticBezierBBox, Vector2 } from 'mz-math';
27 |
28 | const startControlPoint: Vector2 = [150, 550];
29 | const centerControlPoint: Vector2 = [400, 300];
30 | const endControlPoint: Vector2 = [50, 550];
31 | const decimalPlaces = 2; // optional
32 |
33 | const result: IBBox = v2QuadraticBezierBBox(
34 | startControlPoint,
35 | centerControlPoint,
36 | endControlPoint,
37 | decimalPlaces
38 | );
39 | ```
40 |
41 | **IBBox Interface**
42 |
43 | ```ts
44 | export interface IBBox {
45 | x: number; // left top corner x
46 | y: number; // left top corner y
47 | w: number;
48 | h: number;
49 | x2: number; // right bottom corner x
50 | y2: number; // right bottom corner y
51 | }
52 | ```
53 |
--------------------------------------------------------------------------------
/src/docs/data/pages/80-equations/1-linear-equation.md:
--------------------------------------------------------------------------------
1 | # Linear Equation
2 |
3 | Using the **linearEquation()** function, you can a simple linear equation.
4 |
5 | ```js
6 | import { linearEquation, Vector3 } from 'mz-math';
7 |
8 | const equation: Vector3 = [1, 3, 5]; // x + 3 = 5
9 | const decimalPlaces = 2; // optional
10 |
11 | const result: number = linearEquation(equation, decimalPlaces); // 2
12 | ```
--------------------------------------------------------------------------------
/src/docs/data/pages/80-equations/2-system-of-linear-equations.md:
--------------------------------------------------------------------------------
1 | # System of linear Equations
2 |
3 | **System of 2 linear equations**
4 |
5 | Using the **linearEquationSystem2()** function, you can solve a system of 2 linear equations. It receives **2 vectors** of equation parameters and an optional **decimalPlaces** parameter.
6 |
7 | If the system of equations has no solution, then **null** is returned.
8 |
9 | For example:
10 |
11 | ```js
12 | import { linearEquationSystem2, Vector2, Vector3 } from 'mz-math';
13 |
14 | // 3x + 2y = 7
15 | // -6x + 6y = 6
16 |
17 | const equation1: Vector3 = [3, 2, 7];
18 | const equation2: Vector3 = [-6, 6, 6];
19 | const result: Vector2|null = linearEquationSystem2(equation1, equation2); // [1, 2] i.e. x=1, y=2
20 | ```
21 |
22 | **System of 3 linear equations**
23 |
24 | Using the **linearEquationSystem3()** function, you can solve a system of 3 linear equations. It receives **3 vectors** of equation parameters and an optional **decimalPlaces** parameter.
25 |
26 | If the system of equations has no solution, then **null** is returned.
27 |
28 | For example:
29 | ```js
30 | import { linearEquationSystem3, Vector3, Vector } from 'mz-math';
31 |
32 | // 2x + y + 2z = -2
33 | // -2x + 2y -z = -5
34 | // 4x + y + 2x = 0
35 |
36 | const equation1: Vector = [2, 1, 2, -2];
37 | const equation2: Vector = [-2, 2, -1, -5];
38 | const equation3: Vector = [4, 1, 2, 0];
39 | const result: Vector3|null = linearEquationSystem3(equation1, equation2, equation3); // [1, -2, -1] i.e. x=1, y=-2, z=-1
40 | ```
41 |
42 | **System of N linear equations**
43 |
44 | Using the **linearEquationSystemN()** function, you can solve a system of N linear equations. It receives a matrix of equation parameters, and an optional **decimalPlaces** parameter.
45 |
46 | If the system of equations has no solution, then **null** is returned.
47 |
48 | For example:
49 | ```js
50 | import { linearEquationSystem, Vector } from 'mz-math';
51 |
52 | /*
53 | y + z - 2w = -3
54 | x + 2y - z = 2
55 | 2x + 4y + z - 3w = -2
56 | x - 4y - 7z - w = -19
57 | */
58 |
59 | const parameters: Matrix = [
60 | [0, 1, 1, -2, -3],
61 | [1, 2, -1, 0, 2],
62 | [2, 4, 1, -3, -2],
63 | [1, -4, -7, -1, -19],
64 | ];
65 |
66 | const result: Vector|null = linearEquationSystemN(parameters, 2); // round to 2 decimal places
67 |
68 | // The result: [-1, 2, 1, 3] i.e. x = -1, y = 2, z = 1, w = 3
69 | ```
70 |
--------------------------------------------------------------------------------
/src/docs/data/pages/80-equations/3-quadratic-equation.md:
--------------------------------------------------------------------------------
1 | # Quadratic Equation
2 |
3 | Using the **quadraticEquation()** function, you can solve a quadratic equation.
4 |
5 | ```js
6 | import { quadraticEquation, Vector } from 'mz-math';
7 |
8 | const equation: Vector = [-4, 28, -49, 0]; // -4x^2 + 28x - 49 = 0
9 | const decimalPlaces = 2; // optional
10 |
11 | // 1 result
12 | const result: Vector = quadraticEquation(equation, decimalPlaces); // [3.5]
13 | ```
14 |
15 | ```js
16 | import { quadraticEquation, Vector } from 'mz-math';
17 |
18 | const equation: Vector = [1, -1, 0, 0]; // x^2 - x = 0
19 | const decimalPlaces = 2; // optional
20 |
21 | // 2 results
22 | const result: Vector = quadraticEquation(equation, decimalPlaces); // [1, 0]
23 | ```
24 |
25 | ```js
26 | import { quadraticEquation, Vector } from 'mz-math';
27 |
28 | const equation: Vector = [3, -4, 94, 0]; // 3x^2 - 4x + 94 = 0
29 | const decimalPlaces = 2; // optional
30 |
31 | // no results
32 | const result: Vector = quadraticEquation(equation, decimalPlaces); // []
33 | ```
34 |
35 | ```js
36 | import { quadraticEquation, Vector } from 'mz-math';
37 |
38 | const equation: Vector = [1, 0, -10, 39]; // x^2 - 10 = 39
39 | const decimalPlaces = 2; // optional
40 |
41 | // 2 results
42 | const result: Vector = quadraticEquation(equation, decimalPlaces); // [7, -7]
43 | ```
--------------------------------------------------------------------------------
/src/docs/data/pages/80-equations/4-get-linear-equation-by-2-points.md:
--------------------------------------------------------------------------------
1 | # Get linear equation by two points
2 |
3 | The **getLinearEquationBy2Points()** function calculates the equation of a line given two points in a 2D space. The equation is in the form of **y = ax + b**, where **'a'** represents the slope of the line and **'b'** represents the y-intercept.
4 |
5 | ```js
6 | import { getLinearEquationBy2Points, Vector2 } from 'mz-math';
7 |
8 | const point1: Vector2 = [2, 3];
9 | const point2: Vector2 = [4, 7];
10 | const result = getLinearEquationBy2Points(point1, point2);
11 |
12 | /*
13 | Result:
14 | -------
15 | {
16 | formula: "y = 2x - 1",
17 | slope: 2,
18 | yIntercept: -1,
19 | xIntercept: undefined,
20 | }
21 | */
22 | ```
23 |
24 | ```js
25 | import { getLinearEquationBy2Points, Vector2 } from 'mz-math';
26 |
27 | const point1: Vector2 = [1, 5];
28 | const point2: Vector2 = [3, 5];
29 | const result = getLinearEquationBy2Points(point1, point2);
30 |
31 | /*
32 | Result:
33 | -------
34 | {
35 | formula: "y = 5",
36 | slope: 0,
37 | yIntercept: 5,
38 | xIntercept: undefined,
39 | }
40 | */
41 | ```
42 |
43 | ```js
44 | import { getLinearEquationBy2Points, Vector2 } from 'mz-math';
45 |
46 | const point1: Vector2 = [2, 3];
47 | const point2: Vector2 = [2, 7];
48 | const result = getLinearEquationBy2Points(point1, point2);
49 |
50 | /*
51 | Result:
52 | -------
53 | {
54 | formula: "x = 2",
55 | slope: undefined,
56 | yIntercept: undefined,
57 | xIntercept: 2,
58 | }
59 | */
60 | ```
--------------------------------------------------------------------------------
/src/docs/data/pages/90-path-movement/1-circle-movement.md:
--------------------------------------------------------------------------------
1 | # Circle Movement
2 |
3 | ```js
4 | import { circleMovement, Vector2 } from 'mz-math';
5 |
6 | const center: Vector2 = [100, 100];
7 | const radiansAngle = Math.PI/2; // Angle should be in the range [0, Math.PI]
8 | const radius = 250;
9 | const newPosition: Vector2 = circleMovement(center, radiansAngle, radius);
10 | ```
11 |
12 | [Example](https://github.com/mzusin/mz-math/blob/main/examples/circular-movement/circle-movement-3.html)
13 |
14 | ## Circle movement after mouse
15 |
16 | ```js
17 | import { circleMovementAfterMouse, Vector2 } from 'mz-math';
18 |
19 | const mouse = [evt.clientX, evt.clientY];
20 | const center: Vector2 = [100, 100];
21 | const radius = 250;
22 |
23 | const position: Vector2 = circleMovementAfterMouse(mouse, center, radius);
24 | ```
25 |
26 | [Example](https://github.com/mzusin/mz-math/blob/main/examples/circular-movement/circle-movement-mouse-1.html)
27 |
--------------------------------------------------------------------------------
/src/docs/data/pages/90-path-movement/2-ellipse-movement.md:
--------------------------------------------------------------------------------
1 | # Ellipse Movement
2 |
3 | ```js
4 | import { ellipseMovement, Vector2 } from 'mz-math';
5 |
6 | const center: Vector2 = [100, 100];
7 | const radiansAngle = Math.PI/2; // Angle should be in the range [0, Math.PI]
8 | const radius1 = 350;
9 | const radius2 = 150;
10 | const newPosition: Vector2 = ellipseMovement(center, radiansAngle, radius1, radius2);
11 | ```
12 |
13 | [Example](https://github.com/mzusin/mz-math/blob/main/examples/circular-movement/ellipse-movement-3.html)
14 |
15 |
16 | ## Ellipse movement after mouse
17 |
18 | ```js
19 | import { ellipseMovementAfterMouse, Vector2 } from 'mz-math';
20 |
21 | const mouse = [evt.clientX, evt.clientY];
22 | const center: Vector2 = [100, 100];
23 | const radii = [250, 300];
24 |
25 | const position: Vector2 = ellipseMovementAfterMouse(mouse, center, radii);
26 | ```
--------------------------------------------------------------------------------
/src/docs/data/pages/90-path-movement/3-sine-wave-movement.md:
--------------------------------------------------------------------------------
1 | # Sine Wave Movement
2 |
3 | ```js
4 | import { ellipseMovement, Vector2 } from 'mz-math';
5 |
6 | const amplitude = 100; // the peak deviation of the function from zero
7 | const frequency = 0.003; // number of cycles
8 | const phase = 0; // starting point "shifting"
9 | const x = 0; // changes from 0 to .... N
10 | const newPosition: Vector2 = ellipseMovement(x, amplitude, frequency, phase);
11 | ```
12 |
13 | [Example](https://github.com/mzusin/mz-math/blob/main/examples/wave-movement/wave-movement-1.html)
--------------------------------------------------------------------------------
/src/docs/data/pages/90-path-movement/4-lissajous-curve.md:
--------------------------------------------------------------------------------
1 | # Lissajous curve
2 |
3 | ```js
4 | import { lissajousCurve, Vector2, getRandom } from 'mz-math';
5 |
6 | const m = 0;
7 | const p = 0;
8 | const t = 1;
9 |
10 | const k = getRandom(0, Math.PI * 2); // [0, 360]
11 | const n = getRandom(0, Math.PI * 2); // [0, 360]
12 |
13 | const A = getRandom(0, 100); // [0, 100] - width
14 | const B = getRandom(0, 100); // [0, 100] - height
15 |
16 | const newPosition: Vector2 = mzMath.lissajousCurve(
17 | A, // width
18 | B, // height
19 | t,
20 | k,
21 | n,
22 | m,
23 | p
24 | );
25 |
26 | /*
27 | Parametric equation
28 | f(t) = A * cos(k * t - m)
29 | f(t) = B * cos(n * t - p)
30 | */
31 | ```
32 |
33 | [Example](https://github.com/mzusin/mz-math/blob/main/examples/lissajous-curves/lissajous-curves-canvas.html)
--------------------------------------------------------------------------------
/src/docs/data/pages/pages-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "3-nodejs-usage.md": {
3 | "title": "Node.js Usage"
4 | },
5 | "4-multiply-vector-by-scalar.md": {
6 | "title": "Multiply by Scalar"
7 | },
8 | "5-divide-vector-by-scalar.md": {
9 | "title": "Divide by Scalar"
10 | },
11 | "7-normalize-vector.md": {
12 | "title": "Normalized (Unit) Vector"
13 | }
14 | }
--------------------------------------------------------------------------------
/src/docs/generator/client-side/css-provider.js:
--------------------------------------------------------------------------------
1 | import postcss from "postcss";
2 | import tailwindcss from "tailwindcss";
3 | import cssnano from "cssnano";
4 | import autoprefixer from "autoprefixer";
5 | import path from "path";
6 | import fs from "fs";
7 |
8 | /**
9 | * compile client side CSS
10 | * @param {number} cssTimeStamp
11 | * @returns {Promise}
12 | */
13 | export const compileClientSideCSS = async (cssTimeStamp) => {
14 | // defined postcss handler
15 | const postcssHandler = postcss([
16 | // postcssImport({}),
17 | tailwindcss({
18 |
19 | // purge --------
20 | content: [
21 | './docs/**/*.html',
22 | ],
23 | theme: {
24 |
25 | // https://tailwindcss.com/docs/font-family
26 | fontFamily: {
27 | roboto: '"Roboto",system-ui,-apple-system,"Segoe UI","Helvetica Neue",Arial,"Noto Sans","Liberation Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji"'
28 | },
29 | },
30 | variants: {
31 | extend: {},
32 | },
33 |
34 | darkMode: 'class',
35 | }),
36 | cssnano({ preset: 'default' }),
37 | autoprefixer,
38 | ]);
39 |
40 | const cssSourcePath = path.join(process.cwd(), './src/docs/client-side/css/index.css');
41 | const css = fs.readFileSync(cssSourcePath, 'utf-8');
42 | const cssRes = await postcssHandler.process(css, {
43 | from: cssSourcePath
44 | });
45 |
46 | const cssTargetPath = path.join(process.cwd(), `./docs/css/styles.${ cssTimeStamp }.css`);
47 | fs.writeFileSync(cssTargetPath, cssRes.css, 'utf8');
48 | };
--------------------------------------------------------------------------------
/src/docs/generator/client-side/js-provider.js:
--------------------------------------------------------------------------------
1 | import esbuild from 'esbuild';
2 | import path from 'path';
3 |
4 | /**
5 | * compile client side javascript
6 | * @param {number} jsTimeStamp
7 | */
8 | export const compileClientSideScripts = (jsTimeStamp) => {
9 | esbuild
10 | .build({
11 | entryPoints: [path.join(process.cwd(), './src/docs/client-side/js/index.tsx')],
12 | bundle: true,
13 | sourcemap: 'linked', // external
14 | minify: true,
15 | target: ['es6'],
16 | outfile: `./docs/js/index.${ jsTimeStamp }.js`,
17 | loader: {
18 | '.png': 'text',
19 | '.svg': 'dataurl',
20 | },
21 | })
22 | .then(() => {
23 | // console.log('Done.');
24 | })
25 | .catch(() => process.exit(1));
26 | };
--------------------------------------------------------------------------------
/src/docs/generator/common-provider.js:
--------------------------------------------------------------------------------
1 | import path from 'path';
2 | import appRoot from 'app-root-path';
3 | import fs from 'fs';
4 |
5 | export const changeExtension = (filePath, newExtension) => {
6 | const basename = path.basename(filePath, path.extname(filePath));
7 | return path.join(path.dirname(filePath), basename + newExtension);
8 | };
9 |
10 | export const removeNumberOnStart = (fileName) => {
11 | let result = fileName;
12 |
13 | const index = fileName.indexOf('-');
14 | if(index !== -1){
15 | result = result.substring(index + 1);
16 | }
17 |
18 | return result;
19 | };
20 |
21 | export const toTitleCase = (str) => {
22 | str = str.replaceAll('-', ' ');
23 |
24 | return str.replace(
25 | /\w\S*/g,
26 | function(txt) {
27 | return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();
28 | }
29 | );
30 | };
31 |
32 | export const getTimeStamp = () => {
33 | return new Date().getTime();
34 | };
35 |
36 | export const getRoot = () => {
37 | const userRoot = appRoot.path;
38 | const docsModuleRoot = path.join(userRoot, 'node_modules/markdown-documentation-maker');
39 | return fs.existsSync(docsModuleRoot) ? docsModuleRoot : userRoot;
40 | };
--------------------------------------------------------------------------------
/src/docs/generator/index.js:
--------------------------------------------------------------------------------
1 | import path from 'path';
2 | import fs from 'fs';
3 | import fse from 'fs-extra';
4 | import { compileClientSideCSS } from './client-side/css-provider.js';
5 | import { compileClientSideScripts } from './client-side/js-provider.js';
6 | import { configureMarkdown, initMarkDown } from './markdown-config.js'; // https://highlightjs.org
7 | import emoji from 'markdown-it-emoji'; // https://github.com/markdown-it/markdown-it-emoji
8 | import { loadConfig, renderPages } from './render/pages-provider.js';
9 | import { collectSideMenuData, getPagesList } from './render/side-menu-provider.js';
10 | import { getTimeStamp } from './common-provider.js';
11 | import { renderSpecialPages } from './render/special-pages-provider.js';
12 | import { renderSitemap, updateReadmeDocs } from './render/sitemap-provider.js';
13 |
14 | export const DATA_FOLDER = path.join(process.cwd(), './src/docs/data');
15 | export const OUTPUT_FOLDER = path.join(process.cwd(), './docs');
16 |
17 | // markdown -------------------
18 | const md = initMarkDown();
19 | md.use(emoji);
20 | configureMarkdown(md);
21 |
22 | const init = async () => {
23 | const sourceRootPath = path.join(DATA_FOLDER, './pages');
24 | const targetRootPath = path.join(OUTPUT_FOLDER, './pages');
25 |
26 | const cssTimeStamp = getTimeStamp();
27 | const jsTimeStamp = getTimeStamp();
28 |
29 | // empty destination folders
30 | fse.emptyDirSync(targetRootPath);
31 | fse.emptyDirSync(path.join(OUTPUT_FOLDER, './css'));
32 | fse.emptyDirSync(path.join(OUTPUT_FOLDER, './js'));
33 |
34 | // load layout
35 | const layoutPath = path.join(DATA_FOLDER, './layouts/page-layout.html');
36 | const layout = fs.readFileSync(layoutPath, 'utf8');
37 |
38 | // load config files
39 | const mainConfig = loadConfig(path.join(DATA_FOLDER, './config.json'));
40 | const pagesConfig = loadConfig(path.join(DATA_FOLDER, './pages/pages-config.json'));
41 |
42 | // collect side menu data
43 | const sideMenuMap = new Map();
44 | collectSideMenuData(sourceRootPath, null, sideMenuMap);
45 |
46 | // pages list is used for prev / next section at the bottom of the pages
47 | const pagesList = getPagesList(sideMenuMap);
48 |
49 | // render all pages in the given folder recursively - markdown to html
50 | renderPages(sourceRootPath, targetRootPath, {
51 | layout,
52 | sideMenuMap,
53 | pagesConfig,
54 | cssTimeStamp,
55 | jsTimeStamp,
56 | pagesList,
57 | mainConfig,
58 | }, md);
59 |
60 | // render all pages like index.html
61 | const specialPagesLayoutPath = path.join(DATA_FOLDER, './layouts/special-page-layout.html');
62 | const specialPagesLayout = fs.readFileSync(specialPagesLayoutPath, 'utf8');
63 |
64 | renderSpecialPages(
65 | path.join(DATA_FOLDER, './special-pages'),
66 | path.join(OUTPUT_FOLDER),
67 | {
68 | layout: specialPagesLayout,
69 | cssTimeStamp,
70 | jsTimeStamp,
71 | mainConfig,
72 | }
73 | );
74 |
75 | // render sitemap
76 | renderSitemap(
77 | mainConfig?.website?.url || '',
78 | path.join(OUTPUT_FOLDER),
79 | pagesList
80 | );
81 |
82 | compileClientSideScripts(jsTimeStamp);
83 | await compileClientSideCSS(cssTimeStamp);
84 |
85 | updateReadmeDocs(
86 | mainConfig?.website?.url || '',
87 | path.join(OUTPUT_FOLDER),
88 | sideMenuMap,
89 | pagesConfig
90 | );
91 | };
92 |
93 | await init();
--------------------------------------------------------------------------------
/src/docs/generator/render/macros-provider.js:
--------------------------------------------------------------------------------
1 | export const setMacros = (html, data) => {
2 | let result = html;
3 |
4 | result = result.replaceAll('{% css-hash %}', data.cssTimeStamp);
5 | result = result.replaceAll('{% js-hash %}', data.jsTimeStamp);
6 | result = result.replaceAll('{% website-name %}', data.mainConfig.website.name);
7 | result = result.replaceAll('{% github %}', data.mainConfig.social.github);
8 | result = result.replaceAll('{% twitter %}', data.mainConfig.social.twitter);
9 | result = result.replaceAll('{% email %}', data.mainConfig.social.email);
10 | result = result.replaceAll('{% google-analytics-gtag %}', data.mainConfig.analytics.gtag);
11 |
12 | return result;
13 | };
--------------------------------------------------------------------------------
/src/docs/generator/render/sitemap-provider.js:
--------------------------------------------------------------------------------
1 | import { removeNumberOnStart, toTitleCase } from '../common-provider.js';
2 | import fs from 'fs';
3 | import path from 'path';
4 |
5 | export const renderSitemap = (websiteUrl, rootPath, pagesList) => {
6 | let siteMap = `${ websiteUrl }\n`;
7 |
8 | for(const link of pagesList){
9 | const formatted = `${ websiteUrl }/pages/${ removeNumberOnStart(link) }.html\n`;
10 | siteMap += formatted;
11 | }
12 |
13 | const targetFilePath = path.join(rootPath, 'sitemap.txt')
14 | fs.writeFileSync(targetFilePath, siteMap, 'utf8');
15 | };
16 |
17 | export const updateReadmeDocs = (websiteUrl, rootPath, sideMenuMap, pagesConfig) => {
18 | const DOCS_START = '## Documentation 🔖';
19 | const DOCS_END = '------------------------------';
20 |
21 | const readmePath = path.join(process.cwd(), './README.md');
22 | let readme = fs.readFileSync(readmePath, 'utf8');
23 | if(!readme.includes(DOCS_START)) return;
24 |
25 | // create the 'Table of contents'
26 | let md = `${ DOCS_START }\n`;
27 |
28 | const sections = Array.from(sideMenuMap.keys());
29 |
30 | // sort sections (folders) in the alphanumeric order
31 | // before removing the beginning number with dash
32 | sections.sort((item1, item2) => {
33 | return item1.localeCompare(item2, undefined, {
34 | numeric: true,
35 | sensitivity: 'base'
36 | });
37 | });
38 |
39 | for(const section of sections) {
40 | // check if section title appears in pages-config.json
41 | // otherwise remove dashes and apply title case
42 | const sectionConfigValue = pagesConfig[`${ section }`];
43 | const sectionTitle = sectionConfigValue ? sectionConfigValue.title : toTitleCase(removeNumberOnStart(section));
44 |
45 | // find all section links and sort them in alphanumeric order
46 | // before removing the beginning number with dash
47 | const links = Array.from(sideMenuMap.get(section));
48 | links.sort((item1, item2) => {
49 | return item1.localeCompare(item2, undefined, {
50 | numeric: true,
51 | sensitivity: 'base'
52 | });
53 | });
54 |
55 | // add title --------
56 | md += `### ${ sectionTitle } \n`;
57 |
58 | for (let i = 0; i < links.length; i++) {
59 | const link = links[i];
60 | const codeName = removeNumberOnStart(link);
61 |
62 | // check if page titles appears in pages-config.json
63 | // otherwise remove dashes and apply title case
64 | const pagesConfigValue = pagesConfig[`${ link }.md`];
65 | const title = pagesConfigValue ? pagesConfigValue.title : toTitleCase(codeName);
66 |
67 | const url = `${ websiteUrl }/pages/${ codeName }.html`;
68 | md += `- [${ title }](${ url })\n`;
69 | }
70 | }
71 |
72 | md += `${ DOCS_END }\n`;
73 |
74 | // replace the value in readme
75 | const regex = new RegExp(`${ DOCS_START }([\\s\\S]*)${ DOCS_END }`, 'gim');
76 | readme = readme.replace(regex, md);
77 |
78 | fs.writeFileSync(readmePath, readme, 'utf8');
79 | };
--------------------------------------------------------------------------------
/src/docs/generator/render/special-pages-provider.js:
--------------------------------------------------------------------------------
1 | import fs from 'fs';
2 | import path from 'path';
3 | import { removeNumberOnStart } from '../common-provider.js';
4 | import fse from 'fs-extra';
5 | import { setMacros } from './macros-provider.js';
6 |
7 | /**
8 | * render all pages special pages like index.html
9 | * @param {string} sourceRootPath
10 | * @param {string} targetRootPath
11 | * @param {object} data
12 | */
13 | export const renderSpecialPages = (sourceRootPath, targetRootPath, data) => {
14 |
15 | const items = fs.readdirSync(sourceRootPath);
16 |
17 | // loop through all the nested files and folders
18 | for (const item of items) {
19 |
20 | if(item === '.DS_Store') continue;
21 |
22 | // get the absolute file / folder path
23 | const sourceItemPath = path.join(sourceRootPath, item);
24 | const targetItemPath = path.join(targetRootPath, removeNumberOnStart(item));
25 |
26 | // console.log(`Working on ${ sourceItemPath }`);
27 |
28 | const stat = fs.statSync( sourceItemPath );
29 |
30 | // in case it's a file
31 | if(stat.isFile()){
32 |
33 | const ext = path.extname(item);
34 |
35 | if(ext === '.html'){
36 | const html = fs.readFileSync(sourceItemPath, 'utf8');
37 |
38 | let result = data.layout.replaceAll('{% page-content %}', html);
39 | result = setMacros(result, data);
40 |
41 | // write the output HTML to the destination
42 | const targetFilePath = targetItemPath;
43 | fse.ensureFileSync(targetFilePath);
44 | fs.writeFileSync(targetFilePath, result, 'utf8');
45 | }
46 | }
47 |
48 | // in case it's a folder - > render recursively
49 | else{
50 | renderSpecialPages(sourceItemPath, targetRootPath, data);
51 | }
52 | }
53 | };
--------------------------------------------------------------------------------
/src/index-esm.ts:
--------------------------------------------------------------------------------
1 | export * from './main/linear-algebra/vector';
2 | export * from './main/linear-algebra/matrix';
3 | export * from './main/linear-algebra/matrix-transformations';
4 | export * from './main/format';
5 | export * from './main/angle';
6 | export * from './main/random';
7 | export * from './main/other';
8 | export * from './main/convert';
9 | export * from './main/bezier-curves/bezier-curve';
10 | export * from './main/equations/linear-equations';
11 | export * from './main/path-movement';
12 | export * from './main/color';
13 | export * from './main/physics';
14 | export * from './main/id';
15 | export * from './main/derivative';
16 | export * from './main/collision-detection';
17 | export * from './main/animation';
18 | export * from './main/circle-ellipse';
19 | export * from './main/sequence';
20 | export * from './main/statistics';
21 | export * from './main/ml';
22 | export * from './main/series';
23 | export * from './main/combinatorics/factorial';
24 | export * from './main/combinatorics/combinatorics';
--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------
1 | import * as vector from './main/linear-algebra/vector';
2 | import * as matrix from './main/linear-algebra/matrix';
3 | import * as matrixTransformations from './main/linear-algebra/matrix-transformations';
4 | import * as format from './main/format';
5 | import * as angle from './main/angle';
6 | import * as random from './main/random';
7 | import * as other from './main/other';
8 | import * as convert from './main/convert';
9 | import * as bezierCurve from './main/bezier-curves/bezier-curve';
10 | import * as equations from './main/equations/linear-equations';
11 | import * as pathMovement from './main/path-movement';
12 | import * as color from './main/color';
13 | import * as physics from './main/physics';
14 | import * as id from './main/id';
15 | import * as derivative from './main/derivative';
16 | import * as collisions from './main/collision-detection';
17 | import * as animation from './main/animation';
18 | import * as circleEllipse from './main/circle-ellipse';
19 | import * as sequence from './main/sequence';
20 | import * as statistics from './main/statistics';
21 | import * as ml from './main/ml';
22 | import * as series from './main/series';
23 | import * as factorial from './main/combinatorics/factorial';
24 | import * as combinatorics from './main/combinatorics/combinatorics';
25 |
26 | const api = {
27 | ...vector,
28 | ...matrix,
29 | ...matrixTransformations,
30 | ...format,
31 | ...angle,
32 | ...random,
33 | ...other,
34 | ...convert,
35 | ...bezierCurve,
36 | ...equations,
37 | ...pathMovement,
38 | ...color,
39 | ...physics,
40 | ...id,
41 | ...derivative,
42 | ...collisions,
43 | ...animation,
44 | ...circleEllipse,
45 | ...sequence,
46 | ...statistics,
47 | ...ml,
48 | ...series,
49 | ...factorial,
50 | ...combinatorics,
51 | };
52 |
53 | declare global {
54 | interface Window {
55 | mzMath: typeof api,
56 | }
57 | }
58 |
59 | window.mzMath = window.mzMath || api;
60 |
61 | export * from './main/linear-algebra/vector';
62 | export * from './main/linear-algebra/matrix';
63 | export * from './main/linear-algebra/matrix-transformations';
64 | export * from './main/format';
65 | export * from './main/angle';
66 | export * from './main/random';
67 | export * from './main/other';
68 | export * from './main/convert';
69 | export * from './main/bezier-curves/bezier-curve';
70 | export * from './main/equations/linear-equations';
71 | export * from './main/path-movement';
72 | export * from './main/color';
73 | export * from './main/physics';
74 | export * from './main/id';
75 | export * from './main/derivative';
76 | export * from './main/collision-detection';
77 | export * from './main/animation';
78 | export * from './main/circle-ellipse';
79 | export * from './main/sequence';
80 | export * from './main/statistics';
81 | export * from './main/ml';
82 | export * from './main/series';
83 | export * from './main/combinatorics/factorial';
84 | export * from './main/combinatorics/combinatorics';
--------------------------------------------------------------------------------
/src/main/circle-ellipse.ts:
--------------------------------------------------------------------------------
1 | import { setDecimalPlaces } from './format';
2 |
3 | export const getCircleCircumference = (radius: number, decimalPlaces = Infinity) => {
4 | return setDecimalPlaces(2 * Math.PI * radius, decimalPlaces);
5 | };
6 |
7 | export const getEllipseCircumference = (radius1: number, radius2: number, decimalPlaces = Infinity) => {
8 | return setDecimalPlaces(2 * Math.PI * Math.sqrt((radius1 ** 2 + radius2 ** 2) / 2), decimalPlaces);
9 | };
10 |
11 | export const isAngleInCircleArc = (startAngleDeg: number, endAngleDeg: number, currentDegrees: number) : boolean => {
12 |
13 | if(startAngleDeg > endAngleDeg) {
14 | endAngleDeg += 360;
15 | }
16 |
17 | return currentDegrees >= startAngleDeg && currentDegrees <= endAngleDeg ||
18 | (currentDegrees + 360) >= startAngleDeg && (currentDegrees + 360) <= endAngleDeg;
19 | };
20 |
21 | /**
22 | * get the side of a square inscribed in a circle
23 | */
24 | export const getSquareInCircleSide = (radius: number, decimalPlaces = Infinity) => {
25 | return setDecimalPlaces(radius * 2 / Math.sqrt(2), decimalPlaces);
26 | };
27 |
--------------------------------------------------------------------------------
/src/main/collision-detection.ts:
--------------------------------------------------------------------------------
1 | import { ICircle, IPolygon, IRect, Matrix2, Vector2 } from '../types';
2 | import { mod } from './other';
3 | import { v2GetNormal, v2DotProduct } from './linear-algebra/vector';
4 |
5 | /**
6 | * Rectangles collision detection.
7 | * Rectangles should not be rotated.
8 | * The algorithm works by ensuring there is no gap between any of the 4 sides of the rectangles.
9 | * Any gap means a collision does not exist.
10 | * Returns true if collision is detected.
11 | */
12 | export const rectCollide = (rect1: IRect, rect2: IRect) : boolean => {
13 | return rect1.x <= rect2.x + rect2.w &&
14 | rect1.x + rect1.w >= rect2.x &&
15 | rect1.y <= rect2.y + rect2.h &&
16 | rect1.h + rect1.y >= rect2.y;
17 | };
18 |
19 | /**
20 | * Circles collision detection.
21 | * This algorithm works by taking the center points of the two circles
22 | * and ensuring the distance between the center points
23 | * are less than the two radii added together.
24 | * Returns true if collision is detected.
25 | */
26 | export const circleCollide = (circle1: ICircle, circle2: ICircle) => {
27 | const dx = Math.abs(circle1.cx - circle2.cx);
28 | const dy = Math.abs(circle1.cy - circle2.cy);
29 | const distance = Math.sqrt(dx * dx + dy * dy);
30 | return distance <= circle1.r + circle2.r;
31 | };
32 |
33 | //-------------------- Separating Axis Theorem (SAT) Collision detection -------------------------
34 |
35 | const getEdges = (poly: IPolygon) : Matrix2[] => {
36 | const edges: Matrix2[] = [];
37 |
38 | for(let i= 0; i {
48 | const edges: Matrix2[] = [];
49 |
50 | // collect polygon edges, and combine then into a single array
51 | edges.push(...getEdges(poly1));
52 | edges.push(...getEdges(poly2));
53 |
54 | // for each edge, find the normal vector and project both polygons onto it
55 | for (const edge of edges) {
56 | const normal = v2GetNormal(edge[0], edge[1]);
57 | const p1Proj = projectPolygon(poly1, normal);
58 | const p2Proj = projectPolygon(poly2, normal);
59 |
60 | // Check if the projections overlap
61 | const isOverlap = p1Proj.max >= p2Proj.min && p2Proj.max >= p1Proj.min;
62 |
63 | // Check if the projections overlap; if not, the polygons do not collide
64 | if (!isOverlap) return false;
65 | }
66 |
67 | // If all tests pass, the polygons overlap and collide
68 | return true;
69 | };
70 |
71 | /**
72 | * Project every polygon point onto the normal.
73 | * Then find min and max.
74 | */
75 | const projectPolygon = (polygon: IPolygon, normal: Vector2): { min: number, max: number } => {
76 | let min = Infinity;
77 | let max = -Infinity;
78 |
79 | // Project each vertex of the polygon onto the axis
80 | for (const vertex of polygon) {
81 | const projection = v2DotProduct(vertex, normal);
82 | min = Math.min(min, projection);
83 | max = Math.max(max, projection);
84 | }
85 |
86 | return { min, max };
87 | };
--------------------------------------------------------------------------------
/src/main/convert.ts:
--------------------------------------------------------------------------------
1 | export const stringToNumber = (value: string|undefined|null|number, defaultNumber: number) => {
2 | if(value === undefined || value === null) return defaultNumber;
3 | const res = Number(value) ?? defaultNumber;
4 | return isNaN(res) ? defaultNumber : res;
5 | };
--------------------------------------------------------------------------------
/src/main/equations/quadratic-equations.ts:
--------------------------------------------------------------------------------
1 | import { Vector } from '../../types';
2 | import { setDecimalPlaces } from '../format';
3 | import { linearEquation } from './linear-equations';
4 | import { isNumber } from '../other';
5 |
6 | /**
7 | * Quadratic Equation.
8 | * ax^2 + bx + c = d
9 | */
10 | export const quadraticEquation = (equation: Vector, decimalPlaces = Infinity) : Vector => {
11 | const a = equation[0];
12 | const b = equation[1];
13 | const c = equation[2];
14 | const d = equation[3];
15 |
16 | if(a === 0){
17 | // it's a linear equation -------------------------------------------
18 | const res = linearEquation([b, c, d], decimalPlaces);
19 | if(isNumber(res)) return [res];
20 | return [];
21 | }
22 |
23 | const diff = c - d;
24 |
25 | const discriminant = b * b - (4 * a * diff);
26 |
27 | if(discriminant < 0){
28 | return []; // no results
29 | }
30 |
31 | if(discriminant === 0){
32 | return [ setDecimalPlaces(-b / (2 * a), decimalPlaces) ]; // 1 result
33 | }
34 |
35 | // if(determinant > 0) ---> 2 results
36 | const t1 = 2 * a;
37 | const t2 = Math.sqrt(discriminant);
38 |
39 | return [
40 | setDecimalPlaces((-b + t2) / t1, decimalPlaces),
41 | setDecimalPlaces((-b - t2) / t1, decimalPlaces),
42 | ];
43 | };
--------------------------------------------------------------------------------
/src/main/format.ts:
--------------------------------------------------------------------------------
1 | export const setDecimalPlaces = (num: number, decimalPlaces: number | undefined = Infinity) => {
2 | if(decimalPlaces === Infinity) return num;
3 |
4 | if(decimalPlaces < 0){
5 | decimalPlaces = 0;
6 | }
7 |
8 | const coefficient = 10 ** decimalPlaces;
9 | return Math.round(num * coefficient) / coefficient;
10 | };
--------------------------------------------------------------------------------
/src/main/id.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * guid like '932ade5e-c515-4807-ac01-73b20ab3fb66'
3 | */
4 | export const guid = () => {
5 | return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
6 | const r = Math.random() * 16 | 0;
7 | return (c == 'x' ? r : r & 0x3 | 0x8).toString(16);
8 | });
9 | };
10 |
11 | /**
12 | * id like 'df4unio1opulby2uqh4'
13 | */
14 | export const newId = () => {
15 | return Math.random().toString(36).substring(2) + (new Date()).getTime().toString(36);
16 | };
17 |
--------------------------------------------------------------------------------
/src/main/ml.ts:
--------------------------------------------------------------------------------
1 | import { setDecimalPlaces } from './format';
2 | import { getArithmeticMean, getStandardDeviation } from './statistics';
3 | import { IMlNormalizeResult, IMlStandardizeResult } from '../types';
4 |
5 | // --------------------- NORMALIZE --------------------------------
6 |
7 | /**
8 | * Changes value to be in the range [0, 1].
9 | */
10 | export const mlNormalizeValue = (value: number, min: number, max: number, decimalPlaces = Infinity) : number => {
11 | const diff = max - min;
12 | if(diff === 0) return 0;
13 | return setDecimalPlaces((value - min) / diff, decimalPlaces);
14 | };
15 |
16 | /**
17 | * Returns a copy of array, where each value will be in the range [0, 1].
18 | */
19 | export const mlNormalizeArray = (data: number[], min: number, max: number, decimalPlaces = Infinity): number[] => {
20 | const copy = [...data];
21 |
22 | for(let i=0; i {
30 | const min = Math.min(...data);
31 | const max = Math.max(...data);
32 | const _data = mlNormalizeArray(data, min, max, decimalPlaces);
33 |
34 | return {
35 | min: setDecimalPlaces(min, decimalPlaces),
36 | max: setDecimalPlaces(max, decimalPlaces),
37 | data: _data,
38 | };
39 | };
40 |
41 | /**
42 | * Alias.
43 | */
44 | export const mlNormalizeUnseenData = (data: number[], min: number, max: number, decimalPlaces = Infinity): number[] => {
45 | return mlNormalizeArray(data, min, max, decimalPlaces);
46 | };
47 |
48 | // --------------------- STANDARDIZE --------------------------------
49 |
50 | /**
51 | * Changes value to be in the range [-1, 1].
52 | */
53 | export const mlStandardizeValue = (value: number, mean: number, stdDev: number, decimalPlaces = Infinity) : number => {
54 | if(stdDev === 0) return 0;
55 | return setDecimalPlaces((value - mean) / stdDev, decimalPlaces);
56 | };
57 |
58 | /**
59 | * Returns a copy of array, where each value will be in the range [-1, 1].
60 | */
61 | export const mlStandardizeArray = (data: number[], mean: number, stdDev: number, decimalPlaces = Infinity) : number[] => {
62 | return [...data].map(value => mlStandardizeValue(value, mean, stdDev, decimalPlaces));
63 | };
64 |
65 | export const mlStandardizeTestData = (data: number[], decimalPlaces = Infinity): IMlStandardizeResult => {
66 | const mean = getArithmeticMean(data) ?? 0;
67 | const stdDev = getStandardDeviation(data);
68 | const _data = mlStandardizeArray(data, mean, stdDev, decimalPlaces);
69 |
70 | return {
71 | mean: setDecimalPlaces(mean, decimalPlaces),
72 | stdDev: setDecimalPlaces(stdDev, decimalPlaces),
73 | data: _data,
74 | };
75 | };
76 |
77 | /**
78 | * Alias.
79 | */
80 | export const mlStandardizeUnseenData = (data: number[], mean: number, stdDev: number, decimalPlaces = Infinity): number[] => {
81 | return mlStandardizeArray(data, mean, stdDev, decimalPlaces);
82 | };
--------------------------------------------------------------------------------
/src/main/other.ts:
--------------------------------------------------------------------------------
1 | import { Vector2 } from '../types';
2 | import { setDecimalPlaces } from './format';
3 |
4 | export const mod = (n: number, m: number) => {
5 | return ((n % m) + m) % m;
6 | };
7 |
8 | /**
9 | * Convert range [a, b] to [c, d].
10 | * f(x) = (d - c) * (x - a) / (b - a) + c
11 | */
12 | export const convertRange = (x: number, a: number, b: number, c: number, d: number) => {
13 | return (d - c) * (x - a) / (b - a) + c;
14 | };
15 |
16 | /**
17 | * Check if 2 ranges [a,b] and [c,d] overlap.
18 | */
19 | export const doRangesOverlap = (a: number, b: number, c: number, d: number) => {
20 | return Math.max(a, c) <= Math.min(b, d) ;
21 | };
22 |
23 | // eslint-disable-next-line
24 | export const isNumber = (value: any) => {
25 | return !isNaN(parseFloat(value)) && isFinite(value);
26 | };
27 |
28 | /**
29 | * Convert polar coordinates to cartesian coordinates.
30 | */
31 | export const polarToCartesian = (center: Vector2, radii: Vector2, angleInRad: number, decimalPlaces = Infinity) : Vector2 => {
32 | const [cx, cy] = center;
33 | const [rx, ry] = radii;
34 |
35 | return [
36 | setDecimalPlaces(cx + (rx * Math.cos(angleInRad)), decimalPlaces),
37 | setDecimalPlaces(cy + (ry * Math.sin(angleInRad)), decimalPlaces),
38 | ];
39 | };
40 |
41 | /**
42 | * Greatest common divisor (GCD) - Euclidean algorithm.
43 | * O( log(min(num1, num2)) ).
44 | *
45 | * GCD is always defined as a non-negative number.
46 | * If num2 is 0, then the GCD is num1.
47 | * Otherwise, the GCD of num1 and num2 is the same as the GCD of num2 and num1 % num2.
48 | *
49 | * a=48,𝑏=18 ---> 48 % 18 = 12
50 | * a=18,b=12 ---> 18 % 12 = 6
51 | * a=12,b=6 ---> 12 % 6 = 0
52 | * a=6,b=0 ---> result is 6
53 | */
54 | export const gcd = (num1: number, num2: number): number => {
55 | num1 = Math.abs(num1);
56 | num2 = Math.abs(num2);
57 |
58 | while (num2 !== 0) {
59 | const temp = num2;
60 | num2 = num1 % num2;
61 | num1 = temp;
62 | }
63 |
64 | return num1;
65 | };
--------------------------------------------------------------------------------
/src/main/physics.ts:
--------------------------------------------------------------------------------
1 | import { Vector2 } from '../types';
2 |
3 | /**
4 | * Speed = how far something moves in a given amount of time.
5 | * Speed is also a vector:
6 | * magnitude = distance
7 | * direction = time
8 | */
9 | export type Speed = Vector2;
10 |
11 | /**
12 | * Velocity is a measure of how fast an object is moving in a particular direction.
13 | * Velocity = Distance traveled / Time taken
14 | * It has a magnitude and direction, and can be represented as a vector.
15 | */
16 | export type Velocity = Vector2;
17 |
18 | /**
19 | * Acceleration is a measure of how quickly an object's velocity changes over time.
20 | * Acceleration = (Final velocity - Initial velocity) / Time taken
21 | * a = (vf - v0)/t.
22 | * Distance = Initial velocity * time + (acceleration * time^2) / 2
23 | * It also has a magnitude and direction, and can be represented as a vector.
24 | * When the direction is negative ----> it's a "slowdown" movement
25 | */
26 | export type Acceleration = Vector2;
27 |
28 | /**
29 | * Gravity is the force that attracts two objects with mass toward each other.
30 | * Newton's law of universal gravitation formula:
31 | * Gravitational force = (Gravitational constant * Mass of object 1 * Mass of object 2) / Distance between objects^2
32 | * It also has a magnitude and direction, and can be represented as a vector.
33 | * magnitude = the strength of the gravitational force
34 | * direction = the direction in which the force is acting (the direction of the gravitational force is always toward the center of mass of the objects involved)
35 | */
36 | export type Gravity = Vector2;
37 |
38 |
--------------------------------------------------------------------------------
/src/main/random.ts:
--------------------------------------------------------------------------------
1 | import { setDecimalPlaces } from './format';
2 |
3 | /**
4 | * Returns a random number in the [min,max] range.
5 | */
6 | export const getRandom = (min: number, max: number, decimalPlaces = Infinity): number => {
7 | return setDecimalPlaces(Math.random() * (max - min) + min, decimalPlaces);
8 | };
9 |
10 | /**
11 | * Returns a random integer number in the [min,max] range.
12 | */
13 | export const getRandomInt = (min: number, max: number): number => {
14 | return Math.floor(Math.random() * (max - min + 1) + min);
15 | };
16 |
17 | export const getRandomBoolean = () => Math.random() < 0.5;
18 |
19 | /* eslint-disable @typescript-eslint/no-explicit-any */
20 | export const getRandomItemFromArray = (array: any[]) => {
21 | const randomIndex = getRandomInt(0, array.length - 1);
22 | return array[randomIndex];
23 | };
--------------------------------------------------------------------------------
/src/main/sequence.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * 1 + 2 + ... + n = n * (n + 1) / 2
3 | */
4 | export const naturalNumbersSequenceSum = (n: number) => {
5 | return n * (n + 1) / 2;
6 | };
7 |
8 | /**
9 | * n = the number of terms to be added
10 | * a = the first term in the sequence
11 | * d = the constant value between terms
12 | */
13 | export const arithmeticSequenceSum = (n: number, a: number, d: number) => {
14 | return (n / 2) * (2 * a + (n - 1) * d);
15 | };
--------------------------------------------------------------------------------
/src/main/series.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Sum of 1 to n numbers:
3 | * (n * (n + 1)) / 2
4 | */
5 | export const naturalNumbersSum1ToN = (n: number): number => {
6 | return (n / 2) * (n + 1);
7 | };
8 |
9 | /**
10 | * Sum of m to n numbers.
11 | */
12 | export const naturalNumbersSumMToN = (m: number, n: number): number => {
13 | return (n - m + 1) * (m + n) / 2;
14 | };
--------------------------------------------------------------------------------
/src/main/temperature.ts:
--------------------------------------------------------------------------------
1 | import { setDecimalPlaces } from './format';
2 |
3 | export const celsiusToFahrenheit = (celsius: number, decimalPlaces = Infinity) => {
4 | return setDecimalPlaces(celsius * 1.80 + 32.00, decimalPlaces);
5 | };
6 |
7 | export const celsiusToKelvin = (celsius: number, decimalPlaces = Infinity) => {
8 | return setDecimalPlaces(celsius + 273.15, decimalPlaces);
9 | };
10 |
11 | export const fahrenheitToCelsius = (fahrenheit: number, decimalPlaces = Infinity) => {
12 | return setDecimalPlaces((fahrenheit - 32) * 5 / 9, decimalPlaces);
13 | };
14 |
15 | export const fahrenheitToKelvin = (fahrenheit: number, decimalPlaces = Infinity) => {
16 | return setDecimalPlaces((fahrenheit - 32) * 5 / 9 + 273.15, decimalPlaces);
17 | };
18 |
19 | export const kelvinToCelsius = (kelvin: number, decimalPlaces = Infinity) => {
20 | return setDecimalPlaces(kelvin - 273.15, decimalPlaces);
21 | };
22 |
23 | export const kelvinToFahrenheit = (kelvin: number, decimalPlaces = Infinity) => {
24 | return setDecimalPlaces((kelvin - 273.15) * 1.80 + 32, decimalPlaces);
25 | };
--------------------------------------------------------------------------------
/src/types.ts:
--------------------------------------------------------------------------------
1 | export type Vector2 = [number, number];
2 | export type Vector3 = [number, number, number];
3 | export type Vector4 = [number, number, number, number];
4 | export type Vector = number[];
5 |
6 | export type Matrix2 = Vector2[];
7 | export type Matrix3 = Vector3[];
8 | export type Matrix4 = Vector4[];
9 | export type Matrix = Vector[];
10 |
11 | export type HSLColor = [number, number, number]; // [hue, saturation, lightness] [0-360, 0-100, 0-100]
12 | export type RGBColor = [number, number, number]; // [r, g, b] [0, 255, 0, 255, 0, 255]
13 | export type LABColor = [number, number, number]; // [l, a, b] [0, 255, 0, 255, 0, 255] lab(29.2345%, 39.3825, 20.0664);
14 |
15 | export interface IBBox {
16 | x: number;
17 | y: number;
18 | w: number;
19 | h: number;
20 | x2: number;
21 | y2: number;
22 | }
23 |
24 | export interface IRect {
25 | x: number;
26 | y: number;
27 | w: number;
28 | h: number;
29 | }
30 |
31 | export interface ICircle {
32 | cx: number;
33 | cy: number;
34 | r: number;
35 | }
36 |
37 | export type IPolygon = Vector2[];
38 |
39 | export interface IMlStandardizeResult {
40 | mean: number;
41 | stdDev: number;
42 | data: number[];
43 | }
44 |
45 | export interface IMlNormalizeResult {
46 | min: number;
47 | max: number;
48 | data: number[];
49 | }
--------------------------------------------------------------------------------
/test/browser/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | TypeScript Math Helpers
6 |
7 |
8 |
9 |
10 |
15 |
16 |
--------------------------------------------------------------------------------
/test/circle-ellipse.test.ts:
--------------------------------------------------------------------------------
1 | import {
2 | getSquareInCircleSide,
3 | getCircleCircumference,
4 | getEllipseCircumference,
5 | isAngleInCircleArc,
6 | } from '../src/main/circle-ellipse';
7 |
8 | describe('Circle / Ellipse', () => {
9 |
10 | describe('getSquareInCircleSide()', () => {
11 | test('square side in circle with radius = 10', () => {
12 | expect(getSquareInCircleSide(10)).toStrictEqual(14.14213562373095);
13 | });
14 |
15 | test('square side in circle with radius = 10 and 2 decimal places', () => {
16 | expect(getSquareInCircleSide(10, 2)).toStrictEqual(14.14);
17 | });
18 | });
19 |
20 | describe('getCircleCircumference()', () => {
21 | test('getCircleCircumference(10)', () => {
22 | expect(getCircleCircumference(10, 2)).toStrictEqual(62.83);
23 | });
24 | });
25 |
26 | describe('getEllipseCircumference()', () => {
27 | test('getEllipseCircumference(10, 20)', () => {
28 | expect(getEllipseCircumference(10, 20, 2)).toStrictEqual(99.35);
29 | });
30 | });
31 |
32 | describe('isAngleInCircleArc()', () => {
33 | test('isAngleInCircleArc(0, 90, 45)', () => {
34 | expect(isAngleInCircleArc(0, 90, 45)).toStrictEqual(true);
35 | });
36 |
37 | test('isAngleInCircleArc(0, 90, 45)', () => {
38 | expect(isAngleInCircleArc(0, 90, 180)).toStrictEqual(false);
39 | });
40 | });
41 | });
--------------------------------------------------------------------------------
/test/convert.test.ts:
--------------------------------------------------------------------------------
1 | import { stringToNumber } from '../src/main/convert';
2 |
3 | describe('String to Number', () => {
4 | test('If undefined is provided => return the default value', () => {
5 | expect(stringToNumber(undefined, 10)).toStrictEqual(10);
6 | });
7 |
8 | test('If null is provided => return the default value', () => {
9 | expect(stringToNumber(null, 10)).toStrictEqual(10);
10 | });
11 |
12 | test('If 0 is provided => return 0', () => {
13 | expect(stringToNumber(0, 10)).toStrictEqual(0);
14 | });
15 |
16 | test('If "0" is provided => return 0', () => {
17 | expect(stringToNumber('0', 10)).toStrictEqual(0);
18 | });
19 |
20 | test('If "10.1234" is provided => return 10.1234', () => {
21 | expect(stringToNumber('10.1234', 10)).toStrictEqual(10.1234);
22 | });
23 |
24 | test('If "aaa" is provided => return the default value', () => {
25 | expect(stringToNumber('aaa', 20)).toStrictEqual(20);
26 | });
27 | });
--------------------------------------------------------------------------------
/test/derivative.test.ts:
--------------------------------------------------------------------------------
1 | import {
2 | dxPolynomial,
3 | dxSin,
4 | dxCos,
5 | dxTan,
6 | dxCot,
7 | dxArcSin,
8 | dxArcCos,
9 | dxArcTan,
10 | dxArcCot
11 | } from '../src/main/derivative';
12 |
13 | describe('Derivative', () => {
14 |
15 | describe('Polynomial', () => {
16 |
17 | test('y = 2, x = 5', () => {
18 | expect(dxPolynomial(5, [[2, 0]])).toStrictEqual(0);
19 | });
20 |
21 | test('y = 2x, x = 5', () => {
22 | expect(dxPolynomial(5, [[2, 1]])).toStrictEqual(2);
23 | });
24 |
25 | test('y = 5x^3 + 9x^2 + 7x + 3, x = 2', () => {
26 | expect(dxPolynomial(2, [[5, 3], [9, 2], [7, 1], [3, 0]])).toStrictEqual(103);
27 | });
28 |
29 | test('y = 3x+2, x = 10', () => {
30 | expect(dxPolynomial(10, [[3, 1], [2, 0]])).toStrictEqual(3);
31 | });
32 |
33 | test('y = 5x^3 + 9x^2 + 7x + 3, x = 2', () => {
34 | expect(dxPolynomial(2, [[5, 3], [9, 2], [7, 1], [3, 0]])).toStrictEqual(103);
35 | });
36 |
37 | test('y = 5x^(1/3), x = 2', () => {
38 | expect(dxPolynomial(2, [[5, 1/3]], 2)).toStrictEqual(1.05);
39 | });
40 |
41 | test('y = 5x^(-1/3), x = 2', () => {
42 | expect(dxPolynomial(2, [[5, -1/3]], 2)).toStrictEqual(-0.66);
43 | });
44 |
45 | });
46 |
47 | describe('Trigonometric Functions', () => {
48 |
49 | test('dxSin(Math.PI, 2)', () => {
50 | expect(dxSin(Math.PI, 2)).toStrictEqual(-1);
51 | });
52 |
53 | test('dxCos(Math.PI/2, 2)', () => {
54 | expect(dxCos(Math.PI/2, 2)).toStrictEqual(-1);
55 | });
56 |
57 | test('dxTan(Math.PI, 2)', () => {
58 | expect(dxTan(Math.PI, 2)).toStrictEqual(1);
59 | });
60 |
61 | test('dxCot(Math.PI/2, 2)', () => {
62 | expect(dxCot(Math.PI/2, 2)).toStrictEqual(-1);
63 | });
64 |
65 | test('dxArcSin(Math.PI/4, 2)', () => {
66 | expect(dxArcSin(Math.PI/4, 2)).toStrictEqual(1.62);
67 | });
68 |
69 | test('dxArcCos(Math.PI/4, 2)', () => {
70 | expect(dxArcCos(Math.PI/4, 2)).toStrictEqual(-1.62);
71 | });
72 |
73 | test('dxArcTan(Math.PI/4, 2)', () => {
74 | expect(dxArcTan(Math.PI/4, 2)).toStrictEqual(0.62);
75 | });
76 |
77 | test('dxArcCot(Math.PI/4, 2)', () => {
78 | expect(dxArcCot(Math.PI/4, 2)).toStrictEqual(-0.62);
79 | });
80 | });
81 |
82 | });
--------------------------------------------------------------------------------
/test/format.test.ts:
--------------------------------------------------------------------------------
1 | import { setDecimalPlaces } from '../src/main/format';
2 |
3 | describe('Set Decimal Places', () => {
4 | test('2 decimal places of 1.2345 => 1.23', () => {
5 | expect(setDecimalPlaces(1.2345, 2)).toStrictEqual(1.23);
6 | });
7 |
8 | test('2 decimal places of 1.2399 => 1.24', () => {
9 | expect(setDecimalPlaces(1.2399, 2)).toStrictEqual(1.24);
10 | });
11 |
12 | test('if parameter is Infinity => the value should not change', () => {
13 | expect(setDecimalPlaces(1.2399, Infinity)).toStrictEqual(1.2399);
14 | });
15 |
16 | test('if parameter is 0 => the value is integer', () => {
17 | expect(setDecimalPlaces(1.2399, 0)).toStrictEqual(1);
18 | });
19 |
20 | test('if parameter is negative => the value is integer', () => {
21 | expect(setDecimalPlaces(1.2399, -1)).toStrictEqual(1);
22 | });
23 |
24 | test('4 decimal places of 1.2399 => 1.2399', () => {
25 | expect(setDecimalPlaces(1.2399, 4)).toStrictEqual(1.2399);
26 | });
27 |
28 | test('provided number of decimal places > the real number of decimal places => the number should not change', () => {
29 | expect(setDecimalPlaces(1.2399, 10)).toStrictEqual(1.2399);
30 | });
31 |
32 | test('4 decimal places of 1.239999 => 1.2399', () => {
33 | expect(setDecimalPlaces(1.239999, 4)).toStrictEqual(1.24);
34 | });
35 |
36 | test('-4 with Infinite negative places', () => {
37 | expect(setDecimalPlaces(-4, Infinity)).toStrictEqual(-4);
38 | });
39 |
40 | test('-4.22222 with 2 negative places', () => {
41 | expect(setDecimalPlaces(-4.22222, 2)).toStrictEqual(-4.22);
42 | });
43 |
44 | });
--------------------------------------------------------------------------------
/test/linear-interpolation.test.ts:
--------------------------------------------------------------------------------
1 | import { lerp } from '../src/main/linear-interpolation';
2 |
3 | describe('Linear Interpolation', () => {
4 |
5 | test('lerp(5, 0, 100)', () => {
6 | expect(lerp(5, 0, 100)).toStrictEqual(500);
7 | });
8 | });
--------------------------------------------------------------------------------
/test/ml.test.ts:
--------------------------------------------------------------------------------
1 | import { mlNormalizeValue, mlStandardizeValue } from '../src/main/ml';
2 |
3 | describe('ML', () => {
4 |
5 | describe('mlNormalizeValue()', () => {
6 |
7 | it('10, 5, 5', () => {
8 | expect(mlNormalizeValue(10, 5, 5)).toBe(0);
9 | });
10 |
11 | it('10, 5, 15', () => {
12 | expect(mlNormalizeValue(10, 5, 15)).toBe(0.5);
13 | });
14 |
15 | it('10, 5, 15, 2', () => {
16 | expect(mlNormalizeValue(10, 5, 15, 2)).toBe(0.5);
17 | });
18 |
19 | it('10, -5, 15', () => {
20 | expect(mlNormalizeValue(10, -5, 15)).toBe(0.75);
21 | });
22 | });
23 |
24 | describe('mlStandardizeValue()', () => {
25 | it('10, 5, 0', () => {
26 | expect(mlStandardizeValue(10, 5, 0)).toStrictEqual(0);
27 | });
28 |
29 | it('10, 5, 2', () => {
30 | expect(mlStandardizeValue(10, 5, 2)).toStrictEqual(2.5);
31 | });
32 |
33 | it('10, 5, 2, 2', () => {
34 | expect(mlStandardizeValue(10, 5, 2, 2)).toStrictEqual(2.5);
35 | });
36 |
37 | it('10, -5, -2', () => {
38 | expect(mlStandardizeValue(10, -5, -2)).toStrictEqual(-7.5);
39 | });
40 | });
41 | });
--------------------------------------------------------------------------------
/test/sequence.test.ts:
--------------------------------------------------------------------------------
1 | import { naturalNumbersSequenceSum, arithmeticSequenceSum } from '../src/main/sequence';
2 |
3 | describe('Sequence', () => {
4 |
5 | describe('naturalNumbersSequenceSum()', () => {
6 |
7 | test('test numbers from 1 to', () => {
8 | expect(naturalNumbersSequenceSum(1)).toStrictEqual(1);
9 | expect(naturalNumbersSequenceSum(2)).toStrictEqual(3);
10 | expect(naturalNumbersSequenceSum(3)).toStrictEqual(6);
11 | expect(naturalNumbersSequenceSum(5)).toStrictEqual(15);
12 | expect(naturalNumbersSequenceSum(6)).toStrictEqual(21);
13 | });
14 | });
15 |
16 | describe('arithmeticSequenceSum()', () => {
17 | test('2 + 4 + 6 + 8', () => {
18 | expect(arithmeticSequenceSum(4, 2, 2)).toStrictEqual(20);
19 | });
20 | });
21 | });
--------------------------------------------------------------------------------
/test/series.test.ts:
--------------------------------------------------------------------------------
1 | import {
2 | naturalNumbersSum1ToN,
3 | naturalNumbersSumMToN,
4 | } from '../src/main/series';
5 |
6 | describe('Series', () => {
7 |
8 | describe('naturalNumbersSum1ToN()', () => {
9 | test('1', () => {
10 | expect(naturalNumbersSum1ToN(1)).toStrictEqual(1);
11 | });
12 |
13 | test('2', () => {
14 | expect(naturalNumbersSum1ToN(2)).toStrictEqual(3);
15 | });
16 |
17 | test('3', () => {
18 | expect(naturalNumbersSum1ToN(3)).toStrictEqual(6);
19 | });
20 | });
21 |
22 | describe('naturalNumbersSumMToN()', () => {
23 | test('1, 1', () => {
24 | expect(naturalNumbersSumMToN(1,1)).toStrictEqual(1);
25 | });
26 |
27 | test('5, 7', () => {
28 | expect(naturalNumbersSumMToN(5,7)).toStrictEqual(18);
29 | });
30 | });
31 | });
--------------------------------------------------------------------------------
/test/temperature.test.ts:
--------------------------------------------------------------------------------
1 | import {
2 | celsiusToFahrenheit,
3 | celsiusToKelvin,
4 | fahrenheitToCelsius,
5 | fahrenheitToKelvin,
6 | kelvinToCelsius,
7 | kelvinToFahrenheit,
8 | } from '../src/main/temperature';
9 |
10 | describe('Temperature Conversion', () => {
11 |
12 | describe('Celsius to Fahrenheit', () => {
13 | test('should convert 0°C to 32°F', () => {
14 | expect(celsiusToFahrenheit(0)).toStrictEqual(32);
15 | });
16 |
17 | test('should convert -40°C to -40°F', () => {
18 | expect(celsiusToFahrenheit(-40)).toStrictEqual(-40);
19 | });
20 |
21 | test('Test rounding', () => {
22 | expect(celsiusToFahrenheit(32.698034, 2)).toStrictEqual(90.86);
23 | });
24 | });
25 |
26 | describe('Celsius to Kelvin', () => {
27 | test('should convert 0°C to 273.15K', () => {
28 | expect(celsiusToKelvin(0)).toStrictEqual(273.15);
29 | });
30 |
31 | test('should convert -273.15°C to 0K', () => {
32 | expect(celsiusToKelvin(-273.15)).toStrictEqual(0);
33 | });
34 | });
35 |
36 | describe('Fahrenheit to Celsius', () => {
37 | test('should convert 32°F to 0°C', () => {
38 | expect(fahrenheitToCelsius(32)).toStrictEqual(0);
39 | });
40 |
41 | test('should convert -40°F to -40°C', () => {
42 | expect(fahrenheitToCelsius(-40)).toStrictEqual(-40);
43 | });
44 | });
45 |
46 | describe('Fahrenheit to Kelvin', () => {
47 | test('should convert 32°F to 273.15K', () => {
48 | expect(fahrenheitToKelvin(32)).toBeCloseTo(273.15);
49 | });
50 |
51 | test('should convert 212°F to 373.15K', () => {
52 | expect(fahrenheitToKelvin(212)).toBeCloseTo(373.15);
53 | });
54 | });
55 |
56 | describe('Kelvin to Celsius', () => {
57 | test('should convert 273.15K to 0°C', () => {
58 | expect(kelvinToCelsius(273.15)).toBeCloseTo(0);
59 | });
60 |
61 | test('should convert 0K to -273.15°C', () => {
62 | expect(kelvinToCelsius(0)).toBeCloseTo(-273.15);
63 | });
64 | });
65 |
66 | describe('Kelvin to Fahrenheit', () => {
67 | test('should convert 273.15K to 32°F', () => {
68 | expect(kelvinToFahrenheit(273.15)).toBeCloseTo(32);
69 | });
70 |
71 | test('should convert 373.15K to 212°F', () => {
72 | expect(kelvinToFahrenheit(373.15)).toBeCloseTo(212);
73 | });
74 | });
75 | });
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es6",
4 | "module": "es2015",
5 | "moduleResolution": "node",
6 | "outDir": "./types",
7 | "allowJs": true,
8 | "isolatedModules": true,
9 | "esModuleInterop": true,
10 | "useDefineForClassFields": true,
11 | "forceConsistentCasingInFileNames": true,
12 | "importHelpers": true,
13 | "suppressImplicitAnyIndexErrors": true,
14 | "declaration": true,
15 | "declarationMap": false,
16 | "noImplicitAny": true,
17 | "noImplicitReturns": true,
18 | "noImplicitThis": true,
19 | "noUnusedLocals": true,
20 | "noUnusedParameters": true,
21 | "noFallthroughCasesInSwitch": true,
22 | "strictNullChecks": true,
23 | "strictBindCallApply": true,
24 | "jsx": "react",
25 | "skipLibCheck": true
26 | },
27 | "include": [
28 | "src",
29 | ],
30 | "exclude": [
31 | "types",
32 | "node_modules",
33 | "dist",
34 | "**/*.test.ts"
35 | ]
36 | }
--------------------------------------------------------------------------------