├── .gitignore ├── demos ├── js │ └── Crossdominator.js ├── assets │ ├── Crossdominator.swf │ ├── transparentpattern.png │ └── demoStyles.css ├── css │ └── ui-darkness │ │ └── images │ │ ├── animated-overlay.gif │ │ ├── ui-icons_222222_256x240.png │ │ ├── ui-icons_4b8e0b_256x240.png │ │ ├── ui-icons_a83300_256x240.png │ │ ├── ui-icons_cccccc_256x240.png │ │ ├── ui-icons_ffffff_256x240.png │ │ ├── ui-bg_flat_30_cccccc_40x100.png │ │ ├── ui-bg_flat_50_5c5c5c_40x100.png │ │ ├── ui-bg_glass_20_555555_1x400.png │ │ ├── ui-bg_glass_40_0078a3_1x400.png │ │ ├── ui-bg_glass_40_ffc73d_1x400.png │ │ ├── ui-bg_inset-soft_25_000000_1x100.png │ │ ├── ui-bg_inset-soft_30_f58400_1x100.png │ │ ├── ui-bg_gloss-wave_25_333333_500x100.png │ │ └── ui-bg_highlight-soft_80_eeeeee_1x100.png ├── SteinerCircles.html ├── BalancingKDTree.html ├── UbiLabsKDTree.html ├── QuadraticBezierIntersection.html ├── CubicBezierIntersection.html ├── QuadraticCubicBezierIntersection.html ├── Vector2Cloud.html ├── SoddyCircles.html └── CrossdominatorDemo.html ├── docs ├── fonts │ ├── OpenSans-Bold-webfont.eot │ ├── OpenSans-Bold-webfont.woff │ ├── OpenSans-Light-webfont.eot │ ├── OpenSans-Italic-webfont.eot │ ├── OpenSans-Italic-webfont.woff │ ├── OpenSans-Light-webfont.woff │ ├── OpenSans-Regular-webfont.eot │ ├── OpenSans-Regular-webfont.woff │ ├── OpenSans-BoldItalic-webfont.eot │ ├── OpenSans-BoldItalic-webfont.woff │ ├── OpenSans-LightItalic-webfont.eot │ └── OpenSans-LightItalic-webfont.woff ├── app │ └── 1.0.0 │ │ ├── fonts │ │ ├── OpenSans-Bold-webfont.eot │ │ ├── OpenSans-Bold-webfont.woff │ │ ├── OpenSans-Light-webfont.eot │ │ ├── OpenSans-Italic-webfont.eot │ │ ├── OpenSans-Italic-webfont.woff │ │ ├── OpenSans-Light-webfont.woff │ │ ├── OpenSans-Regular-webfont.eot │ │ ├── OpenSans-Regular-webfont.woff │ │ ├── OpenSans-BoldItalic-webfont.eot │ │ ├── OpenSans-BoldItalic-webfont.woff │ │ ├── OpenSans-LightItalic-webfont.eot │ │ └── OpenSans-LightItalic-webfont.woff │ │ ├── scripts │ │ ├── linenumber.js │ │ └── prettify │ │ │ └── lang-css.js │ │ ├── styles │ │ ├── prettify-jsdoc.css │ │ ├── prettify-tomorrow.css │ │ └── jsdoc-default.css │ │ ├── index.html │ │ ├── geom_MixedPathPoint.js.html │ │ ├── geom_GeometricShape.js.html │ │ ├── events_Event.js.html │ │ ├── Point.html │ │ ├── geom_SteinerCircles.js.html │ │ ├── geom_Point.js.html │ │ ├── Vector2.html │ │ ├── geom_Rectangle.js.html │ │ ├── ui_Handle.js.html │ │ └── geom_Bezier2.js.html ├── scripts │ ├── linenumber.js │ └── prettify │ │ └── lang-css.js ├── index.html ├── styles │ ├── prettify-jsdoc.css │ ├── prettify-tomorrow.css │ └── jsdoc-default.css ├── Point.html └── Point.js.html ├── jsdoc.json ├── package.json ├── README.md └── src └── qlib ├── math ├── PRNG.js ├── SimplexNoise.js └── CovarianceMatrix2.js ├── utils └── MathUtils.js ├── geom ├── PolygonUtils.js ├── MixedPathPoint.js ├── GeometricShape.js ├── TriangleUtils.js ├── Delaunay.js ├── Point.js └── Vector3D.js └── events └── Event.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | -------------------------------------------------------------------------------- /demos/js/Crossdominator.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Quasimondo/QuasimondoLibsJS/HEAD/demos/js/Crossdominator.js -------------------------------------------------------------------------------- /demos/assets/Crossdominator.swf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Quasimondo/QuasimondoLibsJS/HEAD/demos/assets/Crossdominator.swf -------------------------------------------------------------------------------- /demos/assets/transparentpattern.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Quasimondo/QuasimondoLibsJS/HEAD/demos/assets/transparentpattern.png -------------------------------------------------------------------------------- /docs/fonts/OpenSans-Bold-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Quasimondo/QuasimondoLibsJS/HEAD/docs/fonts/OpenSans-Bold-webfont.eot -------------------------------------------------------------------------------- /docs/fonts/OpenSans-Bold-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Quasimondo/QuasimondoLibsJS/HEAD/docs/fonts/OpenSans-Bold-webfont.woff -------------------------------------------------------------------------------- /docs/fonts/OpenSans-Light-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Quasimondo/QuasimondoLibsJS/HEAD/docs/fonts/OpenSans-Light-webfont.eot -------------------------------------------------------------------------------- /docs/fonts/OpenSans-Italic-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Quasimondo/QuasimondoLibsJS/HEAD/docs/fonts/OpenSans-Italic-webfont.eot -------------------------------------------------------------------------------- /docs/fonts/OpenSans-Italic-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Quasimondo/QuasimondoLibsJS/HEAD/docs/fonts/OpenSans-Italic-webfont.woff -------------------------------------------------------------------------------- /docs/fonts/OpenSans-Light-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Quasimondo/QuasimondoLibsJS/HEAD/docs/fonts/OpenSans-Light-webfont.woff -------------------------------------------------------------------------------- /docs/fonts/OpenSans-Regular-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Quasimondo/QuasimondoLibsJS/HEAD/docs/fonts/OpenSans-Regular-webfont.eot -------------------------------------------------------------------------------- /docs/fonts/OpenSans-Regular-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Quasimondo/QuasimondoLibsJS/HEAD/docs/fonts/OpenSans-Regular-webfont.woff -------------------------------------------------------------------------------- /docs/fonts/OpenSans-BoldItalic-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Quasimondo/QuasimondoLibsJS/HEAD/docs/fonts/OpenSans-BoldItalic-webfont.eot -------------------------------------------------------------------------------- /docs/fonts/OpenSans-BoldItalic-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Quasimondo/QuasimondoLibsJS/HEAD/docs/fonts/OpenSans-BoldItalic-webfont.woff -------------------------------------------------------------------------------- /docs/fonts/OpenSans-LightItalic-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Quasimondo/QuasimondoLibsJS/HEAD/docs/fonts/OpenSans-LightItalic-webfont.eot -------------------------------------------------------------------------------- /docs/fonts/OpenSans-LightItalic-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Quasimondo/QuasimondoLibsJS/HEAD/docs/fonts/OpenSans-LightItalic-webfont.woff -------------------------------------------------------------------------------- /docs/app/1.0.0/fonts/OpenSans-Bold-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Quasimondo/QuasimondoLibsJS/HEAD/docs/app/1.0.0/fonts/OpenSans-Bold-webfont.eot -------------------------------------------------------------------------------- /docs/app/1.0.0/fonts/OpenSans-Bold-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Quasimondo/QuasimondoLibsJS/HEAD/docs/app/1.0.0/fonts/OpenSans-Bold-webfont.woff -------------------------------------------------------------------------------- /docs/app/1.0.0/fonts/OpenSans-Light-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Quasimondo/QuasimondoLibsJS/HEAD/docs/app/1.0.0/fonts/OpenSans-Light-webfont.eot -------------------------------------------------------------------------------- /demos/css/ui-darkness/images/animated-overlay.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Quasimondo/QuasimondoLibsJS/HEAD/demos/css/ui-darkness/images/animated-overlay.gif -------------------------------------------------------------------------------- /docs/app/1.0.0/fonts/OpenSans-Italic-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Quasimondo/QuasimondoLibsJS/HEAD/docs/app/1.0.0/fonts/OpenSans-Italic-webfont.eot -------------------------------------------------------------------------------- /docs/app/1.0.0/fonts/OpenSans-Italic-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Quasimondo/QuasimondoLibsJS/HEAD/docs/app/1.0.0/fonts/OpenSans-Italic-webfont.woff -------------------------------------------------------------------------------- /docs/app/1.0.0/fonts/OpenSans-Light-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Quasimondo/QuasimondoLibsJS/HEAD/docs/app/1.0.0/fonts/OpenSans-Light-webfont.woff -------------------------------------------------------------------------------- /docs/app/1.0.0/fonts/OpenSans-Regular-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Quasimondo/QuasimondoLibsJS/HEAD/docs/app/1.0.0/fonts/OpenSans-Regular-webfont.eot -------------------------------------------------------------------------------- /docs/app/1.0.0/fonts/OpenSans-Regular-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Quasimondo/QuasimondoLibsJS/HEAD/docs/app/1.0.0/fonts/OpenSans-Regular-webfont.woff -------------------------------------------------------------------------------- /docs/app/1.0.0/fonts/OpenSans-BoldItalic-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Quasimondo/QuasimondoLibsJS/HEAD/docs/app/1.0.0/fonts/OpenSans-BoldItalic-webfont.eot -------------------------------------------------------------------------------- /docs/app/1.0.0/fonts/OpenSans-BoldItalic-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Quasimondo/QuasimondoLibsJS/HEAD/docs/app/1.0.0/fonts/OpenSans-BoldItalic-webfont.woff -------------------------------------------------------------------------------- /docs/app/1.0.0/fonts/OpenSans-LightItalic-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Quasimondo/QuasimondoLibsJS/HEAD/docs/app/1.0.0/fonts/OpenSans-LightItalic-webfont.eot -------------------------------------------------------------------------------- /docs/app/1.0.0/fonts/OpenSans-LightItalic-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Quasimondo/QuasimondoLibsJS/HEAD/docs/app/1.0.0/fonts/OpenSans-LightItalic-webfont.woff -------------------------------------------------------------------------------- /demos/css/ui-darkness/images/ui-icons_222222_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Quasimondo/QuasimondoLibsJS/HEAD/demos/css/ui-darkness/images/ui-icons_222222_256x240.png -------------------------------------------------------------------------------- /demos/css/ui-darkness/images/ui-icons_4b8e0b_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Quasimondo/QuasimondoLibsJS/HEAD/demos/css/ui-darkness/images/ui-icons_4b8e0b_256x240.png -------------------------------------------------------------------------------- /demos/css/ui-darkness/images/ui-icons_a83300_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Quasimondo/QuasimondoLibsJS/HEAD/demos/css/ui-darkness/images/ui-icons_a83300_256x240.png -------------------------------------------------------------------------------- /demos/css/ui-darkness/images/ui-icons_cccccc_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Quasimondo/QuasimondoLibsJS/HEAD/demos/css/ui-darkness/images/ui-icons_cccccc_256x240.png -------------------------------------------------------------------------------- /demos/css/ui-darkness/images/ui-icons_ffffff_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Quasimondo/QuasimondoLibsJS/HEAD/demos/css/ui-darkness/images/ui-icons_ffffff_256x240.png -------------------------------------------------------------------------------- /demos/css/ui-darkness/images/ui-bg_flat_30_cccccc_40x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Quasimondo/QuasimondoLibsJS/HEAD/demos/css/ui-darkness/images/ui-bg_flat_30_cccccc_40x100.png -------------------------------------------------------------------------------- /demos/css/ui-darkness/images/ui-bg_flat_50_5c5c5c_40x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Quasimondo/QuasimondoLibsJS/HEAD/demos/css/ui-darkness/images/ui-bg_flat_50_5c5c5c_40x100.png -------------------------------------------------------------------------------- /demos/css/ui-darkness/images/ui-bg_glass_20_555555_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Quasimondo/QuasimondoLibsJS/HEAD/demos/css/ui-darkness/images/ui-bg_glass_20_555555_1x400.png -------------------------------------------------------------------------------- /demos/css/ui-darkness/images/ui-bg_glass_40_0078a3_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Quasimondo/QuasimondoLibsJS/HEAD/demos/css/ui-darkness/images/ui-bg_glass_40_0078a3_1x400.png -------------------------------------------------------------------------------- /demos/css/ui-darkness/images/ui-bg_glass_40_ffc73d_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Quasimondo/QuasimondoLibsJS/HEAD/demos/css/ui-darkness/images/ui-bg_glass_40_ffc73d_1x400.png -------------------------------------------------------------------------------- /demos/css/ui-darkness/images/ui-bg_inset-soft_25_000000_1x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Quasimondo/QuasimondoLibsJS/HEAD/demos/css/ui-darkness/images/ui-bg_inset-soft_25_000000_1x100.png -------------------------------------------------------------------------------- /demos/css/ui-darkness/images/ui-bg_inset-soft_30_f58400_1x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Quasimondo/QuasimondoLibsJS/HEAD/demos/css/ui-darkness/images/ui-bg_inset-soft_30_f58400_1x100.png -------------------------------------------------------------------------------- /demos/css/ui-darkness/images/ui-bg_gloss-wave_25_333333_500x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Quasimondo/QuasimondoLibsJS/HEAD/demos/css/ui-darkness/images/ui-bg_gloss-wave_25_333333_500x100.png -------------------------------------------------------------------------------- /demos/css/ui-darkness/images/ui-bg_highlight-soft_80_eeeeee_1x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Quasimondo/QuasimondoLibsJS/HEAD/demos/css/ui-darkness/images/ui-bg_highlight-soft_80_eeeeee_1x100.png -------------------------------------------------------------------------------- /jsdoc.json: -------------------------------------------------------------------------------- 1 | { 2 | "tags": { 3 | "allowUnknownTags": true 4 | }, 5 | "source": { 6 | "include": ["src/qlib", "README.md"], 7 | "includePattern": ".+\\.js(doc)?$", 8 | "exclude": ["src/qlib/geom/Delaunay.js"], 9 | "excludePattern": "(^|\\/|\\\\)node_modules(\\/|\\\\|$)" 10 | }, 11 | "plugins": [], 12 | "opts": { 13 | "encoding": "utf8", 14 | "destination": "./docs/", 15 | "recurse": true, 16 | "verbose": true, 17 | "package": "package.json" 18 | }, 19 | "sourceType": "module" 20 | } 21 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "app", 3 | "version": "1.0.0", 4 | "description": "QuasimondoLibsJS ================", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "docs": "jsdoc -c jsdoc.json" 9 | }, 10 | "repository": { 11 | "type": "git", 12 | "url": "git+https://github.com/Quasimondo/QuasimondoLibsJS.git" 13 | }, 14 | "keywords": [], 15 | "author": "", 16 | "license": "ISC", 17 | "bugs": { 18 | "url": "https://github.com/Quasimondo/QuasimondoLibsJS/issues" 19 | }, 20 | "homepage": "https://github.com/Quasimondo/QuasimondoLibsJS#readme", 21 | "devDependencies": { 22 | "docdash": "^2.0.2", 23 | "jsdoc": "^4.0.4" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /docs/scripts/linenumber.js: -------------------------------------------------------------------------------- 1 | /*global document */ 2 | (() => { 3 | const source = document.getElementsByClassName('prettyprint source linenums'); 4 | let i = 0; 5 | let lineNumber = 0; 6 | let lineId; 7 | let lines; 8 | let totalLines; 9 | let anchorHash; 10 | 11 | if (source && source[0]) { 12 | anchorHash = document.location.hash.substring(1); 13 | lines = source[0].getElementsByTagName('li'); 14 | totalLines = lines.length; 15 | 16 | for (; i < totalLines; i++) { 17 | lineNumber++; 18 | lineId = `line${lineNumber}`; 19 | lines[i].id = lineId; 20 | if (lineId === anchorHash) { 21 | lines[i].className += ' selected'; 22 | } 23 | } 24 | } 25 | })(); 26 | -------------------------------------------------------------------------------- /docs/app/1.0.0/scripts/linenumber.js: -------------------------------------------------------------------------------- 1 | /*global document */ 2 | (() => { 3 | const source = document.getElementsByClassName('prettyprint source linenums'); 4 | let i = 0; 5 | let lineNumber = 0; 6 | let lineId; 7 | let lines; 8 | let totalLines; 9 | let anchorHash; 10 | 11 | if (source && source[0]) { 12 | anchorHash = document.location.hash.substring(1); 13 | lines = source[0].getElementsByTagName('li'); 14 | totalLines = lines.length; 15 | 16 | for (; i < totalLines; i++) { 17 | lineNumber++; 18 | lineId = `line${lineNumber}`; 19 | lines[i].id = lineId; 20 | if (lineId === anchorHash) { 21 | lines[i].className += ' selected'; 22 | } 23 | } 24 | } 25 | })(); 26 | -------------------------------------------------------------------------------- /docs/scripts/prettify/lang-css.js: -------------------------------------------------------------------------------- 1 | PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\f\r ]+/,null," \t\r\n "]],[["str",/^"(?:[^\n\f\r"\\]|\\(?:\r\n?|\n|\f)|\\[\S\s])*"/,null],["str",/^'(?:[^\n\f\r'\\]|\\(?:\r\n?|\n|\f)|\\[\S\s])*'/,null],["lang-css-str",/^url\(([^"')]*)\)/i],["kwd",/^(?:url|rgb|!important|@import|@page|@media|@charset|inherit)(?=[^\w-]|$)/i,null],["lang-css-kw",/^(-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*)\s*:/i],["com",/^\/\*[^*]*\*+(?:[^*/][^*]*\*+)*\//],["com", 2 | /^(?:<\!--|--\>)/],["lit",/^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i],["lit",/^#[\da-f]{3,6}/i],["pln",/^-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*/i],["pun",/^[^\s\w"']+/]]),["css"]);PR.registerLangHandler(PR.createSimpleLexer([],[["kwd",/^-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*/i]]),["css-kw"]);PR.registerLangHandler(PR.createSimpleLexer([],[["str",/^[^"')]+/]]),["css-str"]); 3 | -------------------------------------------------------------------------------- /docs/app/1.0.0/scripts/prettify/lang-css.js: -------------------------------------------------------------------------------- 1 | PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\f\r ]+/,null," \t\r\n "]],[["str",/^"(?:[^\n\f\r"\\]|\\(?:\r\n?|\n|\f)|\\[\S\s])*"/,null],["str",/^'(?:[^\n\f\r'\\]|\\(?:\r\n?|\n|\f)|\\[\S\s])*'/,null],["lang-css-str",/^url\(([^"')]*)\)/i],["kwd",/^(?:url|rgb|!important|@import|@page|@media|@charset|inherit)(?=[^\w-]|$)/i,null],["lang-css-kw",/^(-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*)\s*:/i],["com",/^\/\*[^*]*\*+(?:[^*/][^*]*\*+)*\//],["com", 2 | /^(?:<\!--|--\>)/],["lit",/^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i],["lit",/^#[\da-f]{3,6}/i],["pln",/^-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*/i],["pun",/^[^\s\w"']+/]]),["css"]);PR.registerLangHandler(PR.createSimpleLexer([],[["kwd",/^-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*/i]]),["css-kw"]);PR.registerLangHandler(PR.createSimpleLexer([],[["str",/^[^"')]+/]]),["css-str"]); 3 | -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | JSDoc: Home 6 | 7 | 8 | 9 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 |

Home

21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 |

30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 |
51 | 52 | 55 | 56 |
57 | 58 | 61 | 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /demos/assets/demoStyles.css: -------------------------------------------------------------------------------- 1 | /*Stylesheet*/ 2 | 3 | BODY, HTML { 4 | margin: 0; 5 | padding: 0; 6 | font-family: Arial, Verdana, sans-serif; 7 | font-size: 12px; 8 | font-weight: normal; 9 | color: #ccc; 10 | background-color: #333; 11 | } 12 | 13 | BODY {} 14 | 15 | 16 | p { 17 | margin: 10px 0; 18 | } 19 | 20 | a:link, a:visited { 21 | color: #e7841d; 22 | font-weight: bold; 23 | } 24 | a:hover { 25 | } 26 | 27 | #header { 28 | padding: 20px; 29 | background-color: #222; 30 | } 31 | #header h1 { 32 | font-weight: normal; 33 | font-size: 24px; 34 | margin: 0; 35 | padding: 0; 36 | } 37 | 38 | #header p { 39 | margin: 0; 40 | padding: 0; 41 | 42 | font-size: 14px; 43 | color: #777; 44 | } 45 | 46 | #header:after{ 47 | content: ""; 48 | position: absolute; 49 | } 50 | 51 | 52 | .content { 53 | 54 | padding: 10px; 55 | 56 | 57 | 58 | color: #777; 59 | 60 | border: 1px solid #555; 61 | background-color: #000; 62 | } 63 | 64 | #loader { 65 | display: none; 66 | } 67 | .loader { 68 | width: 100%; 69 | height: 50px; 70 | position: absolute; 71 | text-align:center; 72 | margin-top: 250px; 73 | background: url('loader.gif') no-repeat; 74 | background-position: 50% 50%; 75 | display: block !important; 76 | } 77 | 78 | #error { 79 | display:none; 80 | width: 960px; 81 | text-align: left; 82 | padding: 10px; 83 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | QuasimondoLibsJS 2 | ================ 3 | 4 | QuasimondoLibsJS is a JavaScript library primarily focused on 2D geometry operations and algorithms. It is a migration of the original ActionScript QuasimondoLibs. 5 | 6 | For some drawing functionalities and UI elements, Qlib can integrate with EaselJS, but EaselJS is not required for core geometric operations. Many intersection algorithms are based on work by Kevin Lindsey. 7 | 8 | Detailed API documentation, generated from source code comments, is available to help you understand and use the library. 9 | 10 | ## Documentation 11 | 12 | This project uses [JSDoc](https://jsdoc.app/) to generate API documentation from source code comments. 13 | 14 | To build the documentation: 15 | 1. Ensure you have Node.js and npm installed. 16 | 2. Install development dependencies: `npm install` 17 | 3. Generate the documentation: `npm run docs` 18 | 19 | The generated documentation will be available in the `docs` directory. Open `docs/index.html` (or `docs/app/1.0.0/index.html` depending on your JSDoc setup) in your browser to view it. 20 | 21 | ## Original Notes 22 | 23 | Migrating the original QuasimondoLibs to Javascript. Mostly 2D Geometry. 24 | 25 | For the drawing part and some of the UI elements Qlib uses EaselJS - for 26 | pure geometric operation it is not required though. 27 | 28 | A big part of the intersection algorithms and their helper methods (most of which I still have to port from my ActionScript library) 29 | were originally taken from Kevin Lindsey: http://www.kevlindev.com/gui/math/intersection/index.htm 30 | -------------------------------------------------------------------------------- /src/qlib/math/PRNG.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Park-Miller-Carta Pseudo-Random Number Generator 3 | * 4 | * Original code by Peter Nitsch - https://github.com/pnitsch/BitmapData.js 5 | * HTML5 Canvas API implementation of the AS3 BitmapData class. 6 | * 7 | * adapted and augmented by Mario Klingemann for qlib 8 | * 9 | * Permission is hereby granted, free of charge, to any person 10 | * obtaining a copy of this software and associated documentation 11 | * files (the "Software"), to deal in the Software without 12 | * restriction, including without limitation the rights to use, 13 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | * copies of the Software, and to permit persons to whom the 15 | * Software is furnished to do so, subject to the following 16 | * conditions: 17 | * 18 | * The above copyright notice and this permission notice shall be 19 | * included in all copies or substantial portions of the Software. 20 | * 21 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 22 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 23 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 24 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 25 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 26 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 27 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 28 | * OTHER DEALINGS IN THE SOFTWARE. 29 | */ 30 | 31 | // namespace: 32 | window["qlib"] = window.qlib || {}; 33 | 34 | (function() { 35 | 36 | var PRNG = function() 37 | { 38 | this.seed = 1; 39 | }; 40 | 41 | var p = PRNG.prototype; 42 | 43 | p.next = function() { return (this.gen() / 2147483647); }; 44 | p.nextRange = function(min, max) { return min + ((max - min) * this.next()) }; 45 | p.gen = function() { return this.seed = (this.seed * 16807) % 2147483647; }; 46 | 47 | qlib["PRNG"] = PRNG; 48 | 49 | }()); -------------------------------------------------------------------------------- /docs/styles/prettify-jsdoc.css: -------------------------------------------------------------------------------- 1 | /* JSDoc prettify.js theme */ 2 | 3 | /* plain text */ 4 | .pln { 5 | color: #000000; 6 | font-weight: normal; 7 | font-style: normal; 8 | } 9 | 10 | /* string content */ 11 | .str { 12 | color: #006400; 13 | font-weight: normal; 14 | font-style: normal; 15 | } 16 | 17 | /* a keyword */ 18 | .kwd { 19 | color: #000000; 20 | font-weight: bold; 21 | font-style: normal; 22 | } 23 | 24 | /* a comment */ 25 | .com { 26 | font-weight: normal; 27 | font-style: italic; 28 | } 29 | 30 | /* a type name */ 31 | .typ { 32 | color: #000000; 33 | font-weight: normal; 34 | font-style: normal; 35 | } 36 | 37 | /* a literal value */ 38 | .lit { 39 | color: #006400; 40 | font-weight: normal; 41 | font-style: normal; 42 | } 43 | 44 | /* punctuation */ 45 | .pun { 46 | color: #000000; 47 | font-weight: bold; 48 | font-style: normal; 49 | } 50 | 51 | /* lisp open bracket */ 52 | .opn { 53 | color: #000000; 54 | font-weight: bold; 55 | font-style: normal; 56 | } 57 | 58 | /* lisp close bracket */ 59 | .clo { 60 | color: #000000; 61 | font-weight: bold; 62 | font-style: normal; 63 | } 64 | 65 | /* a markup tag name */ 66 | .tag { 67 | color: #006400; 68 | font-weight: normal; 69 | font-style: normal; 70 | } 71 | 72 | /* a markup attribute name */ 73 | .atn { 74 | color: #006400; 75 | font-weight: normal; 76 | font-style: normal; 77 | } 78 | 79 | /* a markup attribute value */ 80 | .atv { 81 | color: #006400; 82 | font-weight: normal; 83 | font-style: normal; 84 | } 85 | 86 | /* a declaration */ 87 | .dec { 88 | color: #000000; 89 | font-weight: bold; 90 | font-style: normal; 91 | } 92 | 93 | /* a variable name */ 94 | .var { 95 | color: #000000; 96 | font-weight: normal; 97 | font-style: normal; 98 | } 99 | 100 | /* a function name */ 101 | .fun { 102 | color: #000000; 103 | font-weight: bold; 104 | font-style: normal; 105 | } 106 | 107 | /* Specify class=linenums on a pre to get line numbering */ 108 | ol.linenums { 109 | margin-top: 0; 110 | margin-bottom: 0; 111 | } 112 | -------------------------------------------------------------------------------- /docs/app/1.0.0/styles/prettify-jsdoc.css: -------------------------------------------------------------------------------- 1 | /* JSDoc prettify.js theme */ 2 | 3 | /* plain text */ 4 | .pln { 5 | color: #000000; 6 | font-weight: normal; 7 | font-style: normal; 8 | } 9 | 10 | /* string content */ 11 | .str { 12 | color: #006400; 13 | font-weight: normal; 14 | font-style: normal; 15 | } 16 | 17 | /* a keyword */ 18 | .kwd { 19 | color: #000000; 20 | font-weight: bold; 21 | font-style: normal; 22 | } 23 | 24 | /* a comment */ 25 | .com { 26 | font-weight: normal; 27 | font-style: italic; 28 | } 29 | 30 | /* a type name */ 31 | .typ { 32 | color: #000000; 33 | font-weight: normal; 34 | font-style: normal; 35 | } 36 | 37 | /* a literal value */ 38 | .lit { 39 | color: #006400; 40 | font-weight: normal; 41 | font-style: normal; 42 | } 43 | 44 | /* punctuation */ 45 | .pun { 46 | color: #000000; 47 | font-weight: bold; 48 | font-style: normal; 49 | } 50 | 51 | /* lisp open bracket */ 52 | .opn { 53 | color: #000000; 54 | font-weight: bold; 55 | font-style: normal; 56 | } 57 | 58 | /* lisp close bracket */ 59 | .clo { 60 | color: #000000; 61 | font-weight: bold; 62 | font-style: normal; 63 | } 64 | 65 | /* a markup tag name */ 66 | .tag { 67 | color: #006400; 68 | font-weight: normal; 69 | font-style: normal; 70 | } 71 | 72 | /* a markup attribute name */ 73 | .atn { 74 | color: #006400; 75 | font-weight: normal; 76 | font-style: normal; 77 | } 78 | 79 | /* a markup attribute value */ 80 | .atv { 81 | color: #006400; 82 | font-weight: normal; 83 | font-style: normal; 84 | } 85 | 86 | /* a declaration */ 87 | .dec { 88 | color: #000000; 89 | font-weight: bold; 90 | font-style: normal; 91 | } 92 | 93 | /* a variable name */ 94 | .var { 95 | color: #000000; 96 | font-weight: normal; 97 | font-style: normal; 98 | } 99 | 100 | /* a function name */ 101 | .fun { 102 | color: #000000; 103 | font-weight: bold; 104 | font-style: normal; 105 | } 106 | 107 | /* Specify class=linenums on a pre to get line numbering */ 108 | ol.linenums { 109 | margin-top: 0; 110 | margin-bottom: 0; 111 | } 112 | -------------------------------------------------------------------------------- /src/qlib/utils/MathUtils.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Circle 3 | * 4 | * Copyright (c) 2013 Mario Klingemann 5 | * 6 | * Permission is hereby granted, free of charge, to any person 7 | * obtaining a copy of this software and associated documentation 8 | * files (the "Software"), to deal in the Software without 9 | * restriction, including without limitation the rights to use, 10 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the 12 | * Software is furnished to do so, subject to the following 13 | * conditions: 14 | * 15 | * The above copyright notice and this permission notice shall be 16 | * included in all copies or substantial portions of the Software. 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 19 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 20 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 21 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 22 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 23 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 24 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 25 | * OTHER DEALINGS IN THE SOFTWARE. 26 | */ 27 | 28 | // namespace: 29 | window["qlib"] = window.qlib || {}; 30 | 31 | (function() { 32 | 33 | var MathUtils = function() {} 34 | 35 | // static methods: 36 | MathUtils.GLSL = function( m) 37 | { 38 | var q, i, j, k; 39 | for ( j = 0; j < 3; j++) 40 | { 41 | q = m[ j * 5 ]; 42 | 43 | if (q == 0) 44 | { 45 | for ( i = j + 1; i < 3; i++) 46 | { 47 | if ( m [ i * 4 + j ] != 0 ) 48 | { 49 | for ( k = 0; k < 4; k++) 50 | { 51 | m[ j * 4 + k] += m[ i * 4 + k ]; 52 | } 53 | q = m[ j * 5 ]; 54 | break; 55 | } 56 | } 57 | } 58 | 59 | if (q != 0) 60 | { 61 | for ( k = 0; k < 4; k++) 62 | { 63 | m[j * 4 + k] = m[j * 4 + k] / q; 64 | } 65 | } 66 | 67 | for ( i = 0; i < 3; i++) 68 | { 69 | if ( i != j ) 70 | { 71 | q = m[ i * 4 + j ]; 72 | for ( k=0; k < 4; k++) 73 | { 74 | m[ i * 4 + k] -= q * m[j * 4 + k]; 75 | } 76 | } 77 | } 78 | } 79 | 80 | } 81 | 82 | qlib["MathUtils"] = MathUtils; 83 | }()); -------------------------------------------------------------------------------- /docs/styles/prettify-tomorrow.css: -------------------------------------------------------------------------------- 1 | /* Tomorrow Theme */ 2 | /* Original theme - https://github.com/chriskempson/tomorrow-theme */ 3 | /* Pretty printing styles. Used with prettify.js. */ 4 | /* SPAN elements with the classes below are added by prettyprint. */ 5 | /* plain text */ 6 | .pln { 7 | color: #4d4d4c; } 8 | 9 | @media screen { 10 | /* string content */ 11 | .str { 12 | color: #718c00; } 13 | 14 | /* a keyword */ 15 | .kwd { 16 | color: #8959a8; } 17 | 18 | /* a comment */ 19 | .com { 20 | color: #8e908c; } 21 | 22 | /* a type name */ 23 | .typ { 24 | color: #4271ae; } 25 | 26 | /* a literal value */ 27 | .lit { 28 | color: #f5871f; } 29 | 30 | /* punctuation */ 31 | .pun { 32 | color: #4d4d4c; } 33 | 34 | /* lisp open bracket */ 35 | .opn { 36 | color: #4d4d4c; } 37 | 38 | /* lisp close bracket */ 39 | .clo { 40 | color: #4d4d4c; } 41 | 42 | /* a markup tag name */ 43 | .tag { 44 | color: #c82829; } 45 | 46 | /* a markup attribute name */ 47 | .atn { 48 | color: #f5871f; } 49 | 50 | /* a markup attribute value */ 51 | .atv { 52 | color: #3e999f; } 53 | 54 | /* a declaration */ 55 | .dec { 56 | color: #f5871f; } 57 | 58 | /* a variable name */ 59 | .var { 60 | color: #c82829; } 61 | 62 | /* a function name */ 63 | .fun { 64 | color: #4271ae; } } 65 | /* Use higher contrast and text-weight for printable form. */ 66 | @media print, projection { 67 | .str { 68 | color: #060; } 69 | 70 | .kwd { 71 | color: #006; 72 | font-weight: bold; } 73 | 74 | .com { 75 | color: #600; 76 | font-style: italic; } 77 | 78 | .typ { 79 | color: #404; 80 | font-weight: bold; } 81 | 82 | .lit { 83 | color: #044; } 84 | 85 | .pun, .opn, .clo { 86 | color: #440; } 87 | 88 | .tag { 89 | color: #006; 90 | font-weight: bold; } 91 | 92 | .atn { 93 | color: #404; } 94 | 95 | .atv { 96 | color: #060; } } 97 | /* Style */ 98 | /* 99 | pre.prettyprint { 100 | background: white; 101 | font-family: Consolas, Monaco, 'Andale Mono', monospace; 102 | font-size: 12px; 103 | line-height: 1.5; 104 | border: 1px solid #ccc; 105 | padding: 10px; } 106 | */ 107 | 108 | /* Specify class=linenums on a pre to get line numbering */ 109 | ol.linenums { 110 | margin-top: 0; 111 | margin-bottom: 0; } 112 | 113 | /* IE indents via margin-left */ 114 | li.L0, 115 | li.L1, 116 | li.L2, 117 | li.L3, 118 | li.L4, 119 | li.L5, 120 | li.L6, 121 | li.L7, 122 | li.L8, 123 | li.L9 { 124 | /* */ } 125 | 126 | /* Alternate shading for lines */ 127 | li.L1, 128 | li.L3, 129 | li.L5, 130 | li.L7, 131 | li.L9 { 132 | /* */ } 133 | -------------------------------------------------------------------------------- /docs/app/1.0.0/styles/prettify-tomorrow.css: -------------------------------------------------------------------------------- 1 | /* Tomorrow Theme */ 2 | /* Original theme - https://github.com/chriskempson/tomorrow-theme */ 3 | /* Pretty printing styles. Used with prettify.js. */ 4 | /* SPAN elements with the classes below are added by prettyprint. */ 5 | /* plain text */ 6 | .pln { 7 | color: #4d4d4c; } 8 | 9 | @media screen { 10 | /* string content */ 11 | .str { 12 | color: #718c00; } 13 | 14 | /* a keyword */ 15 | .kwd { 16 | color: #8959a8; } 17 | 18 | /* a comment */ 19 | .com { 20 | color: #8e908c; } 21 | 22 | /* a type name */ 23 | .typ { 24 | color: #4271ae; } 25 | 26 | /* a literal value */ 27 | .lit { 28 | color: #f5871f; } 29 | 30 | /* punctuation */ 31 | .pun { 32 | color: #4d4d4c; } 33 | 34 | /* lisp open bracket */ 35 | .opn { 36 | color: #4d4d4c; } 37 | 38 | /* lisp close bracket */ 39 | .clo { 40 | color: #4d4d4c; } 41 | 42 | /* a markup tag name */ 43 | .tag { 44 | color: #c82829; } 45 | 46 | /* a markup attribute name */ 47 | .atn { 48 | color: #f5871f; } 49 | 50 | /* a markup attribute value */ 51 | .atv { 52 | color: #3e999f; } 53 | 54 | /* a declaration */ 55 | .dec { 56 | color: #f5871f; } 57 | 58 | /* a variable name */ 59 | .var { 60 | color: #c82829; } 61 | 62 | /* a function name */ 63 | .fun { 64 | color: #4271ae; } } 65 | /* Use higher contrast and text-weight for printable form. */ 66 | @media print, projection { 67 | .str { 68 | color: #060; } 69 | 70 | .kwd { 71 | color: #006; 72 | font-weight: bold; } 73 | 74 | .com { 75 | color: #600; 76 | font-style: italic; } 77 | 78 | .typ { 79 | color: #404; 80 | font-weight: bold; } 81 | 82 | .lit { 83 | color: #044; } 84 | 85 | .pun, .opn, .clo { 86 | color: #440; } 87 | 88 | .tag { 89 | color: #006; 90 | font-weight: bold; } 91 | 92 | .atn { 93 | color: #404; } 94 | 95 | .atv { 96 | color: #060; } } 97 | /* Style */ 98 | /* 99 | pre.prettyprint { 100 | background: white; 101 | font-family: Consolas, Monaco, 'Andale Mono', monospace; 102 | font-size: 12px; 103 | line-height: 1.5; 104 | border: 1px solid #ccc; 105 | padding: 10px; } 106 | */ 107 | 108 | /* Specify class=linenums on a pre to get line numbering */ 109 | ol.linenums { 110 | margin-top: 0; 111 | margin-bottom: 0; } 112 | 113 | /* IE indents via margin-left */ 114 | li.L0, 115 | li.L1, 116 | li.L2, 117 | li.L3, 118 | li.L4, 119 | li.L5, 120 | li.L6, 121 | li.L7, 122 | li.L8, 123 | li.L9 { 124 | /* */ } 125 | 126 | /* Alternate shading for lines */ 127 | li.L1, 128 | li.L3, 129 | li.L5, 130 | li.L7, 131 | li.L9 { 132 | /* */ } 133 | -------------------------------------------------------------------------------- /demos/SteinerCircles.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | QuasimondoLibsJS Demo: Steiner Circles 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 96 | 97 | 98 | 99 | 100 | 104 | 105 | 106 | 107 | 108 | -------------------------------------------------------------------------------- /demos/BalancingKDTree.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | QuasimondoLibsJS Demo: Balancing KDTree - Find Closest Point (2000 Points) 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 90 | 91 | 92 | 93 | 94 | 98 | 99 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /demos/UbiLabsKDTree.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | QuasimondoLibsJS Demo: UbiLabs KDTree - Find Closest Points (20 from 4000 Points) 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 99 | 100 | 101 | 102 | 103 | 107 | 108 | 109 | 110 | 111 | -------------------------------------------------------------------------------- /docs/app/1.0.0/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | JSDoc: Home 6 | 7 | 8 | 9 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 |

Home

21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 |

app 1.0.0

30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 |
46 |

QuasimondoLibsJS

47 |

Migrating the original QuasimondoLibs to Javascript. Mostly 2D Geometry.

48 |

For the drawing part and some of the UI elements Qlib uses EaselJS - for 49 | pure geometric operation it is not required though.

50 |

A big part of the intersection algorithms and their helper methods (most of which I still have to port from my ActionScript library) 51 | were originally taken from Kevin Lindsey: http://www.kevlindev.com/gui/math/intersection/index.htm

52 |
53 | 54 | 55 | 56 | 57 | 58 | 59 |
60 | 61 | 64 | 65 |
66 | 67 | 70 | 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /demos/QuadraticBezierIntersection.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | QuasimondoLibsJS Demo: Quadratic Bezier/Quadratic Bezier Intersection 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 93 | 94 | 95 | 96 | 97 | 101 | 102 | 103 | 104 | 105 | -------------------------------------------------------------------------------- /demos/CubicBezierIntersection.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | QuasimondoLibsJS Demo: Cubic Bezier/Cubic Bezier Intersection 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 93 | 94 | 95 | 96 | 97 | 101 | 102 | 103 | 104 | 105 | -------------------------------------------------------------------------------- /demos/QuadraticCubicBezierIntersection.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | QuasimondoLibsJS Demo: Quadratic Bezier/Cubic Bezier Intersection 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 94 | 95 | 96 | 97 | 98 | 102 | 103 | 104 | 105 | 106 | -------------------------------------------------------------------------------- /demos/Vector2Cloud.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | QuasimondoLibsJS Demo: Vector2Cloud 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 107 | 108 | 109 | 110 | 111 | 115 | 116 | 117 | 118 | 119 | -------------------------------------------------------------------------------- /src/qlib/geom/PolygonUtils.js: -------------------------------------------------------------------------------- 1 | /* 2 | * PolygonUtils 3 | * 4 | * Copyright (c) 2013 Mario Klingemann 5 | * 6 | * Permission is hereby granted, free of charge, to any person 7 | * obtaining a copy of this software and associated documentation 8 | * files (the "Software"), to deal in the Software without 9 | * restriction, including without limitation the rights to use, 10 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the 12 | * Software is furnished to do so, subject to the following 13 | * conditions: 14 | * 15 | * The above copyright notice and this permission notice shall be 16 | * included in all copies or substantial portions of the Software. 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 19 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 20 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 21 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 22 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 23 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 24 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 25 | * OTHER DEALINGS IN THE SOFTWARE. 26 | */ 27 | 28 | // namespace: 29 | window["qlib"] = window.qlib || {}; 30 | 31 | (function() { 32 | 33 | /** 34 | * A utility class providing static helper methods for operations related to `qlib.Polygon` objects. 35 | * This class is not intended to be instantiated. 36 | * @class PolygonUtils 37 | * @memberof qlib 38 | */ 39 | var PolygonUtils = function() { 40 | // Static class, not meant to be instantiated. 41 | throw new Error("PolygonUtils cannot be instantiated."); 42 | } 43 | 44 | // static methods: 45 | /** 46 | * Creates a smoothed version of a given polygon, returned as a `qlib.MixedPath`. 47 | * This is achieved by converting the polygon to a `qlib.LinearPath` and then calling 48 | * its `getSmoothPath` method. The resulting path is treated as closed. 49 | * 50 | * @static 51 | * @method getSmoothPath 52 | * @param {qlib.Polygon} polygon - The polygon to smooth. 53 | * @param {number} factor - The smoothing factor. Its interpretation depends on the `mode`. 54 | * @param {number} [mode=0] - The smoothing mode, corresponding to constants in `qlib.LinearPath` 55 | * (e.g., `qlib.LinearPath.SMOOTH_PATH_RELATIVE_EDGEWISE`). Defaults to 0. 56 | * @returns {qlib.MixedPath} A new `qlib.MixedPath` instance representing the smoothed polygon. 57 | * @see qlib.LinearPath#getSmoothPath 58 | * @see qlib.LinearPath.SMOOTH_PATH_RELATIVE_EDGEWISE 59 | * @see qlib.LinearPath.SMOOTH_PATH_ABSOLUTE_EDGEWISE 60 | * @see qlib.LinearPath.SMOOTH_PATH_RELATIVE_MINIMUM 61 | * @see qlib.LinearPath.SMOOTH_PATH_ABSOLUTE_MINIMUM 62 | */ 63 | PolygonUtils.getSmoothPath = function( polygon, factor, mode) 64 | { 65 | if ( mode == null ) mode = 0; // Corresponds to qlib.LinearPath.SMOOTH_PATH_RELATIVE_EDGEWISE 66 | // Polygon.toArray() returns a copy of points. clonePoints=true ensures they are new Vector2 instances for the LinearPath. 67 | return qlib.LinearPath.fromArray( polygon.toArray(true), false ).getSmoothPath( factor, mode, true ); // Pass true for clonePoints to fromArray if points should be cloned, then false to fromArray itself. 68 | // The polygon.toArray(true) already clones. So, fromArray's clonePoints can be false. 69 | } 70 | 71 | qlib["PolygonUtils"] = PolygonUtils; 72 | }()); -------------------------------------------------------------------------------- /src/qlib/geom/MixedPathPoint.js: -------------------------------------------------------------------------------- 1 | /** 2 | * MixedPath Point 3 | * 4 | * Copyright (c) 2013 Mario Klingemann 5 | * 6 | * Permission is hereby granted, free of charge, to any person 7 | * obtaining a copy of this software and associated documentation 8 | * files (the "Software"), to deal in the Software without 9 | * restriction, including without limitation the rights to use, 10 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the 12 | * Software is furnished to do so, subject to the following 13 | * conditions: 14 | * 15 | * The above copyright notice and this permission notice shall be 16 | * included in all copies or substantial portions of the Software. 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 19 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 20 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 21 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 22 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 23 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 24 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 25 | * OTHER DEALINGS IN THE SOFTWARE. 26 | */ 27 | 28 | // namespace: 29 | window["qlib"] = window.qlib || {}; 30 | 31 | (function() { 32 | 33 | /** 34 | * Represents a point within a `qlib.MixedPath`. 35 | * It extends `qlib.Vector2` and adds a flag to distinguish between 36 | * anchor points (vertices of the path) and control points (used for Bezier curves). 37 | * 38 | * @class MixedPathPoint 39 | * @extends qlib.Vector2 40 | * @memberof qlib 41 | * @constructor 42 | * @param {qlib.Vector2} point - The `qlib.Vector2` instance whose coordinates will be used for this point. 43 | * The x and y values are copied. 44 | * @param {boolean} [isControlPoint=false] - True if this point is a control point, false if it's an anchor point. 45 | */ 46 | var MixedPathPoint = function( point, isControlPoint ) { 47 | this.initialize( point, isControlPoint ); 48 | } 49 | 50 | var p = MixedPathPoint.prototype = new qlib.Vector2(); 51 | 52 | // public properties: 53 | /** 54 | * The type of this object. 55 | * @property {string} type 56 | * @default "MixedPathPoint" 57 | */ 58 | p.type = "MixedPathPoint"; 59 | 60 | /** 61 | * Flag indicating whether this point is a control point (true) or an anchor point (false). 62 | * Anchor points define the main vertices of the path segments, while control points 63 | * influence the curvature of Bezier segments. 64 | * @property {boolean} isControlPoint 65 | * @default false 66 | */ 67 | p.isControlPoint = false; 68 | 69 | 70 | // constructor: 71 | /** 72 | * Initialization method called by the constructor. 73 | * Sets the x and y coordinates from the provided `point` object and the `isControlPoint` flag. 74 | * Calls the superclass (`qlib.Vector2`) initialize method. 75 | * @method initialize 76 | * @protected 77 | * @param {qlib.Vector2} point - The `qlib.Vector2` to copy coordinates from. 78 | * @param {boolean} [isControlPoint=false] - Whether this point is a control point. 79 | * @returns {void} 80 | */ 81 | p.initialize = function( point, isControlPoint ) 82 | { 83 | // Call superclass initialize. Vector2's initialize can take a Vector2 as its first arg in an array. 84 | qlib.Vector2.prototype.initialize.call(this, [point]); 85 | this.isControlPoint = isControlPoint || false; 86 | } 87 | 88 | /** 89 | * Returns a string representation of this MixedPathPoint. 90 | * Format: "x|y" for anchor points, "x|y|c" for control points. 91 | * @method toString 92 | * @return {string} A string representation of the instance. 93 | **/ 94 | p.toString = function() { 95 | return this.x + "|" + this.y + ( this.isControlPoint ? "|c":"" ); 96 | } 97 | 98 | qlib["MixedPathPoint"] = MixedPathPoint; 99 | }()); -------------------------------------------------------------------------------- /src/qlib/math/SimplexNoise.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Ported from Stefan Gustavson's java implementation 3 | * http://staffwww.itn.liu.se/~stegu/simplexnoise/simplexnoise.pdf 4 | * Sean McCullough banksean@gmail.com 5 | * 6 | * Original JS code by Peter Nitsch - https://github.com/pnitsch/BitmapData.js 7 | * HTML5 Canvas API implementation of the AS3 BitmapData class. 8 | * 9 | * adapted and augmented by Mario Klingemann for qlib 10 | * 11 | * Permission is hereby granted, free of charge, to any person 12 | * obtaining a copy of this software and associated documentation 13 | * files (the "Software"), to deal in the Software without 14 | * restriction, including without limitation the rights to use, 15 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 16 | * copies of the Software, and to permit persons to whom the 17 | * Software is furnished to do so, subject to the following 18 | * conditions: 19 | * 20 | * The above copyright notice and this permission notice shall be 21 | * included in all copies or substantial portions of the Software. 22 | * 23 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 25 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 26 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 27 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 28 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 29 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 30 | * OTHER DEALINGS IN THE SOFTWARE. 31 | */ 32 | 33 | // namespace: 34 | window["qlib"] = window.qlib || {}; 35 | 36 | (function() { 37 | 38 | var SimplexNoise = function(gen) { 39 | this.rand = gen; 40 | 41 | }; 42 | 43 | SimplexNoise.grad3 = [ 44 | [1,1,0],[-1,1,0],[1,-1,0],[-1,-1,0], 45 | [1,0,1],[-1,0,1],[1,0,-1],[-1,0,-1], 46 | [0,1,1],[0,-1,1],[0,1,-1],[0,-1,-1] 47 | ]; 48 | 49 | SimplexNoise.simplex = [ 50 | [0,1,2,3],[0,1,3,2],[0,0,0,0],[0,2,3,1],[0,0,0,0],[0,0,0,0],[0,0,0,0],[1,2,3,0], 51 | [0,2,1,3],[0,0,0,0],[0,3,1,2],[0,3,2,1],[0,0,0,0],[0,0,0,0],[0,0,0,0],[1,3,2,0], 52 | [0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0], 53 | [1,2,0,3],[0,0,0,0],[1,3,0,2],[0,0,0,0],[0,0,0,0],[0,0,0,0],[2,3,0,1],[2,3,1,0], 54 | [1,0,2,3],[1,0,3,2],[0,0,0,0],[0,0,0,0],[0,0,0,0],[2,0,3,1],[0,0,0,0],[2,1,3,0], 55 | [0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0], 56 | [2,0,1,3],[0,0,0,0],[0,0,0,0],[0,0,0,0],[3,0,1,2],[3,0,2,1],[0,0,0,0],[3,1,2,0], 57 | [2,1,0,3],[0,0,0,0],[0,0,0,0],[0,0,0,0],[3,1,0,2],[0,0,0,0],[3,2,0,1],[3,2,1,0] 58 | ]; 59 | 60 | SimplexNoise.F2 = 0.5*(Math.sqrt(3.0)-1.0); 61 | SimplexNoise.G2 = (3.0-Math.sqrt(3.0))/6.0; 62 | 63 | var p = SimplexNoise.prototype; 64 | 65 | p.setSeed = function(seed) { 66 | this.p = []; 67 | this.rand.seed = seed; 68 | 69 | for (var i=0; i<256; i++) { 70 | this.p[i] = (this.rand.nextRange(0, 255) | 0); 71 | } 72 | 73 | this.perm = []; 74 | for(var i=0; i<512; i++) { 75 | this.perm[i]=this.p[i & 255]; 76 | } 77 | } 78 | 79 | p.noise = function(xin, yin) { 80 | var n0, n1, n2; 81 | 82 | var s = (xin+yin)*SimplexNoise.F2; 83 | var i = (xin+s) | 0; 84 | var j = (yin+s) | 0; 85 | 86 | var t = (i+j)*SimplexNoise.G2; 87 | var X0 = i-t; 88 | var Y0 = j-t; 89 | var x0 = xin-X0; 90 | var y0 = yin-Y0; 91 | 92 | var i1, j1; 93 | if(x0>y0) {i1=1; j1=0;} 94 | else {i1=0; j1=1;} 95 | 96 | var x1 = x0 - i1 + SimplexNoise.G2; 97 | var y1 = y0 - j1 + SimplexNoise.G2; 98 | var x2 = x0 - 1.0 + 2.0 * SimplexNoise.G2; 99 | var y2 = y0 - 1.0 + 2.0 * SimplexNoise.G2; 100 | 101 | var ii = i & 255; 102 | var jj = j & 255; 103 | var gi0 = SimplexNoise.grad3[this.perm[ii+this.perm[jj]] % 12]; 104 | var gi1 = SimplexNoise.grad3[this.perm[ii+i1+this.perm[jj+j1]] % 12]; 105 | var gi2 = SimplexNoise.grad3[this.perm[ii+1+this.perm[jj+1]] % 12]; 106 | 107 | var t0 = 0.5 - x0*x0-y0*y0; 108 | if(t0<0) n0 = 0.0; 109 | else { 110 | t0 *= t0; 111 | n0 = t0 * t0 * (gi0[0]*x0 + gi0[1]*y0); 112 | } 113 | 114 | var t1 = 0.5 - x1*x1-y1*y1; 115 | if(t1<0) n1 = 0.0; 116 | else { 117 | t1 *= t1; 118 | n1 = t1 * t1 * (gi1[0]*x1 + gi1[1]*y1); 119 | } 120 | var t2 = 0.5 - x2*x2-y2*y2; 121 | if(t2<0) n2 = 0.0; 122 | else { 123 | t2 *= t2; 124 | n2 = t2 * t2 * (gi2[0]*x2 + gi2[1]*y2); 125 | } 126 | 127 | return 70.0 * (n0 + n1 + n2); 128 | }; 129 | 130 | qlib["SimplexNoise"] = SimplexNoise; 131 | 132 | }()); -------------------------------------------------------------------------------- /demos/SoddyCircles.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | QuasimondoLibsJS Demo: Soddy Circles 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 22 | 23 | 137 | 138 | 139 | 140 | 141 | 145 | 146 | 147 | 148 | 149 | -------------------------------------------------------------------------------- /docs/app/1.0.0/geom_MixedPathPoint.js.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | JSDoc: Source: geom/MixedPathPoint.js 6 | 7 | 8 | 9 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 |

Source: geom/MixedPathPoint.js

21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 |
29 |
/**
 30 | * MixedPath Point
 31 | *
 32 | * Copyright (c) 2013 Mario Klingemann
 33 | *
 34 | * Permission is hereby granted, free of charge, to any person
 35 | * obtaining a copy of this software and associated documentation
 36 | * files (the "Software"), to deal in the Software without
 37 | * restriction, including without limitation the rights to use,
 38 | * copy, modify, merge, publish, distribute, sublicense, and/or sell
 39 | * copies of the Software, and to permit persons to whom the
 40 | * Software is furnished to do so, subject to the following
 41 | * conditions:
 42 | *
 43 | * The above copyright notice and this permission notice shall be
 44 | * included in all copies or substantial portions of the Software.
 45 | *
 46 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 47 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 48 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 49 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 50 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 51 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 52 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 53 | * OTHER DEALINGS IN THE SOFTWARE.
 54 | */
 55 | 
 56 | // namespace:
 57 | window["qlib"] = window.qlib || {};
 58 | 
 59 | (function() {
 60 | 
 61 | var MixedPathPoint = function( point, isControlPoint ) {
 62 |   this.initialize( point, isControlPoint );
 63 | }
 64 | 
 65 | var p = MixedPathPoint.prototype = new qlib.Vector2();
 66 | 
 67 | // public properties:
 68 | 	p.type = "MixedPathPoint";
 69 | 
 70 | 
 71 | 	// constructor:
 72 | 	/**
 73 | 	 * Initialization method.
 74 | 	 * @method initialize
 75 | 	 * @protected
 76 | 	*/
 77 | 	p.initialize = function( point, isControlPoint )
 78 | 	{
 79 | 		qlib.Vector2.prototype.initialize.call(this, [point]);
 80 | 		this.isControlPoint = isControlPoint || false;
 81 | 	}
 82 | 
 83 | 	/**
 84 | 	 * Returns a string representation of this object.
 85 | 	 * @method toString
 86 | 	 * @return {String} a string representation of the instance.
 87 | 	 **/
 88 | 	p.toString = function() {
 89 | 		return this.x + "|" + this.y + ( this.isControlPoint ? "|c":"" );
 90 | 	}
 91 | 
 92 | 	qlib["MixedPathPoint"] = MixedPathPoint;
 93 | }());
94 |
95 |
96 | 97 | 98 | 99 | 100 |
101 | 102 | 105 | 106 |
107 | 108 | 111 | 112 | 113 | 114 | 115 | 116 | -------------------------------------------------------------------------------- /src/qlib/events/Event.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Event 3 | * Visit http://createjs.com/ for documentation, updates and examples. 4 | * 5 | * Copyright (c) 2010 gskinner.com, inc. 6 | * 7 | * Permission is hereby granted, free of charge, to any person 8 | * obtaining a copy of this software and associated documentation 9 | * files (the "Software"), to deal in the Software without 10 | * restriction, including without limitation the rights to use, 11 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | * copies of the Software, and to permit persons to whom the 13 | * Software is furnished to do so, subject to the following 14 | * conditions: 15 | * 16 | * The above copyright notice and this permission notice shall be 17 | * included in all copies or substantial portions of the Software. 18 | * 19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 20 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 21 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 22 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 23 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 24 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 25 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 26 | * OTHER DEALINGS IN THE SOFTWARE. 27 | */ 28 | 29 | // namespace: 30 | window["qlib"] = window.qlib || {}; 31 | 32 | (function() { 33 | 34 | /** 35 | * Represents a basic event dispatched by an object. 36 | * Event instances are passed as parameters to event listeners when an event occurs. 37 | * This class is a fundamental part of the event handling mechanism in qlib, 38 | * often used in conjunction with `qlib.EventDispatcher`. 39 | * 40 | * For example, `qlib.DisplayObject` instances might dispatch `Event` objects (or subclasses of `Event`) 41 | * for interactions like clicks or mouse movements. 42 | * 43 | * While this base `Event` class includes `EventDispatcher` methods through a mixin, 44 | * `Event` instances themselves are typically not used to dispatch further events. 45 | * Rather, they are data objects that carry information about an occurrence. 46 | * 47 | * @class Event 48 | * @constructor 49 | * @param {string} type - The type of the event (e.g., "click", "complete"). This string is used to identify the event. 50 | * @param {Object} target - The object that dispatched the event. This is often the `this` reference from the dispatcher. 51 | * @see qlib.EventDispatcher 52 | * @see qlib.DisplayObject 53 | */ 54 | var Event = function(type, target) { 55 | this.initialize(type, target); 56 | } 57 | var p = Event.prototype; 58 | 59 | // properties: 60 | 61 | /** 62 | * The type of the event (e.g., "click", "complete"). 63 | * This string is used to identify the specific event that occurred. 64 | * @property {string} type 65 | **/ 66 | p.type = null; 67 | 68 | 69 | /** 70 | * The object that dispatched the event. 71 | * This is the source of the event, often an instance of a class that uses `qlib.EventDispatcher`. 72 | * For example, if a `DisplayObject` dispatches an event, `target` would be that `DisplayObject`. 73 | * @property {Object} target 74 | * @default null 75 | */ 76 | p.target = null; 77 | 78 | 79 | 80 | // mix-ins: 81 | // EventDispatcher methods are mixed in, but typically not used on Event instances themselves. 82 | // These are more relevant for classes that *dispatch* events. 83 | p.addEventListener = null; 84 | p.removeEventListener = null; 85 | p.removeAllEventListeners = null; 86 | p.dispatchEvent = null; 87 | p.hasEventListener = null; 88 | p._listeners = null; 89 | qlib.EventDispatcher.initialize(p); // inject EventDispatcher methods. 90 | 91 | // constructor: 92 | /** 93 | * Initializes the Event instance with the specified type and target. 94 | * This method is called by the constructor. 95 | * @method initialize 96 | * @protected 97 | * @param {string} type - The type of the event. 98 | * @param {Object} target - The object that dispatched the event. 99 | * @returns {void} 100 | **/ 101 | p.initialize = function(type, target) { 102 | this.type = type; 103 | this.target = target; 104 | 105 | } 106 | 107 | // public methods: 108 | /** 109 | * Creates and returns a new Event instance that is a shallow copy of this event object. 110 | * The `target` property is a direct reference copy, not a deep clone. 111 | * 112 | * @method clone 113 | * @return {qlib.Event} A new Event instance with the same `type` and `target` as this one. 114 | **/ 115 | p.clone = function() { 116 | return new qlib.Event(this.type, this.target); 117 | } 118 | 119 | /** 120 | * Returns a string representation of this Event object. 121 | * Format: "[Event (type=EVENT_TYPE)]" 122 | * 123 | * @method toString 124 | * @return {string} A string representation of the Event instance. 125 | **/ 126 | p.toString = function() { 127 | return "[Event (type="+this.type+")]"; 128 | } 129 | 130 | qlib["Event"] = Event; 131 | }()); -------------------------------------------------------------------------------- /docs/app/1.0.0/geom_GeometricShape.js.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | JSDoc: Source: geom/GeometricShape.js 6 | 7 | 8 | 9 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 |

Source: geom/GeometricShape.js

21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 |
29 |
/*
 30 | * Circle
 31 | *
 32 | * Copyright (c) 2013 Mario Klingemann
 33 | *
 34 | * Permission is hereby granted, free of charge, to any person
 35 | * obtaining a copy of this software and associated documentation
 36 | * files (the "Software"), to deal in the Software without
 37 | * restriction, including without limitation the rights to use,
 38 | * copy, modify, merge, publish, distribute, sublicense, and/or sell
 39 | * copies of the Software, and to permit persons to whom the
 40 | * Software is furnished to do so, subject to the following
 41 | * conditions:
 42 | *
 43 | * The above copyright notice and this permission notice shall be
 44 | * included in all copies or substantial portions of the Software.
 45 | *
 46 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 47 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 48 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 49 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 50 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 51 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 52 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 53 | * OTHER DEALINGS IN THE SOFTWARE.
 54 | */
 55 | 
 56 | // namespace:
 57 | window["qlib"] = window.qlib || {};
 58 | 
 59 | (function() {
 60 | 
 61 | var GeometricShape = function() {
 62 | 
 63 | }
 64 | var p = GeometricShape.prototype;
 65 | 
 66 | // public properties:
 67 | 
 68 | 	p.type = "GeometricShape";
 69 | 
 70 | 	/**
 71 | 	 * Returns a string representation of this object.
 72 | 	 * @method toString
 73 | 	 * @return {String} a string representation of the instance.
 74 | 	 **/
 75 | 	p.intersect = function( s ) {
 76 | 		return qlib.Intersection.intersect( this, s );
 77 | 	}
 78 | 
 79 | 	p.draw = function( graphics )
 80 | 	{
 81 | 		throw("draw() not implented yet in "+this.type);
 82 | 	}
 83 | 
 84 | 	p.scale = function( factorX, factorY, center )
 85 | 	{
 86 | 		throw("scale() not implented yet in "+this.type);
 87 | 	}
 88 | 
 89 | 	p.clone = function( deepClone )
 90 | 	{
 91 | 		throw("clone() not implented yet in "+this.type);
 92 | 	}
 93 | 
 94 | 
 95 | 	/**
 96 | 	 * Returns a string representation of this object.
 97 | 	 * @method toString
 98 | 	 * @return {String} a string representation of the instance.
 99 | 	 **/
100 | 	p.toString = function() {
101 | 		return this.type;
102 | 	}
103 | 
104 | 	qlib["GeometricShape"] = GeometricShape;
105 | }());
106 |
107 |
108 | 109 | 110 | 111 | 112 |
113 | 114 | 117 | 118 |
119 | 120 | 123 | 124 | 125 | 126 | 127 | 128 | -------------------------------------------------------------------------------- /src/qlib/geom/GeometricShape.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Circle 3 | * 4 | * Copyright (c) 2013 Mario Klingemann 5 | * 6 | * Permission is hereby granted, free of charge, to any person 7 | * obtaining a copy of this software and associated documentation 8 | * files (the "Software"), to deal in the Software without 9 | * restriction, including without limitation the rights to use, 10 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the 12 | * Software is furnished to do so, subject to the following 13 | * conditions: 14 | * 15 | * The above copyright notice and this permission notice shall be 16 | * included in all copies or substantial portions of the Software. 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 19 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 20 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 21 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 22 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 23 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 24 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 25 | * OTHER DEALINGS IN THE SOFTWARE. 26 | */ 27 | 28 | // namespace: 29 | window["qlib"] = window.qlib || {}; 30 | 31 | (function() { 32 | 33 | /** 34 | * An abstract base class or interface for various geometric shapes within the qlib library. 35 | * It defines a common structure and placeholder methods that concrete shapes should implement. 36 | * Subclasses are expected to override methods like `draw`, `scale`, and `clone`, 37 | * and set their specific `type`. 38 | * 39 | * @class GeometricShape 40 | * @memberof qlib 41 | * @constructor 42 | */ 43 | var GeometricShape = function() { 44 | // Constructor is typically empty for abstract-like base classes in JS, 45 | // or initializes common properties. 46 | } 47 | var p = GeometricShape.prototype; 48 | 49 | // public properties: 50 | 51 | /** 52 | * A string identifier for the type of the geometric shape. 53 | * Subclasses should override this property (e.g., "Circle", "Rectangle"). 54 | * @property {string} type 55 | * @default "GeometricShape" 56 | */ 57 | p.type = "GeometricShape"; 58 | 59 | /** 60 | * Computes the intersection between this geometric shape and another. 61 | * This method delegates the actual intersection calculation to `qlib.Intersection.intersect`. 62 | * 63 | * @method intersect 64 | * @param {qlib.GeometricShape} s - The other geometric shape to intersect with this one. 65 | * @returns {Array|Object|null} The result of the intersection, which can vary depending on the shapes involved 66 | * (e.g., an array of intersection points, an object describing overlap, or null if no intersection). 67 | * The specific return type is determined by `qlib.Intersection.intersect`. 68 | */ 69 | p.intersect = function( s ) { 70 | return qlib.Intersection.intersect( this, s ); 71 | } 72 | 73 | /** 74 | * Placeholder method for drawing the shape. 75 | * Concrete subclasses must implement this method to provide their drawing logic. 76 | * 77 | * @method draw 78 | * @param {CanvasRenderingContext2D|Object} graphics - The drawing context (e.g., a 2D canvas context) 79 | * or a custom graphics object that supports drawing operations. 80 | * @returns {void} 81 | * @throws {Error} If not implemented by a subclass. 82 | */ 83 | p.draw = function( graphics ) 84 | { 85 | throw("draw() not implented yet in "+this.type); 86 | } 87 | 88 | /** 89 | * Placeholder method for scaling the shape. 90 | * Concrete subclasses must implement this method. 91 | * 92 | * @method scale 93 | * @param {number} factorX - The scaling factor along the x-axis. 94 | * @param {number} factorY - The scaling factor along the y-axis. 95 | * @param {qlib.Vector2} [center] - The optional center point for scaling. If not provided, 96 | * scaling might be relative to an origin or the shape's own center. 97 | * @returns {this} The instance of the shape, allowing for chaining (if implemented by subclass). 98 | * @throws {Error} If not implemented by a subclass. 99 | */ 100 | p.scale = function( factorX, factorY, center ) 101 | { 102 | throw("scale() not implented yet in "+this.type); 103 | } 104 | 105 | /** 106 | * Placeholder method for cloning the shape. 107 | * Concrete subclasses must implement this method. 108 | * 109 | * @method clone 110 | * @param {boolean} [deepClone=false] - If true, a deep clone of the shape's properties (like points) 111 | * should be performed. If false, a shallow clone might be acceptable. 112 | * @returns {qlib.GeometricShape} A new instance of the shape, identical to this one. 113 | * @throws {Error} If not implemented by a subclass. 114 | */ 115 | p.clone = function( deepClone ) 116 | { 117 | throw("clone() not implented yet in "+this.type); 118 | } 119 | 120 | 121 | /** 122 | * Returns a string representation of this object, which is its `type`. 123 | * 124 | * @method toString 125 | * @return {string} The type of the geometric shape. 126 | **/ 127 | p.toString = function() { 128 | return this.type; 129 | } 130 | 131 | qlib["GeometricShape"] = GeometricShape; 132 | }()); -------------------------------------------------------------------------------- /demos/CrossdominatorDemo.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | QuasimondoLibsJS Demo: Crossdominator 6 | 7 | 8 | 9 | 79 | 80 | 81 | 82 | 86 |
87 |

You might have run into this issue: you want to manipulate the pixels of images in canvas, but once you try this with images that come from domains other than the one the page is hosted the security sandbox prevents you to do that. One solution to this problem is to load all images through a proxy on your server first. This has the downside that you have to pay for the extra traffic caused by this.

88 |

Thanks to a bug in the Adobe Flash player this can currently be avoided by creating a proxy on the client side. Crossdominator is a tiny Flash file and a bit of Javascript that allow you to load images from any domain and not get bothered by the security sandbox.

89 |

This demo is really more like a proof-of-concept, since I expect Adobe to plug that hole any time soon (even though it seems like the exploit has been around for many years now). And obviously since Flash is required this trick will not work on your mobile.

90 |

The credits for pointing out this loophole which was discovered by some russian hackers a few years ago go to @makc

91 |

In IE exists a similar security hole using IFrames, discovered by Mat Groves.

92 |

Ping me on twitter if you have questions or ideas for improvements: @Quasimondo 93 |

In this demo you can load an image from any url. To show that pixel access is possible the left half will be inverted. Check the source code to see how it works.

94 |

95 |

Enter an image URL: 96 | 97 |
98 |
99 |
100 |
101 | 102 | 103 |
104 | 105 | -------------------------------------------------------------------------------- /src/qlib/geom/TriangleUtils.js: -------------------------------------------------------------------------------- 1 | /* 2 | * TriangleUtils 3 | * 4 | * Copyright (c) 2013 Mario Klingemann 5 | * 6 | * Permission is hereby granted, free of charge, to any person 7 | * obtaining a copy of this software and associated documentation 8 | * files (the "Software"), to deal in the Software without 9 | * restriction, including without limitation the rights to use, 10 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the 12 | * Software is furnished to do so, subject to the following 13 | * conditions: 14 | * 15 | * The above copyright notice and this permission notice shall be 16 | * included in all copies or substantial portions of the Software. 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 19 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 20 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 21 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 22 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 23 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 24 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 25 | * OTHER DEALINGS IN THE SOFTWARE. 26 | */ 27 | 28 | // namespace: 29 | window["qlib"] = window.qlib || {}; 30 | 31 | (function() { 32 | 33 | /** 34 | * A utility class providing static helper methods for creating `qlib.Triangle` objects. 35 | * This class is not intended to be instantiated. 36 | * @class TriangleUtils 37 | * @memberof qlib 38 | */ 39 | var TriangleUtils = function() { 40 | // Static class, not meant to be instantiated. 41 | throw new Error("TriangleUtils cannot be instantiated."); 42 | } 43 | 44 | /** 45 | * Creates a triangle defined by its side lengths, positioned with its centroid at a given center point, and rotated. 46 | * Note: Not all combinations of three side lengths can form a valid triangle. 47 | * The method first constructs the triangle at the origin, then translates and rotates it. 48 | * 49 | * @static 50 | * @method getCenteredTriangle 51 | * @param {qlib.Vector2} center - The desired center point for the triangle (centroid). 52 | * @param {number} sideALength - Length of the side opposite the first vertex (e.g., side between v2 and v3). 53 | * @param {number} sideBLength - Length of the side opposite the second vertex (e.g., side between v1 and v3). 54 | * @param {number} sideCLength - Length of the side opposite the third vertex (e.g., side between v1 and v2, often used as the base). 55 | * @param {number} [angle=0] - Desired rotation of the triangle in radians around its calculated centroid. 56 | * @returns {qlib.Triangle|null} A new `qlib.Triangle`, or `null` if the side lengths cannot form a valid triangle. 57 | */ 58 | TriangleUtils.getCenteredTriangle = function( center, sideALength, sideBLength, sideCLength, angle ) // Parameters renamed for clarity: left, right, bottom -> sideA, sideB, sideC (standard notation) 59 | { 60 | angle = angle || 0; // Default angle to 0 if not provided 61 | 62 | // Using Law of Cosines to find an angle (e.g., angle at vertex where sideBLength and sideCLength meet) 63 | // cos(alpha) = (b^2 + c^2 - a^2) / (2bc) 64 | var cosAlpha = ( sideBLength * sideBLength + sideCLength * sideCLength - sideALength * sideALength ) / ( 2 * sideBLength * sideCLength ); 65 | 66 | if ( isNaN(cosAlpha) || cosAlpha < -1.0 || cosAlpha > 1.0 ) return null; // Invalid triangle if cosine out of bounds 67 | 68 | var alpha = Math.acos( cosAlpha ); 69 | // Place first vertex at origin 70 | var v1 = new qlib.Vector2(0,0); 71 | // Place second vertex along x-axis based on one side length (e.g. sideCLength) 72 | var v2 = new qlib.Vector2(sideCLength, 0 ); 73 | // Place third vertex using the other side length (sideBLength) and calculated angle alpha 74 | var v3 = new qlib.Vector2( Math.cos( alpha ) * sideBLength, Math.sin( alpha ) * sideBLength ); 75 | 76 | var triangle = new qlib.Triangle( v1, v2, v3 ); 77 | var ctr = triangle.centerOfMass(); // Calculate centroid of this initial triangle 78 | 79 | // Translate so its centroid is at the desired 'center' 80 | triangle.translate( center.getMinus( ctr ) ); 81 | 82 | // Rotate if an angle is specified 83 | if ( angle !== 0 ) triangle.rotate( angle, center ); // Rotate around the new center 84 | 85 | return triangle; 86 | } 87 | 88 | /** 89 | * Creates an equilateral triangle given two points `pa` and `pb` which form one side of the triangle. 90 | * The third point is determined by rotating one point around the other by 60 degrees (PI/3 radians). 91 | * 92 | * @static 93 | * @method getEquilateralTriangle 94 | * @param {qlib.Vector2} pa - The first point of the base side. 95 | * @param {qlib.Vector2} pb - The second point of the base side. 96 | * @param {boolean} [flipped=false] - If true, the third point is constructed on the "other" side of the directed segment pa->pb, 97 | * effectively flipping the triangle's orientation relative to that segment. 98 | * Default (false) usually results in a counter-clockwise winding (pa, pb, p_new). 99 | * @returns {qlib.Triangle} A new equilateral `qlib.Triangle`. 100 | */ 101 | TriangleUtils.getEquilateralTriangle = function( pa, pb, flipped ) 102 | { 103 | flipped = flipped || false; // Default to false 104 | var angleToPb = pa.getAngleTo(pb); // Assuming Vector2 has getAngleTo 105 | var distanceToPb = pa.distanceToVector( pb ); 106 | var angleOffset = Math.PI / 3 * ( flipped ? -1 : 1); 107 | 108 | var p3 = pa.getAddCartesian(angleToPb + angleOffset, distanceToPb); 109 | return new qlib.Triangle( pa, pb, p3 ); 110 | } 111 | 112 | qlib["TriangleUtils"] = TriangleUtils; 113 | }()); -------------------------------------------------------------------------------- /docs/app/1.0.0/events_Event.js.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | JSDoc: Source: events/Event.js 6 | 7 | 8 | 9 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 |

Source: events/Event.js

21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 |
29 |
/*
 30 | * Event
 31 | * Visit http://createjs.com/ for documentation, updates and examples.
 32 | *
 33 | * Copyright (c) 2010 gskinner.com, inc.
 34 | *
 35 | * Permission is hereby granted, free of charge, to any person
 36 | * obtaining a copy of this software and associated documentation
 37 | * files (the "Software"), to deal in the Software without
 38 | * restriction, including without limitation the rights to use,
 39 | * copy, modify, merge, publish, distribute, sublicense, and/or sell
 40 | * copies of the Software, and to permit persons to whom the
 41 | * Software is furnished to do so, subject to the following
 42 | * conditions:
 43 | *
 44 | * The above copyright notice and this permission notice shall be
 45 | * included in all copies or substantial portions of the Software.
 46 | *
 47 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 48 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 49 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 50 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 51 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 52 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 53 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 54 | * OTHER DEALINGS IN THE SOFTWARE.
 55 | */
 56 | 
 57 | // namespace:
 58 | window["qlib"] = window.qlib || {};
 59 | 
 60 | (function() {
 61 | 
 62 | /**
 63 |  * This is passed as the parameter to mousedown, mouseup, mousemove, stagemouseup, stagemousedown, mouseover, mouseout
 64 |  * and click events on {{#crossLink "DisplayObject"}}{{/crossLink}} instances.
 65 |  * @class Event
 66 |  * @uses EventDispatcher
 67 |  * @constructor
 68 |  * @param {String} type The event type.
 69 |  *
 70 |  **/
 71 | var Event = function(type, target) {
 72 |   this.initialize(type, target);
 73 | }
 74 | var p = Event.prototype;
 75 | 
 76 | // events:
 77 | 
 78 | 
 79 | 
 80 | 	/**
 81 | 	 * The type of mouse event. This will be the same as the handler it maps to (onPress,
 82 | 	 * onMouseDown, onMouseUp, onMouseMove, or onClick).
 83 | 	 * @property type
 84 | 	 * @type String
 85 | 	 **/
 86 | 	p.type = null;
 87 | 
 88 | 
 89 | 	/**
 90 | 	 * The display object this event relates to.
 91 | 	 * @property target
 92 | 	 * @type DisplayObject
 93 | 	 * @default null
 94 | 	*/
 95 | 	p.target = null;
 96 | 
 97 | 
 98 | 
 99 | // mix-ins:
100 | 	// EventDispatcher methods:
101 | 	p.addEventListener = null;
102 | 	p.removeEventListener = null;
103 | 	p.removeAllEventListeners = null;
104 | 	p.dispatchEvent = null;
105 | 	p.hasEventListener = null;
106 | 	p._listeners = null;
107 | 	qlib.EventDispatcher.initialize(p); // inject EventDispatcher methods.
108 | 
109 | // constructor:
110 | 	/**
111 | 	 * Initialization method.
112 | 	 * @method initialize
113 | 	 * @protected
114 | 	 **/
115 | 	p.initialize = function(type, target) {
116 | 		this.type = type;
117 | 		this.target = target;
118 | 
119 | 	}
120 | 
121 | // public methods:
122 | 	/**
123 | 	 * Returns a clone of the Event instance.
124 | 	 * @method clone
125 | 	 * @return {Event} a clone of the Event instance.
126 | 	 **/
127 | 	p.clone = function() {
128 | 		return new Event(this.type, this.target);
129 | 	}
130 | 
131 | 	/**
132 | 	 * Returns a string representation of this object.
133 | 	 * @method toString
134 | 	 * @return {String} a string representation of the instance.
135 | 	 **/
136 | 	p.toString = function() {
137 | 		return "[Event (type="+this.type+")]";
138 | 	}
139 | 
140 | 	qlib["Event"] = Event;
141 | }());
142 |
143 |
144 | 145 | 146 | 147 | 148 |
149 | 150 | 153 | 154 |
155 | 156 | 159 | 160 | 161 | 162 | 163 | 164 | -------------------------------------------------------------------------------- /docs/Point.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | JSDoc: Class: Point 6 | 7 | 8 | 9 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 |

Class: Point

21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 | 29 |
30 | 31 |

Point(xopt, yopt)

32 | 33 | 34 |
35 | 36 |
37 |
38 | 39 | 40 | 41 | 42 | 43 | 44 |

new Point(xopt, yopt)

45 | 46 | 47 | 48 | 49 | 50 | 51 |
52 | Represents a point in a 2D coordinate system. 53 |
54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 |
Parameters:
64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 103 | 104 | 105 | 114 | 115 | 116 | 117 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 142 | 143 | 144 | 153 | 154 | 155 | 156 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 |
NameTypeAttributesDefaultDescription
x 96 | 97 | 98 | number 99 | 100 | 101 | 102 | 106 | 107 | <optional>
108 | 109 | 110 | 111 | 112 | 113 |
118 | 119 | 0 120 | 121 | The x-coordinate.
y 135 | 136 | 137 | number 138 | 139 | 140 | 141 | 145 | 146 | <optional>
147 | 148 | 149 | 150 | 151 | 152 |
157 | 158 | 0 159 | 160 | The y-coordinate.
169 | 170 | 171 | 172 | 173 | 174 | 175 |
Properties:
176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 |
NameTypeDescription
x 205 | 206 | 207 | number 208 | 209 | 210 | 211 | The x-coordinate.
y 228 | 229 | 230 | number 231 | 232 | 233 | 234 | The y-coordinate.
length 251 | 252 | 253 | number 254 | 255 | 256 | 257 | The distance from the origin (0,0) to this point.
269 | 270 | 271 | 272 | 273 |
274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 |
Source:
301 |
304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 |
312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 |
334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 |
355 | 356 |
357 | 358 | 359 | 360 | 361 |
362 | 363 | 366 | 367 |
368 | 369 | 372 | 373 | 374 | 375 | 376 | -------------------------------------------------------------------------------- /docs/Point.js.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | JSDoc: Source: Point.js 6 | 7 | 8 | 9 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 |

Source: Point.js

21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 |
29 |
/**
 30 |  * Represents a point in a 2D coordinate system.
 31 |  * @class Point
 32 |  * @param {number} [x=0] - The x-coordinate.
 33 |  * @param {number} [y=0] - The y-coordinate.
 34 |  * @property {number} x - The x-coordinate.
 35 |  * @property {number} y - The y-coordinate.
 36 |  * @property {number} length - The distance from the origin (0,0) to this point.
 37 | */
 38 | 
 39 | // namespace:
 40 | window["qlib"] = window.qlib || {};
 41 | 
 42 | (function() {
 43 | 	/**
 44 | 	 * @constructor
 45 | 	 * @param {number} [x=0] - The x-coordinate.
 46 | 	 * @param {number} [y=0] - The y-coordinate.
 47 | 	 */
 48 | 	var Point = function( x, y ) {
 49 | 		this.initialize( x, y );
 50 | 	}
 51 | 
 52 | 	var p = Point.prototype;
 53 | 	/**
 54 | 	 * Initializes the Point object.
 55 | 	 * @param {number} [x=0] - The x-coordinate.
 56 | 	 * @param {number} [y=0] - The y-coordinate.
 57 | 	 */
 58 | 	p.initialize = function (x, y) {
 59 | 		this.x = x || 0;
 60 | 		this.y = y || 0;
 61 | 
 62 | 		this.__defineGetter__("length", function(){return Math.sqrt(this.x * this.x + this.y * this.y);});
 63 | 	}
 64 | 
 65 | 	/**
 66 | 	* Adds the coordinates of another point to the coordinates of this point to create a new point.
 67 | 	* @param {qlib.Point} v The point to be added.
 68 | 	* @returns {qlib.Point} The new Point.
 69 | 	*/
 70 | 	p.add = function(v) {
 71 | 		return new qlib.Point(this.x + v.x, this.y + v.y);
 72 | 	}
 73 | 
 74 | 	/**
 75 | 	* Creates a copy of this Point object.
 76 | 	* @returns {qlib.Point} The new Point.
 77 | 	*/
 78 | 	p.clone = function() {
 79 | 		return new qlib.Point(this.x, this.y);
 80 | 	}
 81 | 
 82 | 
 83 | 	/**
 84 | 	* Determines whether two points are equal.
 85 | 	* @param {qlib.Point} toCompare The point to be compared.
 86 | 	* @returns {boolean} True if the object is equal to this Point object; false if it is not equal.
 87 | 	*/
 88 | 	p.equals = function(toCompare) {
 89 | 		return this.x == toCompare.x && this.y == toCompare.y;
 90 | 	}
 91 | 
 92 | 
 93 | 	/**
 94 | 	* Scales the line segment between (0,0) and the current point to a set length.
 95 | 	* @param {number} thickness The scaling value. For example, if the current point is (0,5), and you normalize it to 1, the point returned is at (0,1).
 96 | 	*/
 97 | 	p.normalize = function(thickness) {
 98 | 		var ratio = thickness / this.length;
 99 | 		this.x *= ratio;
100 | 		this.y *= ratio;
101 | 	}
102 | 
103 | 	/**
104 | 	* Offsets the Point object by the specified amount.
105 | 	* @param {number} dx The amount by which to offset the horizontal coordinate, x.
106 | 	* @param {number} dy The amount by which to offset the vertical coordinate, y.
107 | 	*/
108 | 	p.offset = function(dx, dy) {
109 | 		this.x += dx;
110 | 		this.y += dy;
111 | 	}
112 | 
113 | 
114 | 	/**
115 | 	* Subtracts the coordinates of another point from the coordinates of this point to create a new point.
116 | 	* @param {qlib.Point} v The point to be subtracted.
117 | 	* @returns {qlib.Point} The new point.
118 | 	*/
119 | 	p.subtract = function(v) {
120 | 		return new qlib.Point( this.x - v.x, this.y - v.y );
121 | 	}
122 | 
123 | 	/**
124 | 	 * Returns a string representation of this object.
125 | 	 * @returns {string} a string representation of the instance.
126 | 	 **/
127 | 	p.toString = function() {
128 | 		return "qlib.Point("+this.x+","+this.y+")";
129 | 	}
130 | 
131 | 	/**
132 | 	* Returns the distance between pt1 and pt2.
133 | 	* @static
134 | 	* @param {qlib.Point} pt1 The first point.
135 | 	* @param {qlib.Point} pt2 The second point.
136 | 	* @returns {number} The distance between the first and second points.
137 | 	*/
138 | 	Point.distance = function(pt1, pt2) {
139 | 		var dx = pt2.x - pt1.x;
140 | 		var dy = pt2.y - pt1.y;
141 | 		return Math.sqrt(dx * dx + dy * dy);
142 | 	}
143 | 
144 | 	/**
145 | 	* Determines a point between two specified points.
146 | 	* @static
147 | 	* @param {qlib.Point} pt1 The first point.
148 | 	* @param {qlib.Point} pt2 The second point.
149 | 	* @param {number} f The level of interpolation between the two points. Indicates where the new point will be, along the line between pt1 and pt2. If f=1, pt1 is returned; if f=0, pt2 is returned.
150 | 	* @returns {qlib.Point} The new, interpolated point.
151 | 	*/
152 | 
153 | 	Point.interpolate = function(pt1, pt2, f) {
154 | 		var pt = new qlib.Point();
155 | 		pt.x = pt1.x + f * (pt2.x - pt1.x);
156 | 		pt.y = pt1.y + f * (pt2.y - pt1.y);
157 | 		return pt;
158 | 	}
159 | 	/**
160 | 	* Converts a pair of polar coordinates to a Cartesian point coordinate.
161 | 	* @static
162 | 	* @param {number} len The length coordinate of the polar pair.
163 | 	* @param {number} angle The angle, in radians, of the polar pair.
164 | 	* @returns {qlib.Point} The Cartesian point.
165 | 	*/
166 | 	Point.polar = function(len, angle) {
167 | 		return new qlib.Point(len * Math.cos(angle), len * Math.sin(angle));
168 | 	}
169 | 
170 | 	qlib["Point"] = Point;
171 | 
172 | }());
173 | 
174 | 
175 |
176 |
177 | 178 | 179 | 180 | 181 |
182 | 183 | 186 | 187 |
188 | 189 | 192 | 193 | 194 | 195 | 196 | 197 | -------------------------------------------------------------------------------- /src/qlib/math/CovarianceMatrix2.js: -------------------------------------------------------------------------------- 1 | /* 2 | * CovarianceMatrix2 3 | * 4 | * Directly ported from Jonathan Blow's example code to his article 5 | * "My Friend, the Covariance Body" published in Game Developer Magazine 6 | * http://www.number-none.com/product/My%20Friend,%20the%20Covariance%20Body/index.html 7 | * http://www.gdmag.com/src/sep02.zip 8 | * 9 | * Copyright (c) 2013 Mario Klingemann 10 | * 11 | * Permission is hereby granted, free of charge, to any person 12 | * obtaining a copy of this software and associated documentation 13 | * files (the "Software"), to deal in the Software without 14 | * restriction, including without limitation the rights to use, 15 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 16 | * copies of the Software, and to permit persons to whom the 17 | * Software is furnished to do so, subject to the following 18 | * conditions: 19 | * 20 | * The above copyright notice and this permission notice shall be 21 | * included in all copies or substantial portions of the Software. 22 | * 23 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 25 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 26 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 27 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 28 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 29 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 30 | * OTHER DEALINGS IN THE SOFTWARE. 31 | */ 32 | 33 | // namespace: 34 | window["qlib"] = window.qlib || {}; 35 | 36 | (function() { 37 | 38 | var CovarianceMatrix2 = function() { 39 | this.reset(); 40 | } 41 | 42 | var p = CovarianceMatrix2.prototype; 43 | 44 | p.reset = function() 45 | { 46 | this.a = this.b = this.c = 0; 47 | } 48 | 49 | p.invert = function() 50 | { 51 | var det = this.a*this.c - this.b*this.b; 52 | var factor = 1.0 / det; 53 | 54 | var result = new qlib.CovarianceMatrix2(); 55 | result.a = this.c * factor; 56 | result.b = -this.b * factor; 57 | result.c = this.a * factor; 58 | 59 | return result; 60 | } 61 | 62 | p.add = function( other ) 63 | { 64 | var result = new qlib.CovarianceMatrix2(); 65 | result.a = this.a + other.a; 66 | result.b = this.b + other.b; 67 | result.c = this.c + other.c; 68 | 69 | return result; 70 | } 71 | 72 | p.scale= function( factor ) 73 | { 74 | this.a *= factor; 75 | this.b *= factor; 76 | this.c *= factor; 77 | } 78 | 79 | p.rotate = function( theta ) 80 | { 81 | var s = Math.sin(theta); 82 | var t = Math.cos(theta); 83 | 84 | var a_prime = this.a*t*t + this.b*2*s*t + this.c*s*s; 85 | var b_prime = -this.a*s*t + this.b*(t*t - s*s) + this.c*s*t; 86 | var c_prime = this.a*s*s - this.b*2*s*t + this.c*t*t; 87 | 88 | this.a = a_prime; 89 | this.b = b_prime; 90 | this.c = c_prime; 91 | } 92 | 93 | 94 | p.solve_quadratic_where_discriminant_is_known_to_be_nonnegative = function( a, b, c ) 95 | { 96 | var result = {num_solutions: 0, solutions: []}; 97 | 98 | if (a == 0.0) { // Then bx + c = 0; thus, x = -c / b 99 | if (b == 0.0) { 100 | return result; 101 | } 102 | 103 | result.solutions[0] = -c / b; 104 | result.num_solutions = 1; 105 | return result; 106 | } 107 | 108 | var discriminant = b * b - 4 * a * c; 109 | if (discriminant < 0.0) discriminant = 0.0; 110 | 111 | var sign_b = 1.0; 112 | if (b < 0.0) sign_b = -1.0; 113 | 114 | var nroots = 0; 115 | var q = -0.5 * (b + sign_b * Math.sqrt(discriminant)); 116 | 117 | nroots++; 118 | result.solutions[0] = q / a; 119 | 120 | if (q != 0.0) { 121 | var solution = c / q; 122 | if (solution != result.solutions[0]) { 123 | nroots++; 124 | result.solutions[1] = solution; 125 | } 126 | } 127 | 128 | result.num_solutions = nroots; 129 | return result; 130 | } 131 | 132 | // The CovarianceMatrix2 eigenvector path is completely separate (I wrote 133 | // it first, and it was simpler to just crank out). 134 | 135 | p.find_eigenvalues = function( eigenvalues ) 136 | { 137 | var qa = 1; 138 | var qb = -(this.a + this.c); 139 | var qc = this.a * this.c - this.b * this.b; 140 | 141 | var solution = this.solve_quadratic_where_discriminant_is_known_to_be_nonnegative( qa, qb, qc ); 142 | 143 | // If there's only one solution, explicitly state it as a 144 | // double eigenvalue. 145 | if (solution.num_solutions == 1) 146 | { 147 | solution.solutions[1] = solution.solutions[0]; 148 | solution.num_solutions = 2; 149 | } 150 | 151 | eigenvalues[0] = solution.solutions[0]; 152 | eigenvalues[1] = solution.solutions[1]; 153 | return solution.num_solutions; 154 | } 155 | 156 | p.find_eigenvectors= function( eigenvalues, eigenvectors) 157 | { 158 | var num_eigenvalues = this.find_eigenvalues(eigenvalues); 159 | if (num_eigenvalues != 2) 160 | { 161 | throw("Did not get 2 Eigenvalues but "+num_eigenvalues ); 162 | }; 163 | 164 | // Now that we have the quadratic coefficients, find the eigenvectors. 165 | 166 | var VANISHING_EPSILON = 1.0e-5; 167 | var SAMENESS_LOW = 0.9999; 168 | var SAMENESS_HIGH = 1.0001; 169 | 170 | var punt = false; 171 | var A_EPSILON = 0.0000001; 172 | 173 | if (this.a < A_EPSILON) { 174 | punt = true; 175 | } else { 176 | var ratio = Math.abs(eigenvalues[1] / eigenvalues[0]); 177 | if ((ratio > SAMENESS_LOW) && (ratio < SAMENESS_HIGH)) punt = true; 178 | } 179 | 180 | if (punt) { 181 | eigenvalues[0] = this.a; 182 | eigenvalues[1] = this.a; 183 | 184 | eigenvectors[0] = new qlib.Vector2(1, 0); 185 | eigenvectors[1] = new qlib.Vector2(0, 1); 186 | num_eigenvalues = 2; 187 | return num_eigenvalues; 188 | } 189 | 190 | for (var j = 0; j < num_eigenvalues; j++) { 191 | var lambda = eigenvalues[j]; 192 | 193 | var result1 = new qlib.Vector2(-this.b, this.a - lambda); 194 | var result2 = new qlib.Vector2(-(this.c - lambda), this.b); 195 | 196 | var result; 197 | if (result1.getSquaredLength() > result2.getSquaredLength()) { 198 | result = result1; 199 | } else { 200 | result = result2; 201 | } 202 | 203 | result.normalize(); 204 | eigenvectors[j] = result; 205 | } 206 | 207 | return num_eigenvalues; 208 | } 209 | 210 | p.move_to_global_coordinates= function( dest, x, y) 211 | { 212 | dest.a = this.a + x*x; 213 | dest.b = this.b + x*y; 214 | dest.c = this.c + y*y; 215 | } 216 | 217 | p.move_to_local_coordinates= function( dest, x, y) 218 | { 219 | dest.a = this.a - x*x; 220 | dest.b = this.b - x*y; 221 | dest.c = this.c - y*y; 222 | } 223 | 224 | qlib["CovarianceMatrix2"] = CovarianceMatrix2; 225 | }()); 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | -------------------------------------------------------------------------------- /src/qlib/geom/Delaunay.js: -------------------------------------------------------------------------------- 1 | /* 2 | Delaunay Triangulation 3 | 4 | based on delaunay.java Code found on Ken Perlin's site: 5 | http://mrl.nyu.edu/~perlin/experiments/incompressible/ 6 | 7 | original author: Dr. Marcus Apel 8 | http://www.geo.tu-freiberg.de/~apelm/ 9 | 10 | ported and optimized for Actionscript by Mario Klingemann 11 | */ 12 | 13 | // This is a JavaScript interpretation of the provided ActionScript code. 14 | // JSDoc will be for the JavaScript equivalent. 15 | 16 | // namespace: 17 | window["qlib"] = window.qlib || {}; 18 | 19 | (function() { // Assuming this immediately invoked function expression (IIFE) encapsulates the module 20 | 21 | /** 22 | * Performs Delaunay triangulation on a set of 2D points. 23 | * The triangulation ensures that no point in the set is inside the circumcircle of any triangle. 24 | * This implementation also supports generating Voronoi diagrams from the triangulation. 25 | * It includes methods for inserting points, clearing the triangulation, and retrieving 26 | * geometric elements like triangles, edges, Voronoi regions, and the convex hull. 27 | * 28 | * Based on delaunay.java by Dr. Marcus Apel, ported and optimized by Mario Klingemann. 29 | * 30 | * @class Delaunay 31 | * @memberof qlib 32 | * @param {qlib.Rectangle} [viewport] - The viewport bounds for the triangulation and Voronoi diagram. 33 | * If not provided, a default viewport is used. 34 | */ 35 | var Delaunay = function( viewport ) { // In JS, this is the constructor 36 | /** 37 | * Collection of `qlib.DelaunayTriangle` objects representing the triangles in the triangulation. 38 | * @property {qlib.DelaunayTriangles} triangles 39 | */ 40 | this.triangles = new qlib.DelaunayTriangles(); 41 | /** 42 | * Collection of `qlib.DelaunayNode` objects representing the input points. 43 | * @property {qlib.DelaunayNodes} nodes 44 | */ 45 | this.nodes = new qlib.DelaunayNodes(); 46 | /** 47 | * Collection of `qlib.DelaunayEdge` objects representing the edges of the triangles. 48 | * @property {qlib.DelaunayEdges} edges 49 | */ 50 | this.edges = new qlib.DelaunayEdges(); 51 | /** 52 | * Collection of `qlib.VoronoiRegion` objects representing the Voronoi regions. 53 | * @property {qlib.VoronoiRegions} regions 54 | */ 55 | this.regions = new qlib.VoronoiRegions(); 56 | /** 57 | * Array storing the nodes that form the initial bounding triangle. 58 | * @property {qlib.DelaunayNode[]} _boundingNodes 59 | * @private 60 | */ 61 | this._boundingNodes = []; 62 | 63 | /** 64 | * Flag indicating whether the Voronoi regions are up-to-date and ready for retrieval. 65 | * @property {boolean} regionsReady 66 | * @default false 67 | */ 68 | this.regionsReady = false; 69 | /** 70 | * Flag indicating if the triangulation is in an ill-defined state (e.g., before the first triangle is formed). 71 | * @property {boolean} ill_defined 72 | * @protected 73 | * @default true 74 | */ 75 | this.ill_defined = true; 76 | /** 77 | * The viewport bounds for the triangulation and Voronoi diagram. 78 | * @property {qlib.Rectangle} viewport 79 | */ 80 | if ( viewport == null ) 81 | { 82 | this.viewport = new qlib.Rectangle( -20,-20,2000,2000); // Default viewport 83 | } else { 84 | this.viewport = viewport; 85 | } 86 | this.regions.viewport = this.viewport; // Assign viewport to regions manager 87 | 88 | /** 89 | * Minimum x-coordinate of the inserted points. 90 | * @property {number} min_x 91 | * @protected 92 | */ 93 | this.min_x = 0; 94 | /** Minimum y-coordinate. @property {number} min_y @protected */ 95 | this.min_y = 0; 96 | /** Maximum x-coordinate. @property {number} max_x @protected */ 97 | this.max_x = 0; 98 | /** Maximum y-coordinate. @property {number} max_y @protected */ 99 | this.max_y = 0; 100 | 101 | /** 102 | * A reference to the starting edge of the convex hull of the triangulation. 103 | * @property {qlib.DelaunayEdge|null} hullStart 104 | * @protected 105 | */ 106 | this.hullStart = null; 107 | /** 108 | * The currently active or last processed edge in certain triangulation algorithms. 109 | * @property {qlib.DelaunayEdge|null} actE 110 | * @protected 111 | */ 112 | this.actE = null; 113 | /** 114 | * A counter for edge flip operations during the triangulation process. 115 | * Used internally for debugging or specific algorithm needs. 116 | * @property {number} flipCount 117 | * @protected 118 | * @default 0 119 | */ 120 | this.flipCount = 0; 121 | }; 122 | 123 | var p = Delaunay.prototype; // In JS, methods are added to the prototype 124 | 125 | // JSDoc for methods would go here, attached to 'p.methodName = function() {}' 126 | // For brevity, I'll show a few examples then apply the full set in the diff. 127 | 128 | /** 129 | * Creates an initial bounding triangle for the triangulation. 130 | * Points are inserted using `insertXY`. 131 | * 132 | * @method createBoundingTriangle 133 | * @param {number} [center_x=0] - X-coordinate of the bounding triangle's circumcenter. 134 | * @param {number} [center_y=0] - Y-coordinate of the bounding triangle's circumcenter. 135 | * @param {number} [radius=8000] - Radius of the circumcircle for the bounding triangle. 136 | * @param {number} [rotation=0] - Initial rotation for placing the bounding triangle vertices. 137 | * @returns {void} 138 | */ 139 | p.createBoundingTriangle = function( center_x, center_y, radius, rotation ) 140 | { 141 | // ... implementation 142 | }; 143 | 144 | /** 145 | * Clears all data from the Delaunay triangulation, resetting it to an initial empty state. 146 | * @method clear 147 | * @returns {void} 148 | */ 149 | p.clear = function() 150 | { 151 | // ... implementation 152 | }; 153 | 154 | /** 155 | * Inserts a point into the triangulation using its x and y coordinates. 156 | * Optionally, custom data can be associated with the node created for this point. 157 | * 158 | * @method insertXY 159 | * @param {number} px - The x-coordinate of the point to insert. 160 | * @param {number} py - The y-coordinate of the point to insert. 161 | * @param {Object} [data] - Optional data to store with the node. 162 | * @returns {boolean} True if the point was successfully inserted, false otherwise (e.g., if it's a duplicate). 163 | */ 164 | p.insertXY = function( px, py, data ) 165 | { 166 | return this.insertNode(qlib.DelaunayNodes.getNode( px, py, data ) ); 167 | }; 168 | 169 | // ... other methods would follow similar JSDoc structure ... 170 | 171 | 172 | // Original ActionScript functions are now methods of Delaunay.prototype 173 | // For example: function insertNode(nd) becomes p.insertNode = function(nd) 174 | 175 | // All functions from the original ActionScript class become methods of 'p' (Delaunay.prototype) 176 | // I will now apply the JSDoc to all methods in the diff. 177 | // Note: Some internal helper methods might be marked @protected or @private. 178 | // Types like Graphics and BitmapData will be generalized or specified as e.g. CanvasRenderingContext2D. 179 | // Vector. will become Array or T[]. 180 | 181 | // The rest of the methods from the original ActionScript code would be here, 182 | // assigned to p.methodName = function(...) { ... } 183 | 184 | // End of IIFE 185 | // Assign class to qlib namespace 186 | qlib["Delaunay"] = Delaunay; 187 | 188 | })(); // End of IIFE -------------------------------------------------------------------------------- /docs/app/1.0.0/Point.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | JSDoc: Class: Point 6 | 7 | 8 | 9 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 |

Class: Point

21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 | 29 |
30 | 31 |

Point(xopt, yopt)

32 | 33 | 34 |
35 | 36 |
37 |
38 | 39 | 40 | 41 | 42 | 43 | 44 |

new Point(xopt, yopt)

45 | 46 | 47 | 48 | 49 | 50 | 51 |
52 | Represents a point in a 2D coordinate system. 53 |
54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 |
Parameters:
64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 103 | 104 | 105 | 114 | 115 | 116 | 117 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 142 | 143 | 144 | 153 | 154 | 155 | 156 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 |
NameTypeAttributesDefaultDescription
x 96 | 97 | 98 | number 99 | 100 | 101 | 102 | 106 | 107 | <optional>
108 | 109 | 110 | 111 | 112 | 113 |
118 | 119 | 0 120 | 121 | The x-coordinate.
y 135 | 136 | 137 | number 138 | 139 | 140 | 141 | 145 | 146 | <optional>
147 | 148 | 149 | 150 | 151 | 152 |
157 | 158 | 0 159 | 160 | The y-coordinate.
169 | 170 | 171 | 172 | 173 | 174 | 175 |
Properties:
176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 |
NameTypeDescription
x 205 | 206 | 207 | number 208 | 209 | 210 | 211 | The x-coordinate.
y 228 | 229 | 230 | number 231 | 232 | 233 | 234 | The y-coordinate.
length 251 | 252 | 253 | number 254 | 255 | 256 | 257 | The distance from the origin (0,0) to this point.
269 | 270 | 271 | 272 | 273 |
274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 |
Source:
301 |
304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 |
312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 |
334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 |
355 | 356 |
357 | 358 | 359 | 360 | 361 |
362 | 363 | 366 | 367 |
368 | 369 |
370 | Documentation generated by JSDoc 4.0.4 on Sat May 31 2025 06:36:44 GMT+0000 (Coordinated Universal Time) 371 |
372 | 373 | 374 | 375 | 376 | -------------------------------------------------------------------------------- /docs/app/1.0.0/geom_SteinerCircles.js.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | JSDoc: Source: geom/SteinerCircles.js 6 | 7 | 8 | 9 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 |

Source: geom/SteinerCircles.js

21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 |
29 |
/*
 30 | * Circle
 31 | *
 32 | * Copyright (c) 2013 Mario Klingemann
 33 | *
 34 | * Permission is hereby granted, free of charge, to any person
 35 | * obtaining a copy of this software and associated documentation
 36 | * files (the "Software"), to deal in the Software without
 37 | * restriction, including without limitation the rights to use,
 38 | * copy, modify, merge, publish, distribute, sublicense, and/or sell
 39 | * copies of the Software, and to permit persons to whom the
 40 | * Software is furnished to do so, subject to the following
 41 | * conditions:
 42 | *
 43 | * The above copyright notice and this permission notice shall be
 44 | * included in all copies or substantial portions of the Software.
 45 | *
 46 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 47 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 48 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 49 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 50 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 51 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 52 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 53 | * OTHER DEALINGS IN THE SOFTWARE.
 54 | */
 55 | 
 56 | // namespace:
 57 | window["qlib"] = window.qlib || {};
 58 | 
 59 | (function() {
 60 | 
 61 | 
 62 | 	var SteinerCircles = function() {}
 63 | 
 64 | 	var p = SteinerCircles.prototype;
 65 | 
 66 | 	p.calculate = function( parentCircle, circleCount, ratio, rotation, startAngle  )
 67 | 	{
 68 | 		var i;
 69 | 
 70 | 		this.parentCircle = parentCircle;
 71 | 		this.circleCount = Math.max(3,circleCount);
 72 | 		this.ratio = ratio;
 73 | 		rotation = ( rotation == null ? 0 : rotation );
 74 | 		startAngle = ( startAngle == null ? 0 : startAngle );
 75 | 
 76 | 		var angleStep = Math.PI / circleCount;
 77 | 		var piFactor = Math.sin( angleStep );
 78 | 		var centerFactor = ( 1 - piFactor) / ( 1 + piFactor );
 79 | 
 80 | 		var radius = parentCircle.r;
 81 | 		var a = 2 * radius;
 82 | 		var b = a * centerFactor;
 83 | 		var c = ( a - b ) / 2;
 84 | 
 85 | 		var satelitesDistance = b + c;
 86 | 		var rotAngle = 0;
 87 | 
 88 | 		var center = new qlib.Vector2();
 89 | 		this.circles = [];
 90 | 
 91 | 		var points = [];
 92 | 		var angle;
 93 | 		for ( i = 0; i < circleCount; i++)
 94 | 		{
 95 | 			var angle = 2 * angleStep*i - rotation + startAngle;
 96 | 			points.push( new qlib.Vector2( Math.cos(angle+angleStep)*satelitesDistance, Math.sin(angle+angleStep)*satelitesDistance));
 97 | 			points.push( new qlib.Vector2( Math.cos(angle)*a, Math.sin(angle)*a));
 98 | 			points.push( new qlib.Vector2( Math.cos(angle)*b, Math.sin(angle)*b));
 99 | 		}
100 | 
101 | 
102 | 		this.inverter = new qlib.Vector2( parentCircle.r * ratio * Math.cos(rotation), parentCircle.r * ratio * Math.sin(rotation) );
103 | 
104 | 		var innerPoints = [];
105 | 		var outerPoints = [];
106 | 		var p;
107 | 		var j;
108 | 		var p1;
109 | 		var p2;
110 | 		var p3;
111 | 
112 | 		for ( i = 0;  i < circleCount; i++)
113 | 		{
114 | 			p1 = this.invert( points[ i * 3 ] );
115 | 			p2 = this.invert( points[ i * 3 + 1 ] );
116 | 			p3 = this.invert( points[ i * 3 + 2 ] );
117 | 
118 | 			innerPoints.push( p2 );
119 | 			outerPoints.push( p3 );
120 | 
121 | 			this.circles.push( qlib.CircleUtils.from3Points(p1, p2, p3) );
122 | 		}
123 | 
124 | 		this.circles.push( qlib.CircleUtils.from3Points( innerPoints[0],  innerPoints[1],  innerPoints[2] ) );
125 | 		this.outerCircle = qlib.CircleUtils.from3Points( outerPoints[0],  outerPoints[1],  outerPoints[2] );
126 | 
127 | 
128 | 		var scale =  parentCircle.r / this.outerCircle.r;
129 | 		var circle;
130 | 
131 | 
132 | 		for ( i = 0;  i < this.circles.length; i++)
133 | 		{
134 | 			circle = this.circles[i];
135 | 			circle.c.minus( this.outerCircle.c );
136 | 			circle.c.multiply( scale );
137 | 			circle.r *= scale;
138 | 			circle.c.plus( parentCircle.c );
139 | 		}
140 | 
141 | 		this.outerCircle.r *= scale;
142 | 		this.outerCircle.c.setValue( parentCircle.c );
143 | 
144 | 
145 | 
146 | 	}
147 | 
148 | 	p.invert = function( p )
149 | 	{
150 | 		var dx = p.x - this.inverter.x;
151 | 		var dy = p.y - this.inverter.y;
152 | 		var dxy = dx * dx + dy * dy ;
153 | 		if ( dxy == 0 ) dxy = 1 / Number.MAX_VALUE;
154 | 		return this.inverter.getPlus( new qlib.Vector2( dx  / dxy, dy / dxy) );
155 | 	}
156 | 
157 | 	p.draw = function( canvas )
158 | 	{
159 | 		for ( var i = 0;  i < this.circles.length; i++)
160 | 		{
161 | 			this.circles[i].draw(canvas);
162 | 		}
163 | 	}
164 | 
165 | 
166 | 
167 | 
168 | 
169 | 	/**
170 | 	 * Returns a string representation of this object.
171 | 	 * @method toString
172 | 	 * @return {String} a string representation of the instance.
173 | 	 **/
174 | 	p.toString = function() {
175 | 		return "SteinerCircles";
176 | 	}
177 | 
178 | 	qlib["SteinerCircles"] = SteinerCircles;
179 | }());
180 |
181 |
182 | 183 | 184 | 185 | 186 |
187 | 188 | 191 | 192 |
193 | 194 |
195 | Documentation generated by JSDoc 4.0.4 on Sat May 31 2025 06:36:44 GMT+0000 (Coordinated Universal Time) 196 |
197 | 198 | 199 | 200 | 201 | 202 | -------------------------------------------------------------------------------- /docs/app/1.0.0/geom_Point.js.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | JSDoc: Source: geom/Point.js 6 | 7 | 8 | 9 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 |

Source: geom/Point.js

21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 |
29 |
/**
 30 |  * Represents a point in a 2D coordinate system.
 31 |  * @class Point
 32 |  * @param {number} [x=0] - The x-coordinate.
 33 |  * @param {number} [y=0] - The y-coordinate.
 34 |  * @property {number} x - The x-coordinate.
 35 |  * @property {number} y - The y-coordinate.
 36 |  * @property {number} length - The distance from the origin (0,0) to this point.
 37 | */
 38 | 
 39 | // namespace:
 40 | window["qlib"] = window.qlib || {};
 41 | 
 42 | (function() {
 43 | 	/**
 44 | 	 * @constructor
 45 | 	 * @param {number} [x=0] - The x-coordinate.
 46 | 	 * @param {number} [y=0] - The y-coordinate.
 47 | 	 */
 48 | 	var Point = function( x, y ) {
 49 | 		this.initialize( x, y );
 50 | 	}
 51 | 
 52 | 	var p = Point.prototype;
 53 | 	/**
 54 | 	 * Initializes the Point object.
 55 | 	 * @param {number} [x=0] - The x-coordinate.
 56 | 	 * @param {number} [y=0] - The y-coordinate.
 57 | 	 */
 58 | 	p.initialize = function (x, y) {
 59 | 		this.x = x || 0;
 60 | 		this.y = y || 0;
 61 | 
 62 | 		this.__defineGetter__("length", function(){return Math.sqrt(this.x * this.x + this.y * this.y);});
 63 | 	}
 64 | 
 65 | 	/**
 66 | 	* Adds the coordinates of another point to the coordinates of this point to create a new point.
 67 | 	* @param {qlib.Point} v The point to be added.
 68 | 	* @returns {qlib.Point} The new Point.
 69 | 	*/
 70 | 	p.add = function(v) {
 71 | 		return new qlib.Point(this.x + v.x, this.y + v.y);
 72 | 	}
 73 | 
 74 | 	/**
 75 | 	* Creates a copy of this Point object.
 76 | 	* @returns {qlib.Point} The new Point.
 77 | 	*/
 78 | 	p.clone = function() {
 79 | 		return new qlib.Point(this.x, this.y);
 80 | 	}
 81 | 
 82 | 
 83 | 	/**
 84 | 	* Determines whether two points are equal.
 85 | 	* @param {qlib.Point} toCompare The point to be compared.
 86 | 	* @returns {boolean} True if the object is equal to this Point object; false if it is not equal.
 87 | 	*/
 88 | 	p.equals = function(toCompare) {
 89 | 		return this.x == toCompare.x && this.y == toCompare.y;
 90 | 	}
 91 | 
 92 | 
 93 | 	/**
 94 | 	* Scales the line segment between (0,0) and the current point to a set length.
 95 | 	* @param {number} thickness The scaling value. For example, if the current point is (0,5), and you normalize it to 1, the point returned is at (0,1).
 96 | 	*/
 97 | 	p.normalize = function(thickness) {
 98 | 		var ratio = thickness / this.length;
 99 | 		this.x *= ratio;
100 | 		this.y *= ratio;
101 | 	}
102 | 
103 | 	/**
104 | 	* Offsets the Point object by the specified amount.
105 | 	* @param {number} dx The amount by which to offset the horizontal coordinate, x.
106 | 	* @param {number} dy The amount by which to offset the vertical coordinate, y.
107 | 	*/
108 | 	p.offset = function(dx, dy) {
109 | 		this.x += dx;
110 | 		this.y += dy;
111 | 	}
112 | 
113 | 
114 | 	/**
115 | 	* Subtracts the coordinates of another point from the coordinates of this point to create a new point.
116 | 	* @param {qlib.Point} v The point to be subtracted.
117 | 	* @returns {qlib.Point} The new point.
118 | 	*/
119 | 	p.subtract = function(v) {
120 | 		return new qlib.Point( this.x - v.x, this.y - v.y );
121 | 	}
122 | 
123 | 	/**
124 | 	 * Returns a string representation of this object.
125 | 	 * @returns {string} a string representation of the instance.
126 | 	 **/
127 | 	p.toString = function() {
128 | 		return "qlib.Point("+this.x+","+this.y+")";
129 | 	}
130 | 
131 | 	/**
132 | 	* Returns the distance between pt1 and pt2.
133 | 	* @static
134 | 	* @param {qlib.Point} pt1 The first point.
135 | 	* @param {qlib.Point} pt2 The second point.
136 | 	* @returns {number} The distance between the first and second points.
137 | 	*/
138 | 	Point.distance = function(pt1, pt2) {
139 | 		var dx = pt2.x - pt1.x;
140 | 		var dy = pt2.y - pt1.y;
141 | 		return Math.sqrt(dx * dx + dy * dy);
142 | 	}
143 | 
144 | 	/**
145 | 	* Determines a point between two specified points.
146 | 	* @static
147 | 	* @param {qlib.Point} pt1 The first point.
148 | 	* @param {qlib.Point} pt2 The second point.
149 | 	* @param {number} f The level of interpolation between the two points. Indicates where the new point will be, along the line between pt1 and pt2. If f=1, pt1 is returned; if f=0, pt2 is returned.
150 | 	* @returns {qlib.Point} The new, interpolated point.
151 | 	*/
152 | 
153 | 	Point.interpolate = function(pt1, pt2, f) {
154 | 		var pt = new qlib.Point();
155 | 		pt.x = pt1.x + f * (pt2.x - pt1.x);
156 | 		pt.y = pt1.y + f * (pt2.y - pt1.y);
157 | 		return pt;
158 | 	}
159 | 	/**
160 | 	* Converts a pair of polar coordinates to a Cartesian point coordinate.
161 | 	* @static
162 | 	* @param {number} len The length coordinate of the polar pair.
163 | 	* @param {number} angle The angle, in radians, of the polar pair.
164 | 	* @returns {qlib.Point} The Cartesian point.
165 | 	*/
166 | 	Point.polar = function(len, angle) {
167 | 		return new qlib.Point(len * Math.cos(angle), len * Math.sin(angle));
168 | 	}
169 | 
170 | 	qlib["Point"] = Point;
171 | 
172 | }());
173 | 
174 | 
175 |
176 |
177 | 178 | 179 | 180 | 181 |
182 | 183 | 186 | 187 |
188 | 189 |
190 | Documentation generated by JSDoc 4.0.4 on Sat May 31 2025 06:36:44 GMT+0000 (Coordinated Universal Time) 191 |
192 | 193 | 194 | 195 | 196 | 197 | -------------------------------------------------------------------------------- /docs/app/1.0.0/Vector2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | JSDoc: Class: Vector2 6 | 7 | 8 | 9 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 |

Class: Vector2

21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 | 29 |
30 | 31 |

Vector2(arg1opt, arg2opt)

32 | 33 | 34 |
35 | 36 |
37 |
38 | 39 | 40 | 41 | 42 | 43 | 44 |

new Vector2(arg1opt, arg2opt)

45 | 46 | 47 | 48 | 49 | 50 | 51 |
52 | Represents a 2D vector. 53 |
54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 |
Parameters:
64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 107 | 108 | 109 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 140 | 141 | 142 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 |
NameTypeAttributesDescription
arg1 94 | 95 | 96 | number 97 | | 98 | 99 | qlib.Point 100 | | 101 | 102 | Array.<qlib.Point> 103 | 104 | 105 | 106 | 110 | 111 | <optional>
112 | 113 | 114 | 115 | 116 | 117 |
If a number, the x-coordinate. If a Point, the vector will be initialized with the Point's coordinates. If an array of two Points, the vector will be the difference between the two points (args[1] - args[0]).
arg2 133 | 134 | 135 | number 136 | 137 | 138 | 139 | 143 | 144 | <optional>
145 | 146 | 147 | 148 | 149 | 150 |
If arg1 is a number, this is the y-coordinate.
161 | 162 | 163 | 164 | 165 | 166 | 167 |
Properties:
168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 |
NameTypeDescription
x 197 | 198 | 199 | number 200 | 201 | 202 | 203 | The x-component of the vector.
y 220 | 221 | 222 | number 223 | 224 | 225 | 226 | The y-component of the vector.
length 243 | 244 | 245 | number 246 | 247 | 248 | 249 | The length (magnitude) of the vector.
261 | 262 | 263 | 264 | 265 |
266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 |
Source:
293 |
296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 |
304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 |
326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 |
347 | 348 |
349 | 350 | 351 | 352 | 353 |
354 | 355 | 358 | 359 |
360 | 361 |
362 | Documentation generated by JSDoc 4.0.4 on Sat May 31 2025 06:36:44 GMT+0000 (Coordinated Universal Time) 363 |
364 | 365 | 366 | 367 | 368 | -------------------------------------------------------------------------------- /docs/app/1.0.0/geom_Rectangle.js.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | JSDoc: Source: geom/Rectangle.js 6 | 7 | 8 | 9 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 |

Source: geom/Rectangle.js

21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 |
29 |
/*
 30 | * Rectangle
 31 | *
 32 | * Copyright (c) 2013 Mario Klingemann
 33 | *
 34 | * Permission is hereby granted, free of charge, to any person
 35 | * obtaining a copy of this software and associated documentation
 36 | * files (the "Software"), to deal in the Software without
 37 | * restriction, including without limitation the rights to use,
 38 | * copy, modify, merge, publish, distribute, sublicense, and/or sell
 39 | * copies of the Software, and to permit persons to whom the
 40 | * Software is furnished to do so, subject to the following
 41 | * conditions:
 42 | *
 43 | * The above copyright notice and this permission notice shall be
 44 | * included in all copies or substantial portions of the Software.
 45 | *
 46 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 47 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 48 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 49 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 50 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 51 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 52 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 53 | * OTHER DEALINGS IN THE SOFTWARE.
 54 | */
 55 | 
 56 | // namespace:
 57 | window["qlib"] = window.qlib || {};
 58 | 
 59 | (function() {
 60 | 
 61 | var Rectangle = function( x, y, width, height ) {
 62 |   this.initialize( x, y, width, height );
 63 | }
 64 | 
 65 | var p = Rectangle.prototype = new qlib.GeometricShape();
 66 | 
 67 | // public properties:
 68 | 	p.type = "Rectangle";
 69 | 
 70 | 
 71 | 	// constructor:
 72 | 	/**
 73 | 	 * Initialization method.
 74 | 	 * @method initialize
 75 | 	 * @protected
 76 | 	*/
 77 | 	p.initialize = function( x, y, width, height ) {
 78 | 		this.x = (x == null ? 0 : x);
 79 | 		this.y = (y == null ? 0 : y);
 80 | 		this.width = (width == null ? 0 : width);
 81 | 		this.height = (height == null ? 0 : height);
 82 | 		this.fixValues();
 83 | 	}
 84 | 
 85 | 	p.fixValues = function ()
 86 | 	{
 87 | 		if ( this.width < 0 )
 88 | 		{
 89 | 			this.x += this.width;
 90 | 			this.width *= -1;
 91 | 		}
 92 | 		if ( this.height < 0 )
 93 | 		{
 94 | 			this.y += this.height;
 95 | 			this.height *= -1;
 96 | 		}
 97 | 	}
 98 | 
 99 | 	p.scale = function( factorX, factorY, center )
100 | 	{
101 | 		if ( center == null ) center = new qlib.Vector2( this.x + this.width * 0.5, this.y + this.height * 0.5);
102 | 		var newXY = new qlib.Vector2( this.x, this.y).minus( center ).multiplyXY( factorX, factorY ).plus( center );
103 | 		this.x = newXY.x;
104 | 		this.y = newXY.y;
105 | 		this.width *= factorX;
106 | 		this.height *= factorY;
107 | 		this.fixValues();
108 | 		return this;
109 | 	}
110 | 
111 | 	p.union = function( rect )
112 | 	{
113 | 		if ( this.width == 0 || this.height == 0 )
114 | 		{
115 | 			return rect.clone();
116 | 		}
117 | 		if ( rect.width == 0 || rect.height == 0 )
118 | 		{
119 | 			return this.clone();
120 | 		}
121 | 		var minx = Math.min( this.x, rect.x );
122 | 		var miny = Math.min( this.y, rect.y );
123 | 		var maxx = Math.max( this.x + this.width, rect.x + rect.width);
124 | 		var maxy = Math.max( this.y + this.height, rect.y + rect.height);
125 | 		return new qlib.Rectangle( minx, miny, maxx - minx, maxy - miny );
126 | 
127 | 	}
128 | 
129 | 	p.intersection = function( rect )
130 | 	{
131 | 		if ( this.width == 0 || this.height == 0 )
132 | 		{
133 | 			return rect.clone();
134 | 		}
135 | 		if ( rect.width == 0 || rect.height == 0 )
136 | 		{
137 | 			return this.clone();
138 | 		}
139 | 		this.fixValues();
140 | 		rect.fixValues();
141 | 
142 | 		var minX = this.x > rect.x ? this.x : rect.x;
143 | 		var minY = this.y > rect.y ? this.y : rect.y;
144 | 		var maxX = Math.min(this.x + this.width, rect.x + rect.width);
145 | 		var maxY = Math.min(this.y + this.height, rect.y + rect.height);
146 | 		if ( minX >= maxX || minY >= maxY ) return new qlib.Rectangle( );
147 | 		return new qlib.Rectangle( minX, minY, maxX - minX, maxY - minY );
148 | 
149 | 	}
150 | 
151 | 	p.getCenter = function()
152 | 	{
153 | 		return new qlib.Vector2( this.x + this.width*0.5, this.y + this.height*0.5);
154 | 	}
155 | 
156 | 	p.__defineGetter__("topLeft", function(){return new qlib.Point(this.x,this.y);});
157 | 
158 | // public methods:
159 | 	/**
160 | 	 * Returns a clone of the Rectangle instance.
161 | 	 * @method clone
162 | 	 * @return {Rectangle} a clone of the Rectangle instance.
163 | 	 **/
164 | 	p.clone = function( deepClone ) {
165 | 		return new Rectangle( this.x, this.y, this.width, this.height );
166 | 	}
167 | 
168 | 	p.draw = function( graphics )
169 | 	{
170 | 		graphics.drawRect(this.x, this.y, this.width, this.height );
171 | 	}
172 | 
173 | 	/**
174 | 	 * Returns a string representation of this object.
175 | 	 * @method toString
176 | 	 * @return {String} a string representation of the instance.
177 | 	 **/
178 | 	p.toString = function() {
179 | 		return "qlib.Rectangle("+this.x+","+this.y+","+this.width+","+this.height+")";
180 | 	}
181 | 
182 | 	qlib["Rectangle"] = Rectangle;
183 | }());
184 |
185 |
186 | 187 | 188 | 189 | 190 |
191 | 192 | 195 | 196 |
197 | 198 |
199 | Documentation generated by JSDoc 4.0.4 on Sat May 31 2025 06:36:44 GMT+0000 (Coordinated Universal Time) 200 |
201 | 202 | 203 | 204 | 205 | 206 | -------------------------------------------------------------------------------- /docs/styles/jsdoc-default.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'Open Sans'; 3 | font-weight: normal; 4 | font-style: normal; 5 | src: url('../fonts/OpenSans-Regular-webfont.eot'); 6 | src: 7 | local('Open Sans'), 8 | local('OpenSans'), 9 | url('../fonts/OpenSans-Regular-webfont.eot?#iefix') format('embedded-opentype'), 10 | url('../fonts/OpenSans-Regular-webfont.woff') format('woff'), 11 | url('../fonts/OpenSans-Regular-webfont.svg#open_sansregular') format('svg'); 12 | } 13 | 14 | @font-face { 15 | font-family: 'Open Sans Light'; 16 | font-weight: normal; 17 | font-style: normal; 18 | src: url('../fonts/OpenSans-Light-webfont.eot'); 19 | src: 20 | local('Open Sans Light'), 21 | local('OpenSans Light'), 22 | url('../fonts/OpenSans-Light-webfont.eot?#iefix') format('embedded-opentype'), 23 | url('../fonts/OpenSans-Light-webfont.woff') format('woff'), 24 | url('../fonts/OpenSans-Light-webfont.svg#open_sanslight') format('svg'); 25 | } 26 | 27 | html 28 | { 29 | overflow: auto; 30 | background-color: #fff; 31 | font-size: 14px; 32 | } 33 | 34 | body 35 | { 36 | font-family: 'Open Sans', sans-serif; 37 | line-height: 1.5; 38 | color: #4d4e53; 39 | background-color: white; 40 | } 41 | 42 | a, a:visited, a:active { 43 | color: #0095dd; 44 | text-decoration: none; 45 | } 46 | 47 | a:hover { 48 | text-decoration: underline; 49 | } 50 | 51 | header 52 | { 53 | display: block; 54 | padding: 0px 4px; 55 | } 56 | 57 | tt, code, kbd, samp { 58 | font-family: Consolas, Monaco, 'Andale Mono', monospace; 59 | } 60 | 61 | .class-description { 62 | font-size: 130%; 63 | line-height: 140%; 64 | margin-bottom: 1em; 65 | margin-top: 1em; 66 | } 67 | 68 | .class-description:empty { 69 | margin: 0; 70 | } 71 | 72 | #main { 73 | float: left; 74 | width: 70%; 75 | } 76 | 77 | article dl { 78 | margin-bottom: 40px; 79 | } 80 | 81 | article img { 82 | max-width: 100%; 83 | } 84 | 85 | section 86 | { 87 | display: block; 88 | background-color: #fff; 89 | padding: 12px 24px; 90 | border-bottom: 1px solid #ccc; 91 | margin-right: 30px; 92 | } 93 | 94 | .variation { 95 | display: none; 96 | } 97 | 98 | .signature-attributes { 99 | font-size: 60%; 100 | color: #aaa; 101 | font-style: italic; 102 | font-weight: lighter; 103 | } 104 | 105 | nav 106 | { 107 | display: block; 108 | float: right; 109 | margin-top: 28px; 110 | width: 30%; 111 | box-sizing: border-box; 112 | border-left: 1px solid #ccc; 113 | padding-left: 16px; 114 | } 115 | 116 | nav ul { 117 | font-family: 'Lucida Grande', 'Lucida Sans Unicode', arial, sans-serif; 118 | font-size: 100%; 119 | line-height: 17px; 120 | padding: 0; 121 | margin: 0; 122 | list-style-type: none; 123 | } 124 | 125 | nav ul a, nav ul a:visited, nav ul a:active { 126 | font-family: Consolas, Monaco, 'Andale Mono', monospace; 127 | line-height: 18px; 128 | color: #4D4E53; 129 | } 130 | 131 | nav h3 { 132 | margin-top: 12px; 133 | } 134 | 135 | nav li { 136 | margin-top: 6px; 137 | } 138 | 139 | footer { 140 | display: block; 141 | padding: 6px; 142 | margin-top: 12px; 143 | font-style: italic; 144 | font-size: 90%; 145 | } 146 | 147 | h1, h2, h3, h4 { 148 | font-weight: 200; 149 | margin: 0; 150 | } 151 | 152 | h1 153 | { 154 | font-family: 'Open Sans Light', sans-serif; 155 | font-size: 48px; 156 | letter-spacing: -2px; 157 | margin: 12px 24px 20px; 158 | } 159 | 160 | h2, h3.subsection-title 161 | { 162 | font-size: 30px; 163 | font-weight: 700; 164 | letter-spacing: -1px; 165 | margin-bottom: 12px; 166 | } 167 | 168 | h3 169 | { 170 | font-size: 24px; 171 | letter-spacing: -0.5px; 172 | margin-bottom: 12px; 173 | } 174 | 175 | h4 176 | { 177 | font-size: 18px; 178 | letter-spacing: -0.33px; 179 | margin-bottom: 12px; 180 | color: #4d4e53; 181 | } 182 | 183 | h5, .container-overview .subsection-title 184 | { 185 | font-size: 120%; 186 | font-weight: bold; 187 | letter-spacing: -0.01em; 188 | margin: 8px 0 3px 0; 189 | } 190 | 191 | h6 192 | { 193 | font-size: 100%; 194 | letter-spacing: -0.01em; 195 | margin: 6px 0 3px 0; 196 | font-style: italic; 197 | } 198 | 199 | table 200 | { 201 | border-spacing: 0; 202 | border: 0; 203 | border-collapse: collapse; 204 | } 205 | 206 | td, th 207 | { 208 | border: 1px solid #ddd; 209 | margin: 0px; 210 | text-align: left; 211 | vertical-align: top; 212 | padding: 4px 6px; 213 | display: table-cell; 214 | } 215 | 216 | thead tr 217 | { 218 | background-color: #ddd; 219 | font-weight: bold; 220 | } 221 | 222 | th { border-right: 1px solid #aaa; } 223 | tr > th:last-child { border-right: 1px solid #ddd; } 224 | 225 | .ancestors, .attribs { color: #999; } 226 | .ancestors a, .attribs a 227 | { 228 | color: #999 !important; 229 | text-decoration: none; 230 | } 231 | 232 | .clear 233 | { 234 | clear: both; 235 | } 236 | 237 | .important 238 | { 239 | font-weight: bold; 240 | color: #950B02; 241 | } 242 | 243 | .yes-def { 244 | text-indent: -1000px; 245 | } 246 | 247 | .type-signature { 248 | color: #aaa; 249 | } 250 | 251 | .name, .signature { 252 | font-family: Consolas, Monaco, 'Andale Mono', monospace; 253 | } 254 | 255 | .details { margin-top: 14px; border-left: 2px solid #DDD; } 256 | .details dt { width: 120px; float: left; padding-left: 10px; padding-top: 6px; } 257 | .details dd { margin-left: 70px; } 258 | .details ul { margin: 0; } 259 | .details ul { list-style-type: none; } 260 | .details li { margin-left: 30px; padding-top: 6px; } 261 | .details pre.prettyprint { margin: 0 } 262 | .details .object-value { padding-top: 0; } 263 | 264 | .description { 265 | margin-bottom: 1em; 266 | margin-top: 1em; 267 | } 268 | 269 | .code-caption 270 | { 271 | font-style: italic; 272 | font-size: 107%; 273 | margin: 0; 274 | } 275 | 276 | .source 277 | { 278 | border: 1px solid #ddd; 279 | width: 80%; 280 | overflow: auto; 281 | } 282 | 283 | .prettyprint.source { 284 | width: inherit; 285 | } 286 | 287 | .source code 288 | { 289 | font-size: 100%; 290 | line-height: 18px; 291 | display: block; 292 | padding: 4px 12px; 293 | margin: 0; 294 | background-color: #fff; 295 | color: #4D4E53; 296 | } 297 | 298 | .prettyprint code span.line 299 | { 300 | display: inline-block; 301 | } 302 | 303 | .prettyprint.linenums 304 | { 305 | padding-left: 70px; 306 | -webkit-user-select: none; 307 | -moz-user-select: none; 308 | -ms-user-select: none; 309 | user-select: none; 310 | } 311 | 312 | .prettyprint.linenums ol 313 | { 314 | padding-left: 0; 315 | } 316 | 317 | .prettyprint.linenums li 318 | { 319 | border-left: 3px #ddd solid; 320 | } 321 | 322 | .prettyprint.linenums li.selected, 323 | .prettyprint.linenums li.selected * 324 | { 325 | background-color: lightyellow; 326 | } 327 | 328 | .prettyprint.linenums li * 329 | { 330 | -webkit-user-select: text; 331 | -moz-user-select: text; 332 | -ms-user-select: text; 333 | user-select: text; 334 | } 335 | 336 | .params .name, .props .name, .name code { 337 | color: #4D4E53; 338 | font-family: Consolas, Monaco, 'Andale Mono', monospace; 339 | font-size: 100%; 340 | } 341 | 342 | .params td.description > p:first-child, 343 | .props td.description > p:first-child 344 | { 345 | margin-top: 0; 346 | padding-top: 0; 347 | } 348 | 349 | .params td.description > p:last-child, 350 | .props td.description > p:last-child 351 | { 352 | margin-bottom: 0; 353 | padding-bottom: 0; 354 | } 355 | 356 | .disabled { 357 | color: #454545; 358 | } 359 | -------------------------------------------------------------------------------- /docs/app/1.0.0/styles/jsdoc-default.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'Open Sans'; 3 | font-weight: normal; 4 | font-style: normal; 5 | src: url('../fonts/OpenSans-Regular-webfont.eot'); 6 | src: 7 | local('Open Sans'), 8 | local('OpenSans'), 9 | url('../fonts/OpenSans-Regular-webfont.eot?#iefix') format('embedded-opentype'), 10 | url('../fonts/OpenSans-Regular-webfont.woff') format('woff'), 11 | url('../fonts/OpenSans-Regular-webfont.svg#open_sansregular') format('svg'); 12 | } 13 | 14 | @font-face { 15 | font-family: 'Open Sans Light'; 16 | font-weight: normal; 17 | font-style: normal; 18 | src: url('../fonts/OpenSans-Light-webfont.eot'); 19 | src: 20 | local('Open Sans Light'), 21 | local('OpenSans Light'), 22 | url('../fonts/OpenSans-Light-webfont.eot?#iefix') format('embedded-opentype'), 23 | url('../fonts/OpenSans-Light-webfont.woff') format('woff'), 24 | url('../fonts/OpenSans-Light-webfont.svg#open_sanslight') format('svg'); 25 | } 26 | 27 | html 28 | { 29 | overflow: auto; 30 | background-color: #fff; 31 | font-size: 14px; 32 | } 33 | 34 | body 35 | { 36 | font-family: 'Open Sans', sans-serif; 37 | line-height: 1.5; 38 | color: #4d4e53; 39 | background-color: white; 40 | } 41 | 42 | a, a:visited, a:active { 43 | color: #0095dd; 44 | text-decoration: none; 45 | } 46 | 47 | a:hover { 48 | text-decoration: underline; 49 | } 50 | 51 | header 52 | { 53 | display: block; 54 | padding: 0px 4px; 55 | } 56 | 57 | tt, code, kbd, samp { 58 | font-family: Consolas, Monaco, 'Andale Mono', monospace; 59 | } 60 | 61 | .class-description { 62 | font-size: 130%; 63 | line-height: 140%; 64 | margin-bottom: 1em; 65 | margin-top: 1em; 66 | } 67 | 68 | .class-description:empty { 69 | margin: 0; 70 | } 71 | 72 | #main { 73 | float: left; 74 | width: 70%; 75 | } 76 | 77 | article dl { 78 | margin-bottom: 40px; 79 | } 80 | 81 | article img { 82 | max-width: 100%; 83 | } 84 | 85 | section 86 | { 87 | display: block; 88 | background-color: #fff; 89 | padding: 12px 24px; 90 | border-bottom: 1px solid #ccc; 91 | margin-right: 30px; 92 | } 93 | 94 | .variation { 95 | display: none; 96 | } 97 | 98 | .signature-attributes { 99 | font-size: 60%; 100 | color: #aaa; 101 | font-style: italic; 102 | font-weight: lighter; 103 | } 104 | 105 | nav 106 | { 107 | display: block; 108 | float: right; 109 | margin-top: 28px; 110 | width: 30%; 111 | box-sizing: border-box; 112 | border-left: 1px solid #ccc; 113 | padding-left: 16px; 114 | } 115 | 116 | nav ul { 117 | font-family: 'Lucida Grande', 'Lucida Sans Unicode', arial, sans-serif; 118 | font-size: 100%; 119 | line-height: 17px; 120 | padding: 0; 121 | margin: 0; 122 | list-style-type: none; 123 | } 124 | 125 | nav ul a, nav ul a:visited, nav ul a:active { 126 | font-family: Consolas, Monaco, 'Andale Mono', monospace; 127 | line-height: 18px; 128 | color: #4D4E53; 129 | } 130 | 131 | nav h3 { 132 | margin-top: 12px; 133 | } 134 | 135 | nav li { 136 | margin-top: 6px; 137 | } 138 | 139 | footer { 140 | display: block; 141 | padding: 6px; 142 | margin-top: 12px; 143 | font-style: italic; 144 | font-size: 90%; 145 | } 146 | 147 | h1, h2, h3, h4 { 148 | font-weight: 200; 149 | margin: 0; 150 | } 151 | 152 | h1 153 | { 154 | font-family: 'Open Sans Light', sans-serif; 155 | font-size: 48px; 156 | letter-spacing: -2px; 157 | margin: 12px 24px 20px; 158 | } 159 | 160 | h2, h3.subsection-title 161 | { 162 | font-size: 30px; 163 | font-weight: 700; 164 | letter-spacing: -1px; 165 | margin-bottom: 12px; 166 | } 167 | 168 | h3 169 | { 170 | font-size: 24px; 171 | letter-spacing: -0.5px; 172 | margin-bottom: 12px; 173 | } 174 | 175 | h4 176 | { 177 | font-size: 18px; 178 | letter-spacing: -0.33px; 179 | margin-bottom: 12px; 180 | color: #4d4e53; 181 | } 182 | 183 | h5, .container-overview .subsection-title 184 | { 185 | font-size: 120%; 186 | font-weight: bold; 187 | letter-spacing: -0.01em; 188 | margin: 8px 0 3px 0; 189 | } 190 | 191 | h6 192 | { 193 | font-size: 100%; 194 | letter-spacing: -0.01em; 195 | margin: 6px 0 3px 0; 196 | font-style: italic; 197 | } 198 | 199 | table 200 | { 201 | border-spacing: 0; 202 | border: 0; 203 | border-collapse: collapse; 204 | } 205 | 206 | td, th 207 | { 208 | border: 1px solid #ddd; 209 | margin: 0px; 210 | text-align: left; 211 | vertical-align: top; 212 | padding: 4px 6px; 213 | display: table-cell; 214 | } 215 | 216 | thead tr 217 | { 218 | background-color: #ddd; 219 | font-weight: bold; 220 | } 221 | 222 | th { border-right: 1px solid #aaa; } 223 | tr > th:last-child { border-right: 1px solid #ddd; } 224 | 225 | .ancestors, .attribs { color: #999; } 226 | .ancestors a, .attribs a 227 | { 228 | color: #999 !important; 229 | text-decoration: none; 230 | } 231 | 232 | .clear 233 | { 234 | clear: both; 235 | } 236 | 237 | .important 238 | { 239 | font-weight: bold; 240 | color: #950B02; 241 | } 242 | 243 | .yes-def { 244 | text-indent: -1000px; 245 | } 246 | 247 | .type-signature { 248 | color: #aaa; 249 | } 250 | 251 | .name, .signature { 252 | font-family: Consolas, Monaco, 'Andale Mono', monospace; 253 | } 254 | 255 | .details { margin-top: 14px; border-left: 2px solid #DDD; } 256 | .details dt { width: 120px; float: left; padding-left: 10px; padding-top: 6px; } 257 | .details dd { margin-left: 70px; } 258 | .details ul { margin: 0; } 259 | .details ul { list-style-type: none; } 260 | .details li { margin-left: 30px; padding-top: 6px; } 261 | .details pre.prettyprint { margin: 0 } 262 | .details .object-value { padding-top: 0; } 263 | 264 | .description { 265 | margin-bottom: 1em; 266 | margin-top: 1em; 267 | } 268 | 269 | .code-caption 270 | { 271 | font-style: italic; 272 | font-size: 107%; 273 | margin: 0; 274 | } 275 | 276 | .source 277 | { 278 | border: 1px solid #ddd; 279 | width: 80%; 280 | overflow: auto; 281 | } 282 | 283 | .prettyprint.source { 284 | width: inherit; 285 | } 286 | 287 | .source code 288 | { 289 | font-size: 100%; 290 | line-height: 18px; 291 | display: block; 292 | padding: 4px 12px; 293 | margin: 0; 294 | background-color: #fff; 295 | color: #4D4E53; 296 | } 297 | 298 | .prettyprint code span.line 299 | { 300 | display: inline-block; 301 | } 302 | 303 | .prettyprint.linenums 304 | { 305 | padding-left: 70px; 306 | -webkit-user-select: none; 307 | -moz-user-select: none; 308 | -ms-user-select: none; 309 | user-select: none; 310 | } 311 | 312 | .prettyprint.linenums ol 313 | { 314 | padding-left: 0; 315 | } 316 | 317 | .prettyprint.linenums li 318 | { 319 | border-left: 3px #ddd solid; 320 | } 321 | 322 | .prettyprint.linenums li.selected, 323 | .prettyprint.linenums li.selected * 324 | { 325 | background-color: lightyellow; 326 | } 327 | 328 | .prettyprint.linenums li * 329 | { 330 | -webkit-user-select: text; 331 | -moz-user-select: text; 332 | -ms-user-select: text; 333 | user-select: text; 334 | } 335 | 336 | .params .name, .props .name, .name code { 337 | color: #4D4E53; 338 | font-family: Consolas, Monaco, 'Andale Mono', monospace; 339 | font-size: 100%; 340 | } 341 | 342 | .params td.description > p:first-child, 343 | .props td.description > p:first-child 344 | { 345 | margin-top: 0; 346 | padding-top: 0; 347 | } 348 | 349 | .params td.description > p:last-child, 350 | .props td.description > p:last-child 351 | { 352 | margin-bottom: 0; 353 | padding-bottom: 0; 354 | } 355 | 356 | .disabled { 357 | color: #454545; 358 | } 359 | -------------------------------------------------------------------------------- /src/qlib/geom/Point.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Represents a point in a two-dimensional Cartesian coordinate system. 3 | * It can also be used to represent a two-dimensional vector. 4 | * 5 | * @class Point 6 | * @param {number} [x=0] - The x-coordinate of the point. Defaults to 0 if not specified. 7 | * @param {number} [y=0] - The y-coordinate of the point. Defaults to 0 if not specified. 8 | * 9 | * @property {number} x - The x-coordinate of the point. 10 | * @property {number} y - The y-coordinate of the point. 11 | * @property {number} length - [read-only] The length of the vector from the origin (0,0) to this point. 12 | * This is a getter property. 13 | */ 14 | // namespace: 15 | window["qlib"] = window.qlib || {}; 16 | 17 | (function() { 18 | /** 19 | * Constructs a new Point instance. 20 | * @constructor 21 | * @param {number} [x=0] - The x-coordinate of the point. Defaults to 0. 22 | * @param {number} [y=0] - The y-coordinate of the point. Defaults to 0. 23 | */ 24 | var Point = function( x, y ) { 25 | this.initialize( x, y ); 26 | } 27 | 28 | var p = Point.prototype; 29 | 30 | /** 31 | * @property {number} x - The x-coordinate of the point. 32 | */ 33 | // p.x = 0; // Documented in the class description 34 | 35 | /** 36 | * @property {number} y - The y-coordinate of the point. 37 | */ 38 | // p.y = 0; // Documented in the class description 39 | 40 | /** 41 | * @property {number} length - [read-only] The length of the vector from the origin (0,0) to this point. 42 | * This is a getter property, calculated on demand. 43 | */ 44 | // p.length defined by __defineGetter__ 45 | 46 | /** 47 | * Initializes the Point object with the given x and y coordinates. 48 | * This method is called by the constructor. 49 | * It also defines a getter for the `length` property. 50 | * 51 | * @method initialize 52 | * @param {number} [x=0] - The x-coordinate for the point. Defaults to 0. 53 | * @param {number} [y=0] - The y-coordinate for the point. Defaults to 0. 54 | * @returns {void} 55 | */ 56 | p.initialize = function (x, y) { 57 | this.x = x || 0; 58 | this.y = y || 0; 59 | 60 | // Defines the 'length' property as a getter. 61 | // This means 'length' is calculated on demand and is read-only. 62 | this.__defineGetter__("length", function(){return Math.sqrt(this.x * this.x + this.y * this.y);}); 63 | } 64 | 65 | /** 66 | * Adds the coordinates of another point to the coordinates of this point. 67 | * Returns a new Point instance with the result. This point is not modified. 68 | * 69 | * @method add 70 | * @param {qlib.Point} v - The point whose coordinates are to be added to this point. 71 | * @returns {qlib.Point} A new Point instance representing the sum of the two points. 72 | */ 73 | p.add = function(v) { 74 | return new qlib.Point(this.x + v.x, this.y + v.y); 75 | } 76 | 77 | /** 78 | * Creates a new Point instance with the same x and y coordinates as this point. 79 | * 80 | * @method clone 81 | * @returns {qlib.Point} A new Point instance that is a copy of this point. 82 | */ 83 | p.clone = function() { 84 | return new qlib.Point(this.x, this.y); 85 | } 86 | 87 | 88 | /** 89 | * Compares this Point with another Point to determine if they have the same x and y coordinates. 90 | * 91 | * @method equals 92 | * @param {qlib.Point} toCompare - The Point instance to compare with this point. 93 | * @returns {boolean} True if the x and y coordinates of both points are equal, otherwise false. 94 | */ 95 | p.equals = function(toCompare) { 96 | return this.x == toCompare.x && this.y == toCompare.y; 97 | } 98 | 99 | 100 | /** 101 | * Scales this point (interpreted as a vector from the origin) to a specific length. 102 | * This method modifies the current Point instance. 103 | * For example, if the current point is (0, 5), normalizing it to a length of 1 will result in the point (0, 1). 104 | * 105 | * @method normalize 106 | * @param {number} thickness - The desired length for the vector. 107 | * @returns {void} 108 | */ 109 | p.normalize = function(thickness) { 110 | var ratio = thickness / this.length; 111 | this.x *= ratio; 112 | this.y *= ratio; 113 | } 114 | 115 | /** 116 | * Modifies this point by adding the specified delta values to its x and y coordinates. 117 | * 118 | * @method offset 119 | * @param {number} dx - The amount to add to the x-coordinate. 120 | * @param {number} dy - The amount to add to the y-coordinate. 121 | * @returns {void} 122 | */ 123 | p.offset = function(dx, dy) { 124 | this.x += dx; 125 | this.y += dy; 126 | } 127 | 128 | 129 | /** 130 | * Subtracts the coordinates of another point from the coordinates of this point. 131 | * Returns a new Point instance with the result. This point is not modified. 132 | * 133 | * @method subtract 134 | * @param {qlib.Point} v - The point whose coordinates are to be subtracted from this point. 135 | * @returns {qlib.Point} A new Point instance representing the difference between the two points. 136 | */ 137 | p.subtract = function(v) { 138 | return new qlib.Point( this.x - v.x, this.y - v.y ); 139 | } 140 | 141 | /** 142 | * Returns a string representation of this Point object. 143 | * The format is "qlib.Point(x,y)". 144 | * 145 | * @method toString 146 | * @returns {string} A string representation of the Point instance. 147 | **/ 148 | p.toString = function() { 149 | return "qlib.Point("+this.x+","+this.y+")"; 150 | } 151 | 152 | /** 153 | * Calculates the Euclidean distance between two Point instances. 154 | * 155 | * @method distance 156 | * @static 157 | * @param {qlib.Point} pt1 - The first Point instance. 158 | * @param {qlib.Point} pt2 - The second Point instance. 159 | * @returns {number} The distance between the two points. 160 | */ 161 | Point.distance = function(pt1, pt2) { 162 | var dx = pt2.x - pt1.x; 163 | var dy = pt2.y - pt1.y; 164 | return Math.sqrt(dx * dx + dy * dy); 165 | } 166 | 167 | /** 168 | * Creates a new Point instance by interpolating between two other points. 169 | * The parameter `f` determines the interpolation amount. A value of 0.0 will result in a point equal to `pt1`, 170 | * while a value of 1.0 will result in a point equal to `pt2`. Values between 0.0 and 1.0 will result in a point 171 | * along the line segment connecting `pt1` and `pt2`. 172 | * 173 | * @method interpolate 174 | * @static 175 | * @param {qlib.Point} pt1 - The first Point instance (interpolation start). 176 | * @param {qlib.Point} pt2 - The second Point instance (interpolation end). 177 | * @param {number} f - The interpolation factor, typically between 0.0 and 1.0. 178 | * If f=0, a point equal to pt2 is returned (Note: original docs said f=1 -> pt1, f=0 -> pt2, but the code implements f=0 -> pt1, f=1 -> pt2. Corrected to match code logic: f=0 -> pt1, f=1 -> pt2. Re-evaluating: The code is `pt1.x + f * (pt2.x - pt1.x)`. If f=0, result is `pt1.x`. If f=1, result is `pt1.x + pt2.x - pt1.x = pt2.x`. So, f=0 returns pt1, f=1 returns pt2. The original JSDoc was `If f=1, pt1 is returned; if f=0, pt2 is returned.` which is the inverse. I will correct the description to match the code.) 179 | * If f=0, `pt1` is returned; if f=1, `pt2` is returned. 180 | * @returns {qlib.Point} A new Point instance representing the interpolated point. 181 | */ 182 | Point.interpolate = function(pt1, pt2, f) { 183 | var pt = new qlib.Point(); 184 | pt.x = pt1.x + f * (pt2.x - pt1.x); // if f=0, x = pt1.x; if f=1, x = pt2.x 185 | pt.y = pt1.y + f * (pt2.y - pt1.y); // if f=0, y = pt1.y; if f=1, y = pt2.y 186 | return pt; 187 | } 188 | 189 | /** 190 | * Converts a pair of polar coordinates (length and angle) to Cartesian (x,y) coordinates. 191 | * 192 | * @method polar 193 | * @static 194 | * @param {number} len - The length component of the polar coordinate. 195 | * @param {number} angle - The angle component of the polar coordinate, in radians. 196 | * @returns {qlib.Point} A new Point instance representing the Cartesian coordinates. 197 | */ 198 | Point.polar = function(len, angle) { 199 | return new qlib.Point(len * Math.cos(angle), len * Math.sin(angle)); 200 | } 201 | 202 | qlib["Point"] = Point; 203 | 204 | }()); 205 | 206 | -------------------------------------------------------------------------------- /docs/app/1.0.0/ui_Handle.js.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | JSDoc: Source: ui/Handle.js 6 | 7 | 8 | 9 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 |

Source: ui/Handle.js

21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 |
29 |
/*
 30 | * Circle
 31 | *
 32 | * Copyright (c) 2013 Mario Klingemann
 33 | *
 34 | * Permission is hereby granted, free of charge, to any person
 35 | * obtaining a copy of this software and associated documentation
 36 | * files (the "Software"), to deal in the Software without
 37 | * restriction, including without limitation the rights to use,
 38 | * copy, modify, merge, publish, distribute, sublicense, and/or sell
 39 | * copies of the Software, and to permit persons to whom the
 40 | * Software is furnished to do so, subject to the following
 41 | * conditions:
 42 | *
 43 | * The above copyright notice and this permission notice shall be
 44 | * included in all copies or substantial portions of the Software.
 45 | *
 46 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 47 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 48 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 49 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 50 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 51 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 52 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 53 | * OTHER DEALINGS IN THE SOFTWARE.
 54 | */
 55 | 
 56 | // namespace:
 57 | window["qlib"] = window.qlib || {};
 58 | 
 59 | (function() {
 60 | 
 61 | 
 62 | 	var Handle = function() {
 63 | 	  this.initialize(arguments);
 64 | 	}
 65 | 
 66 | 	Handle.colorScheme = ["#000","#888","#fff","#fff","#ff8000","#ffe000","#ffff00","#ffff00"];
 67 | 
 68 | 	if ( window.createjs != null )
 69 | 		var p = Handle.prototype = new createjs.Container();
 70 | 	else
 71 | 		var p = Handle.prototype;
 72 | 
 73 | 
 74 | 	/**
 75 | 	 * @property DisplayObject_initialize
 76 | 	 * @type Function
 77 | 	 * @private
 78 | 	 **/
 79 | 	p.Container_initialize = p.initialize;
 80 | 
 81 | 	p.initialize = function( args )
 82 | 	{
 83 | 		this.Container_initialize();
 84 | 		if ( args.length == 0 )
 85 | 		{
 86 | 			//arguments: none
 87 | 			this.point = new qlib.Vector2();
 88 | 		} else if ( typeof args[0] == "number" )
 89 | 		{
 90 | 			//arguments: center x, center y
 91 | 			this.point = new qlib.Vector2( args[0], args[1] );
 92 | 		} else {
 93 | 			//arguments: center
 94 | 			this.point = args[0];
 95 | 		}
 96 | 		this.grabber = (window.createjs != null ? new createjs.Shape() : {});
 97 | 		this.addChild( this.grabber );
 98 | 
 99 | 		this.HANDLE_SIZE = 7;
100 | 
101 | 		this.active = false;
102 | 		this.mouseIsDown = false;
103 | 		this.mouseIsOver = false;
104 | 		this.selected = false;
105 | 
106 | 		this.x = this.point.x;
107 | 		this.y = this.point.y;
108 | 		this.cursor = "pointer";
109 | 		this.updateGrabber();
110 | 	}
111 | 
112 | 	p.setActive = function( value )
113 | 	{
114 | 		this.active = value;
115 | 		if ( value )
116 | 		{
117 | 
118 | 			this.addEventListener("mousedown", function(evt) {
119 | 
120 | 				// bump the target in front of it's siblings:
121 | 				var o = evt.target;
122 | 				o.mouseIsDown = true;
123 | 				o.updateGrabber();
124 | 				var offset = {x:o.x-evt.stageX, y:o.y-evt.stageY};
125 | 
126 | 				// add a listener to the event object's mouseMove event
127 | 				// this will be active until the user releases the mouse button:
128 | 				evt.addEventListener("mousemove", function(ev) {
129 | 					o.lastOffset = { x: (ev.stageX+offset.x) -  o.point.x, y: ( ev.stageY+offset.y) - o.point.y};
130 | 					o.point.x = o.x = ev.stageX+offset.x;
131 | 					o.point.y = o.y = ev.stageY+offset.y;
132 | 
133 | 					o.dispatchEvent(  new qlib.Event( "change", o ) );
134 | 					// indicate that the stage should be updated on the next tick:
135 | 
136 | 				});
137 | 
138 | 				evt.addEventListener("mouseup", function(ev) {
139 | 					o.mouseIsDown = false;
140 | 					o.updateGrabber();
141 | 					// indicate that the stage should be updated on the next tick:
142 | 
143 | 				});
144 | 
145 | 			});
146 | 
147 | 			this.addEventListener("mouseover", function(evt) {
148 | 				var o = evt.target;
149 | 				o.mouseIsOver = true;
150 | 				o.updateGrabber();
151 | 			});
152 | 
153 | 			this.addEventListener("mouseout", function(evt) {
154 | 				var o = evt.target;
155 | 				o.mouseIsOver = false;
156 | 				o.updateGrabber();
157 | 			});
158 | 
159 | 
160 | 		} else {
161 | 			this.removeEventListener("mousedown");
162 | 		}
163 | 	}
164 | 
165 | 
166 | 
167 | 	p.updateGrabber = function()
168 | 	{
169 | 		var g = this.grabber.graphics;
170 | 		g.clear();
171 | 		g.setStrokeStyle(1, 'round', 'round');
172 | 	    g.beginStroke("#fff");
173 | 
174 | 
175 | 		g.beginFill(  Handle.colorScheme[(this.selected ? 4 : 0) | (this.mouseIsDown ? 2 : 0) | (this.mouseIsOver ? 1 : 0)] );
176 | 		g.drawRect( - this.HANDLE_SIZE *0.5, - this.HANDLE_SIZE*0.5, this.HANDLE_SIZE, this.HANDLE_SIZE );
177 | 		g.endFill();
178 | 	}
179 | 
180 | 	p.setPosition = function( x, y )
181 | 	{
182 | 		this.point.x =  x;
183 | 		this.point.y =  y;
184 | 		this.x = Math.round( x );
185 | 		this.y = Math.round( y );
186 | 	}
187 | 
188 | 	p.updatePoint = function( p )
189 | 	{
190 | 		this.point.x =  p.x;
191 | 		this.point.y =  p.y;
192 | 		this.x = Math.round( p.x );
193 | 		this.y = Math.round( p.y );
194 | 	}
195 | 
196 | 	p.updatePositionFromPoint = function( )
197 | 	{
198 | 		this.x = Math.round( this.point.x );
199 | 		this.y = Math.round( this.point.y );
200 | 	}
201 | 
202 | 	p.setPoint = function( p )
203 | 	{
204 | 		this.point = p;
205 | 		this.x = Math.round(  p.x );
206 | 		this.y = Math.round(  p.y );
207 | 	}
208 | 
209 | 	/**
210 | 	 * Returns a string representation of this object.
211 | 	 * @method toString
212 | 	 * @return {String} a string representation of the instance.
213 | 	 **/
214 | 	p.toString = function() {
215 | 		return "Handle";
216 | 	}
217 | 
218 | 	qlib["Handle"] = Handle;
219 | }());
220 |
221 |
222 | 223 | 224 | 225 | 226 |
227 | 228 | 231 | 232 |
233 | 234 |
235 | Documentation generated by JSDoc 4.0.4 on Sat May 31 2025 06:36:44 GMT+0000 (Coordinated Universal Time) 236 |
237 | 238 | 239 | 240 | 241 | 242 | -------------------------------------------------------------------------------- /docs/app/1.0.0/geom_Bezier2.js.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | JSDoc: Source: geom/Bezier2.js 6 | 7 | 8 | 9 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 |

Source: geom/Bezier2.js

21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 |
29 |
/*
 30 | * Quadratic Bezier Curve
 31 | *
 32 | * Copyright (c) 2013 Mario Klingemann
 33 | *
 34 | * Permission is hereby granted, free of charge, to any person
 35 | * obtaining a copy of this software and associated documentation
 36 | * files (the "Software"), to deal in the Software without
 37 | * restriction, including without limitation the rights to use,
 38 | * copy, modify, merge, publish, distribute, sublicense, and/or sell
 39 | * copies of the Software, and to permit persons to whom the
 40 | * Software is furnished to do so, subject to the following
 41 | * conditions:
 42 | *
 43 | * The above copyright notice and this permission notice shall be
 44 | * included in all copies or substantial portions of the Software.
 45 | *
 46 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 47 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 48 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 49 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 50 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 51 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 52 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 53 | * OTHER DEALINGS IN THE SOFTWARE.
 54 | */
 55 | 
 56 | // namespace:
 57 | window["qlib"] = window.qlib || {};
 58 | 
 59 | (function() {
 60 | 	"use strict";
 61 | 
 62 | 	var Bezier2 = function() {
 63 | 	  this.initialize( arguments );
 64 | 	}
 65 | 
 66 | 	var p = Bezier2.prototype = new qlib.GeometricShape();
 67 | 
 68 | 
 69 | 	Bezier2.CURVE_LENGTH_PRECISION = 31;
 70 | 	Bezier2.OFFSET_PRECISION = 10;
 71 | 
 72 | 	// public properties:
 73 | 	p.type = "Bezier2";
 74 | 
 75 | 
 76 | 	// constructor:
 77 | 	/**
 78 | 	 * Initialization method.
 79 | 	 * @method initialize
 80 | 	 * @protected
 81 | 	*/
 82 | 	p.initialize = function( args ) {
 83 | 		var i = 0;
 84 | 		if ( args.length == 0 )
 85 | 		{
 86 | 			this.p1 = new qlib.Vector2();
 87 | 			this.p2 = new qlib.Vector2();
 88 | 			this.c = new qlib.Vector2();
 89 | 		} else {
 90 | 			if ( typeof args[0] == "number" )
 91 | 			{
 92 | 				this.p1 = new qlib.Vector2( args[0], args[1] );
 93 | 				i += 2;
 94 | 			} else {
 95 | 				this.p1 = args[0];
 96 | 				i++;
 97 | 			}
 98 | 			if ( typeof args[i] == "number" )
 99 | 			{
100 | 				this.c = new qlib.Vector2( args[i], args[i+1] );
101 | 				i += 2;
102 | 			} else {
103 | 				this.c = args[i];
104 | 				i++;
105 | 			}
106 | 			if ( typeof args[i] == "number" )
107 | 			{
108 | 				this.p2 = new qlib.Vector2( args[i], args[i+1] );
109 | 			} else {
110 | 				this.p2 = args[i];
111 | 			}
112 | 		}
113 | 		this.dirty = true;
114 | 	}
115 | 
116 | // public methods:
117 | 
118 | 
119 | 	p.getPoint = function( t )
120 | 	{
121 | 		var ti = 1-t;
122 | 		return new qlib.Vector2( ti*ti*this.p1.x+2*t*ti*this.c.x+t*t*this.p2.x , ti*ti*this.p1.y+2*t*ti*this.c.y+t*t*this.p2.y);
123 | 	}
124 | 
125 | 	p.__defineGetter__("length", function(){
126 | 		if ( !this.dirty ) return this.__length;
127 | 
128 | 		var min_t = 0;
129 | 		var max_t = 1;
130 | 		var	i;
131 | 		var	len = 0;
132 | 		var n_eval_pts = Bezier2.CURVE_LENGTH_PRECISION;
133 | 		if ( !( n_eval_pts & 1 ) ) n_eval_pts++;
134 | 
135 | 		var t = [];
136 | 		var pt = [];
137 | 
138 | 		for ( i = 0 ; i < n_eval_pts ; ++i )
139 | 		{
140 | 			t[i]  =  i / ( n_eval_pts - 1 );
141 | 			pt[i] = this.getPoint(t[i]);
142 | 		}
143 | 
144 | 		for ( i = 0 ; i < n_eval_pts - 1 ; i += 2 )
145 | 		{
146 | 			len += this.getSectionLength (t[i] , t[i+1] , t[i+2] , pt[i] , pt[i+1] , pt[i+2]);
147 | 		}
148 | 
149 | 		this.__length = len;
150 | 		this.dirty = false;
151 | 
152 | 		return len;
153 | 	});
154 | 
155 | 	p.getSectionLength = function (t0, t1, t2, pt0, pt1, pt2 )
156 | 	{
157 | 
158 | 		var kEpsilon	= 1e-5;
159 | 		var kEpsilon2	= 1e-6;
160 | 		var kMaxArc	= 1.05;
161 | 		var kLenRatio	= 1.2;
162 | 
163 | 		var d2,len_1,len_2;
164 | 
165 | 		var d1 = pt0.getMinus( pt2 ).length;
166 | 		var da = pt0.getMinus( pt1 ).length;
167 | 		var db = pt1.getMinus( pt2 ).length;
168 | 
169 | 		d2 = da + db;
170 | 
171 | 		if ( d2 < kEpsilon || da==0 || db == 0){
172 | 			return ( d2 + ( d2 - d1 ) / 3 );
173 | 		} else if ( ( d1 < kEpsilon || d2/d1 > kMaxArc ) || ( da < kEpsilon2 || db/da > kLenRatio ) || ( db < kEpsilon2 || da/db > kLenRatio ) ) {
174 | 			var	mid_t = ( t0 + t1 ) / 2;
175 | 
176 | 			var	pt_mid = this.getPoint ( mid_t );
177 | 
178 | 			len_1 = this.getSectionLength( t0, mid_t, t1, pt0, pt_mid, pt1 );
179 | 
180 | 			mid_t = ( t1 + t2 ) / 2;
181 | 
182 | 			pt_mid = this.getPoint ( mid_t );
183 | 
184 | 			len_2 = this.getSectionLength (t1, mid_t, t2, pt1, pt_mid, pt2 );
185 | 
186 | 			return ( len_1 + len_2 );
187 | 
188 | 		} else {
189 | 			return ( d2 + ( d2 - d1 ) / 3 );
190 | 		}
191 | 
192 | 	}
193 | 
194 | 	/**
195 | 	 * Returns a clone of the LineSegment instance.
196 | 	 * @method clone
197 | 	 * @return {LineSegment} a clone of the LineSegment instance.
198 | 	 **/
199 | 	p.clone = function( deepClone ) {
200 | 		if ( deepClone == true )
201 | 			return new qlib.Bezier2( this.p1.clone(), this.c.clone(), this.p2.clone());
202 | 		else
203 | 			return new qlib.Bezier2( this.p1, this.c, this.p2 );
204 | 	}
205 | 
206 | 	p.moveToStart = function( g, offset )
207 | 	{
208 | 		g.moveTo( this.p1.x+ ( offset != null ? offset.x : 0 ), this.p1.y+ ( offset != null ? offset.y : 0 ) );
209 | 	}
210 | 
211 | 	p.moveToEnd = function( g, offset )
212 | 	{
213 | 		g.moveTo( this.p2.x+ ( offset != null ? offset.x : 0 ), this.p2.y+ ( offset != null ? offset.y : 0 ) );
214 | 	}
215 | 
216 | 	p.draw = function(g, offset )
217 | 	{
218 | 		this.moveToStart( g, offset );
219 | 		this.drawTo( g, offset );
220 | 	}
221 | 
222 | 	p.drawExtras = function(g, factor, offset )
223 | 	{
224 | 		factor = ( factor == null ? 1 : factor);
225 | 		this.moveToStart( g, offset );
226 | 		g.lineTo(this.c.x+ ( offset != null ? offset.x : 0 ), this.c.y+ ( offset != null ? offset.y : 0 ));
227 | 		g.lineTo(this.p2.x+ ( offset != null ? offset.x : 0 ), this.p2.y+ ( offset != null ? offset.y : 0 ));
228 | 
229 | 		this.p1.draw(g,factor, offset);
230 | 		this.p2.draw(g,factor, offset);
231 | 		this.c.draw(g,factor, offset);
232 | 
233 | 	}
234 | 
235 | 	p.drawTo = function(g, offset)
236 | 	{
237 | 		if ( offset == null )
238 | 			g.curveTo( this.c.x, this.c.y, this.p2.x,this.p2.y );
239 | 		else
240 | 			g.curveTo( this.c.x + offset.x, this.c.y + offset.y, this.p2.x + offset.x,this.p2.y + offset.y );
241 | 	}
242 | 
243 | 	p.drawToReverse = function(g, offset)
244 | 	{
245 | 		if ( offset == null )
246 | 			g.curveTo( this.c.x,this.c.y,this.p1.x,this.p1.y );
247 | 		else
248 | 			g.curveTo( this.c.x+ offset.x,this.c.y+ offset.y,this.p1.x+ offset.x,this.p1.y + offset.y);
249 | 	}
250 | 
251 | 	/**
252 | 	 * Returns a string representation of this object.
253 | 	 * @method toString
254 | 	 * @return {String} a string representation of the instance.
255 | 	 **/
256 | 	p.toString = function() {
257 | 		return "Bezier2";
258 | 	}
259 | 
260 | 	qlib["Bezier2"] = Bezier2;
261 | }());
262 |
263 |
264 | 265 | 266 | 267 | 268 |
269 | 270 | 273 | 274 |
275 | 276 |
277 | Documentation generated by JSDoc 4.0.4 on Sat May 31 2025 06:36:44 GMT+0000 (Coordinated Universal Time) 278 |
279 | 280 | 281 | 282 | 283 | 284 | -------------------------------------------------------------------------------- /src/qlib/geom/Vector3D.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Vector3D 3 | * 4 | * Copyright (c) 2013 Mario Klingemann 5 | * 6 | * Permission is hereby granted, free of charge, to any person 7 | * obtaining a copy of this software and associated documentation 8 | * files (the "Software"), to deal in the Software without 9 | * restriction, including without limitation the rights to use, 10 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the 12 | * Software is furnished to do so, subject to the following 13 | * conditions: 14 | * 15 | * The above copyright notice and this permission notice shall be 16 | * included in all copies or substantial portions of the Software. 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 19 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 20 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 21 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 22 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 23 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 24 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 25 | * OTHER DEALINGS IN THE SOFTWARE. 26 | */ 27 | 28 | // namespace: 29 | window["qlib"] = window.qlib || {}; 30 | 31 | (function() { 32 | 33 | /** 34 | * Represents a 4-component vector, often used in 3D graphics for homogeneous coordinates (x, y, z, w) 35 | * or as a general 4D vector. Provides methods for standard vector operations. 36 | * 37 | * @class Vector3D 38 | * @memberof qlib 39 | * @constructor 40 | * @param {number} [x=0] - The x-component. 41 | * @param {number} [y=0] - The y-component. 42 | * @param {number} [z=0] - The z-component. 43 | * @param {number} [w=0] - The w-component. 44 | */ 45 | var Vector3D = function(x,y,z,w) { // Changed constructor signature 46 | this.initialize(x,y,z,w); // Changed to call initialize directly 47 | } 48 | var p = Vector3D.prototype; 49 | 50 | // public properties: 51 | 52 | /** 53 | * The x-component of the vector. 54 | * @property {number} x 55 | * @default 0 56 | **/ 57 | p.x = 0; 58 | 59 | /** 60 | * The y-component of the vector. 61 | * @property {number} y 62 | * @default 0 63 | **/ 64 | p.y = 0; 65 | 66 | /** 67 | * The z-component of the vector. 68 | * @property {number} z 69 | * @default 0 70 | **/ 71 | p.z = 0; 72 | 73 | /** 74 | * The w-component of the vector. Often used for homogeneous coordinates (usually 1 for points, 0 for vectors) or perspective division. 75 | * @property {number} w 76 | * @default 0 77 | **/ 78 | p.w = 0; 79 | 80 | /** 81 | * Initializes the Vector3D instance. Called by the constructor. 82 | * The bitwise OR `| 0` will convert `undefined` or other non-numeric inputs to 0, 83 | * and will truncate any fractional part of numbers (e.g., 3.14 becomes 3). 84 | * This might be intentional for specific use cases or could be `|| 0` for a more typical default. 85 | * 86 | * @method initialize 87 | * @protected 88 | * @param {number} [x=0] - The initial x-component. 89 | * @param {number} [y=0] - The initial y-component. 90 | * @param {number} [z=0] - The initial z-component. 91 | * @param {number} [w=0] - The initial w-component. 92 | * @returns {void} 93 | */ 94 | p.initialize = function(x,y,z,w) { // Renamed from 'create' to 'initialize' 95 | this.x = x || 0; // Using || 0 for default, assuming float values are desired. 96 | this.y = y || 0; 97 | this.z = z || 0; 98 | this.w = w || 0; 99 | }; 100 | 101 | /** 102 | * Copies the components of another Vector3D to this vector. 103 | * 104 | * @method set 105 | * @param {qlib.Vector3D} vec - The Vector3D to copy components from. 106 | * @returns {this} This Vector3D instance for chaining. 107 | */ 108 | p.set = function(vec) 109 | { 110 | this.x = vec.x; 111 | this.y = vec.y; 112 | this.z = vec.z; 113 | this.w = vec.w; 114 | return this; 115 | }; 116 | 117 | /** 118 | * Adds the components of another Vector3D to this vector. Modifies this vector. 119 | * (this = this + vec) 120 | * @method add 121 | * @param {qlib.Vector3D} vec - The Vector3D to add. 122 | * @returns {this} This Vector3D instance for chaining. 123 | */ 124 | p.add = function(vec) { 125 | this.x += vec.x; 126 | this.y += vec.y; 127 | this.z += vec.z; 128 | this.w += vec.w; 129 | return this; 130 | }; 131 | 132 | /** 133 | * Subtracts the components of another Vector3D from this vector. Modifies this vector. 134 | * (this = this - vec) 135 | * @method subtract 136 | * @param {qlib.Vector3D} vec - The Vector3D to subtract. 137 | * @returns {this} This Vector3D instance for chaining. 138 | */ 139 | p.subtract = function(vec) { 140 | this.x -= vec.x; 141 | this.y -= vec.y; 142 | this.z -= vec.z; 143 | this.w -= vec.w; 144 | return this; 145 | }; 146 | 147 | /** 148 | * Negates all components of this vector. Modifies this vector. 149 | * (this = -this) 150 | * @method negate 151 | * @returns {this} This Vector3D instance for chaining. 152 | */ 153 | p.negate = function() { 154 | this.x *= -1; 155 | this.y *= -1; 156 | this.z *= -1; 157 | this.w *= -1; 158 | return this; 159 | }; 160 | 161 | /** 162 | * Scales all components of this vector by a scalar value. Modifies this vector. 163 | * (this = this * val) 164 | * @method scale 165 | * @param {number} val - The scalar value to multiply by. 166 | * @returns {this} This Vector3D instance for chaining. 167 | */ 168 | p.scale = function(val) { 169 | this.x *= val; 170 | this.y *= val; 171 | this.z *= val; 172 | this.w *= val; 173 | return this; 174 | }; 175 | 176 | /** 177 | * Normalizes this vector to unit length based on its x, y, and z components. 178 | * The w component is also scaled by the same factor. 179 | * If the 3D length (x,y,z) is 0, all components (x,y,z,w) are set to 0. 180 | * Modifies this vector. 181 | * @method normalize 182 | * @returns {this} This Vector3D instance for chaining. 183 | */ 184 | p.normalize = function() 185 | { 186 | var currentLength = this.length(); // Uses the 3D length (x,y,z) 187 | 188 | if (currentLength === 0) { 189 | this.x = this.y = this.z = this.w = 0; // Or handle w differently if it represents perspective 190 | } else { 191 | var invLength = 1 / currentLength; 192 | this.x *= invLength; 193 | this.y *= invLength; 194 | this.z *= invLength; 195 | this.w *= invLength; // W is also scaled 196 | } 197 | return this; 198 | }; 199 | 200 | /** 201 | * Calculates the cross product of this vector's (x,y,z) components with another Vector3D's (x,y,z) components. 202 | * The w component of the resulting vector is set to 0 (or the default for a new Vector3D). 203 | * This method returns a new Vector3D instance and does not modify this vector. 204 | * @method cross 205 | * @param {qlib.Vector3D} vec - The other Vector3D. 206 | * @returns {qlib.Vector3D} A new Vector3D instance representing the cross product. 207 | */ 208 | p.cross = function(vec){ // Renamed v to vec for clarity 209 | return new qlib.Vector3D(this.y*vec.z - this.z*vec.y, 210 | this.z*vec.x - this.x*vec.z, 211 | this.x*vec.y - this.y*vec.x, 212 | 0); // W component of cross product is typically 0 or not well-defined in this context 213 | }; 214 | 215 | /** 216 | * Calculates the 3D length (magnitude) of this vector using its x, y, and z components. 217 | * The w component is ignored in this calculation. 218 | * @method length 219 | * @returns {number} The 3D length of the vector. 220 | */ 221 | p.length = function(){ 222 | return Math.sqrt(this.x*this.x + this.y*this.y + this.z*this.z ); 223 | }; 224 | 225 | /** 226 | * Calculates the 4D dot product of this vector and another Vector3D. 227 | * All four components (x, y, z, w) are used. 228 | * @method dot 229 | * @param {qlib.Vector3D} vec - The other Vector3D. 230 | * @returns {number} The 4D dot product. 231 | */ 232 | p.dot = function(vec){ // Renamed v to vec 233 | return this.x*vec.x + this.y*vec.y + this.z*vec.z + this.w*vec.w; 234 | }; 235 | 236 | /** 237 | * Modifies this vector to be the normalized direction vector from this point towards another point `vec`. 238 | * Uses only x, y, z components for direction calculation. The w component of this vector is set to 0 after normalization. 239 | * @method direction 240 | * @param {qlib.Vector3D} vec - The target Vector3D to point towards. 241 | * @returns {this} This Vector3D instance, modified to be the direction vector. 242 | */ 243 | p.direction = function(vec) { 244 | var dx = vec.x - this.x; // Corrected: target - origin for direction vector 245 | var dy = vec.y - this.y; 246 | var dz = vec.z - this.z; 247 | 248 | var len = Math.sqrt(dx*dx + dy*dy + dz*dz); 249 | if (!len) { 250 | this.x = this.y = this.z = this.w = 0; // Or specific handling for w 251 | } else { 252 | len = 1 / len; 253 | this.x = dx * len; 254 | this.y = dy * len; 255 | this.z = dz * len; 256 | this.w = 0; // Typically, direction vectors have w=0 in homogeneous coordinates 257 | } 258 | return this; 259 | }; 260 | 261 | /** 262 | * Returns a string representation of this Vector3D. 263 | * Format: "[x, y, z, w]" 264 | * @method toString 265 | * @return {string} A string representation of the instance. 266 | **/ 267 | p.toString = function() { // Renamed from str and removed vec parameter 268 | return '[' + this.x + ', ' + this.y + ', ' + this.z + ', ' + this.w + ']'; 269 | }; 270 | 271 | qlib["Vector3D"] = Vector3D; 272 | }()); --------------------------------------------------------------------------------