{"id":13525749,"url":"https://github.com/davisdude/mlib","last_synced_at":"2025-10-20T12:34:14.839Z","repository":{"id":13627128,"uuid":"16320407","full_name":"davisdude/mlib","owner":"davisdude","description":"A math and collisions library for Lua.","archived":false,"fork":false,"pushed_at":"2024-01-04T04:56:51.000Z","size":4094,"stargazers_count":87,"open_issues_count":2,"forks_count":12,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-03-16T10:41:28.788Z","etag":null,"topics":["intersection","lua","math"],"latest_commit_sha":null,"homepage":"","language":"Lua","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"zlib","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/davisdude.png","metadata":{"files":{"readme":"README.md","changelog":"Changes.txt","contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2014-01-28T18:00:33.000Z","updated_at":"2025-03-14T10:27:18.000Z","dependencies_parsed_at":"2024-04-12T01:55:32.632Z","dependency_job_id":"fa2e76cf-fafc-4ea5-8e53-a6803de98b85","html_url":"https://github.com/davisdude/mlib","commit_stats":null,"previous_names":[],"tags_count":12,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/davisdude%2Fmlib","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/davisdude%2Fmlib/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/davisdude%2Fmlib/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/davisdude%2Fmlib/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/davisdude","download_url":"https://codeload.github.com/davisdude/mlib/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244009023,"owners_count":20382951,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["intersection","lua","math"],"created_at":"2024-08-01T06:01:21.748Z","updated_at":"2025-10-20T12:34:14.745Z","avatar_url":"https://github.com/davisdude.png","language":"Lua","readme":"MLib\n====\n\n__MLib__ is a math and shape-intersection detection library written in Lua. It's aim is to be __robust__ and __easy to use__.\n\n__NOTE:__ \n- I am (slowly) working on completely rewriting this in order to be easier to use and less bug-prone. You can check out the progress [here](../../tree/dev).\n- I am currently slowing development of MLib while moving over to helping with [CPML](https://github.com/excessive/cpml). To discuss this, please comment [here](../../issues/12).\n\nIf you are looking for a library that handles updating/collision responses for you, take a look at [hxdx](https://github.com/adonaac/hxdx). It uses MLib functions as well as Box2d to handle physics calculations. \n\n## Downloading\nYou can download the latest __stable__ version of MLib by downloading the latest [release](../../releases/).\nYou can download the latest __working__ version of MLib by downloading the latest [commit](../../commits/master/). Documentation will __only__ be updated upon releases, not upon commits.\n\n## Implementing\nTo use MLib, simply place [mlib.lua](mlib.lua) inside the desired folder in your project. Then use the `require 'path.to.mlib'` to use any of the functions.\n\n## Examples\nIf you don't have [LÖVE](https://love2d.org/) installed, you can download the .zip of the demo from the [Executables](Examples/Executables) folder and extract and run the .exe that way.\nYou can see some examples of the code in action [here](Examples).\nAll examples are done using the *awesome* engine of [LÖVE](https://love2d.org/).\nTo run them properly, download the [.love file](Examples/LOVE) and install LÖVE to your computer.\nAfter that, make sure you set .love files to open with \"love.exe\".\nFor more, see [here](https://love2d.org/).\n\n## When should I use MLib?\n- If you need to know exactly where two objects intersect.\n- If you need general mathematical equations to be done.\n- If you need very precise details about point intersections.\n\n## When should I __not__ use MLib?\n- All of the objects in a platformer, or other game, for instance, should not be registered with MLib. Only ones that need very specific information.\n- When you don't need precise information/odd shapes.\n\n## Specs\n\nAlternatively, you can find the tests [here](spec.lua). Keep in mind that you may need to change certain semantics to suit your OS.\nYou can run them via [Telescope](https://github.com/norman/telescope/) and type the following command in the command-line of the root folder:\n```\ntsc -f specs.lua\n```\nIf that does not work, you made need to put a link to Lua inside of the folder for `telescope` and run the following command:\n```\nlua tsc -f specs.lua\n```\nIf you encounter further errors, try to run the command line as an administrator (usually located in `C:\\Windows\\System32\\`), then right-click on `cmd.exe` and select `Run as administrator`, then do\n```\ncd C:\\Path\\to\\telescope\\\n```\nAnd __then__ run one of the above commands. If none of those work, just take my word for it that all the tests pass and look at this picture.\n![Success](Reference Pictures/Success.png)\n\n## Functions\n- [mlib.line](#mlibline)\n  - [mlib.line.checkPoint](#mliblinecheckpoint)\n  - [mlib.line.getClosestPoint](#mliblinegetclosestpoint)\n  - [mlib.line.getYIntercept](#mliblinegetintercept)\n  - [mlib.line.getIntersection](#mliblinegetintersection)\n  - [mlib.line.getLength](#mliblinegetlength)\n  - [mlib.line.getMidpoint](#mliblinegetmidpoint)\n  - [mlib.line.getPerpendicularSlope](#mliblinegetperpendicularslope)\n  - [mlib.line.getSegmentIntersection](#mliblinegetsegmentintersection)\n  - [mlib.line.getSlope](#mliblinegetslope)\n- [mlib.segment](#mlibsegment)\n  - [mlib.segment.checkPoint](#mlibsegmentcheckpoint)\n  - [mlib.segment.getPerpendicularBisector](#mlibsegmentgetperpendicularbisector)\n  - [mlib.segment.getIntersection](#mlibsegmentgetintersection)\n- [mlib.polygon](#mlibpolygon)\n  - [mlib.polygon.checkPoint](#mlibpolygoncheckpoint)\n  - [mlib.polygon.getCentroid](#mlibpolygongetcentroid)\n  - [mlib.polygon.getCircleIntersection](#mlibpolygongetcircleintersection)\n  - [mlib.polygon.getLineIntersection](#mlibpolygongetlineintersection)\n  - [mlib.polygon.getPolygonArea](#mlibpolygongetpolygonarea)\n  - [mlib.polygon.getPolygonIntersection](#mlibpolygongetpolygonintersection)\n  - [mlib.polygon.getSegmentIntersection](#mlibpolygongetsegmentintersection)\n  - [mlib.polygon.getSignedPolygonArea](#mlibpolygongetsignedpolygonarea)\n  - [mlib.polygon.getTriangleHeight](#mlibpolygongettriangleheight)\n  - [mlib.polygon.isCircleInside](#mlibpolygoniscircleinside)\n  - [mlib.polygon.isCircleCompletelyInside](#mlibpolygoniscirclecompletelyinside)\n  - [mlib.polygon.isPolygonInside](#mlibpolygonispolygoninside)\n  - [mlib.polygon.isPolygonCompletelyInside](#mlibpolygonispolygoncompletelyinside)\n  - [mlib.polygon.isSegmentInside](#mlibpolygonissegmentinside)\n  - [mlib.polygon.isSegmentCompletelyInside](#mlibpolygonissegmentcompletelyinside)\n- [mlib.circle](#mlibcircle)\n  - [mlib.circle.checkPoint](#mlibcirclecheckpoint)\n  - [mlib.circle.getArea](#mlibcirclegetarea)\n  - [mlib.circle.getCircleIntersection](#mlibcirclegetcircleintersection)\n  - [mlib.circle.getCircumference](#mlibcirclegetcircumference)\n  - [mlib.circle.getLineIntersection](#mlibcirclegetlineintersection)\n  - [mlib.circle.getSegmentIntersection](#mlibcirclegetsegmentintersection)\n  - [mlib.circle.isCircleCompletelyInside](#mlibcircleiscirclecompletelyinside)\n  - [mlib.circle.isCircleCompletelyInsidePolygon](#mlibcircleiscirclecompletelyinsidepolygon)\n  - [mlib.circle.isPointOnCircle](#mlibcircleispointoncircle)\n  - [mlib.circle.isPolygonCompletelyInside](#mlibcircleispolygoncompletelyinside)\n- [mlib.statistics](#mlibstatistics)\n  - [mlib.statistics.getCentralTendency](#mlibstatisticsgetcentraltendency)\n  - [mlib.statistics.getDispersion](#mlibstatisticsgetdispersion)\n  - [mlib.statistics.getMean](#mlibstatisticsgetmean)\n  - [mlib.statistics.getMedian](#mlibstatisticsgetmedian)\n  - [mlib.statistics.getMode](#mlibstatisticsgetmode)\n  - [mlib.statistics.getRange](#mlibstatisticsgetrange)\n  - [mlib.statistics.getStandardDeviation](#mlibstatisticsgetstandarddeviation)\n  - [mlib.statistics.getVariance](#mlibstatisticsgetvariance)\n  - [mlib.statistics.getVariationRatio](#mlibstatisticsgetvariationratio)\n- [mlib.math](#mlibmath)\n  - [mlib.math.getAngle](#mlibmathgetangle)\n  - [mlib.math.getPercentage](#mlibmathgetpercentage)\n  - [mlib.math.getPercentOfChange](#mlibmathgetpercentofchange)\n  - [mlib.math.getQuadraticRoots](#mlibmathgetquadraticroots)\n  - [mlib.math.getRoot](#mlibmathgetroot)\n  - [mlib.math.getSummation](#mlibmathgetsummation)\n  - [mlib.math.isPrime](#mlibmathisprime)\n  - [mlib.math.round](#mlibmathround)\n- [Aliases](#aliases)\n\n#### mlib.line\n- Deals with linear aspects, such as slope and length.\n\n##### mlib.line.checkPoint\n- Checks if a point lies on a line.\n- Synopsis:\n  - `onPoint = mlib.line.checkPoint( px, px, x1, y1, x2, y2 )`\n- Arguments:\n  - `px`, `py`: Numbers. The x and y coordinates of the point being tested.\n  - `x1`, `y1`, `x2`, `y2`: Numbers. Two x and y coordinates of the line being tested.\n- Returns:\n  - `onPoint`: Boolean.\n    - `true` if the point is on the line.\n\t- `false` if it does not.\n- Notes:\n  - You cannot use the format `mlib.line.checkPoint( px, px, slope, intercept )` because this would lead to errors on vertical lines.\n\n##### mlib.line.getClosestPoint\n- Gives the closest point to a line.\n- Synopses:\n  - `cx, cy = mlib.line.getClosestPoint( px, py, x1, y1, x2, y2 )`\n  - `cx, cy = mlib.line.getClosestPoint( px, py, slope, intercept )`\n- Arguments:\n  - `x`, `y`: Numbers. The x and y coordinates of the point.\n  - `x1`, `y1`, `x2`, `y2`: Numbers. Two x and y coordinates on the line.\n  - `slope`, `intercept`:\n    - Numbers. The slope and y-intercept of the line.\n\t- Booleans (`false`). The slope and y-intercept of a vertical line.\n- Returns:\n  - `cx`, `cy`: Numbers. The closest points that lie on the line to the point.\n\n##### mlib.line.getYIntercept\n- Gives y-intercept of the line.\n- Synopses:\n  - `intercept, isVertical = mlib.line.getYIntercept( x1, y1, x2, y2 )`\n  - `intercept, isVertical = mlib.line.getYIntercept( x1, y1, slope )`\n- Arguments:\n  - `x1`, `y1`, `x2`, `y2`: Numbers. Two x and y coordinates that lie on the line.\n  - `slope`:\n    - Number. The slope of the line.\n- Returns:\n  - `intercept`:\n    - Number. The y-intercept of the line.\n    - Number. The `x1` coordinate of the line if the line is vertical.\n  - `isVertical`:\n    - Boolean. `true` if the line is vertical, `false` if the line is not vertical.\n\n##### mlib.line.getIntersection\n- Gives the intersection of two lines.\n- Synopses:\n  - `x, y = mlib.line.getIntersection( x1, y1, x2, y2, x3, y3, x4, y4 )`\n  - `x, y = mlib.line.getIntersection( slope1, intercept1, x3, y3, x4, y4 )`\n  - `x, y = mlib.line.getIntersection( slope1, intercept1, slope2, intercept2 )`\n- Arguments:\n  - `x1`, `y1`, `x2`, `y2`: Numbers. Two x and y coordinates that lie on the first line.\n  - `x3`, `y3`, `x4`, `y4`: Numbers. Two x and y coordinates that lie on the second line.\n  - `slope1`, `intercept1`:\n    - Numbers. The slope and y-intercept of the first line.\n\t- Booleans (`false`). The slope and y-intercept of the first line (if the first line is vertical).\n  - `slope2`, `intercept2`:\n    - Numbers. The slope and y-intercept of the second line.\n\t- Booleans (`false`). The slope and y-intercept of the second line (if the second line is vertical).\n- Returns:\n  - `x`, `y`:\n    - Numbers. The x and y coordinate where the lines intersect.\n\t- Boolean:\n\t  - `true`, `nil`: The lines are collinear.\n\t  - `false`, `nil`: The lines are parallel and __not__ collinear.\n\n##### mlib.line.getLength\n- Gives the distance between two points.\n- Synopsis:\n  - `length = mlib.line.getLength( x1, y1, x2, y2 )\n- Arguments:\n  - `x1`, `y1`, `x2`, `y2`: Numbers. Two x and y coordinates.\n- Returns:\n  - `length`: Number. The distance between the two points.\n\n##### mlib.line.getMidpoint\n- Gives the midpoint of two points.\n- Synopsis:\n  - `x, y = mlib.line.getMidpoint( x1, y1, x2, y2 )`\n- Arguments:\n  - `x1`, `y1`, `x2`, `y2`: Numbers. Two x and y coordinates.\n- Returns:\n  - `x`, `y`: Numbers. The midpoint x and y coordinates.\n\n##### mlib.line.getPerpendicularSlope\n- Gives the perpendicular slope of a line.\n- Synopses:\n  - `perpSlope = mlib.line.getPerpendicularSlope( x1, y1, x2, y2 )`\n  - `perpSlope = mlib.line.getPerpendicularSlope( slope )`\n- Arguments:\n  - `x1`, `y1`, `x2`, `y2`: Numbers. Two x and y coordinates.\n  - `slope`: Number. The slope of the line.\n- Returns:\n  - `perpSlope`:\n    - Number. The perpendicular slope of the line.\n\t- Boolean (`false`). The perpendicular slope of the line (if the original line was horizontal).\n\n##### mlib.line.getSegmentIntersection\n- Gives the intersection of a line segment and a line.\n- Synopses:\n  - `x1, y1, x2, y2 = mlib.line.getSegmentIntersection( x1, y1, x2, y2, x3, y3, x4, y4 )`\n  - `x1, y1, x2, y2 = mlib.line.getSegmentIntersection( x1, y1, x2, y2, slope, intercept )`\n- Arguments:\n  - `x1`, `y1`, `x2`, `y2`: Numbers. Two x and y coordinates that lie on the line segment.\n  - `x3`, `y3`, `x4`, `y4`: Numbers. Two x and y coordinates that lie on the line.\n  - `slope`, `intercept`:\n    - Numbers. The slope and y-intercept of the the line.\n\t- Booleans (`false`). The slope and y-intercept of the line (if the line is vertical).\n- Returns:\n  - `x1`, `y1`, `x2`, `y2`:\n    - Number, Number, Number, Number.\n\t  - The points of the line segment if the line and segment are collinear.\n\t- Number, Number, Boolean (`nil`), Boolean (`nil`).\n\t  - The coordinate of intersection if the line and segment intersect and are not collinear.\n\t- Boolean (`false`), Boolean (`nil`), Boolean (`nil`),\n\t  - Boolean (`nil`). If the line and segment don't intersect.\n\n##### mlib.line.getSlope\n- Gives the slope of a line.\n- Synopsis:\n  - `slope = mlib.line.getSlope( x1, y1, x2, y2 )\n- Arguments:\n  - `x1`, `y1`, `x2`, `y2`: Numbers. Two x and y coordinates.\n- Returns:\n  - `slope`:\n    - Number. The slope of the line.\n\t- Boolean (`false`). The slope of the line (if the line is vertical).\n\n#### mlib.segment\n- Deals with line segments.\n\n##### mlib.segment.checkPoint\n- Checks if a point lies on a line segment.\n- Synopsis:\n  - `onSegment = mlib.segment.checkPoint( px, py, x1 y1, x2, y2 )`\n- Arguments:\n  - `px`, `py`: Numbers. The x and y coordinates of the point being checked.\n  - `x1`, `y1`, `x2`, `y2`: Numbers. Two x and y coordinates.\n- Returns:\n  - `onSegment`: Boolean.\n    - `true` if the point lies on the line segment.\n\t- `false` if the point does not lie on the line segment.\n\n##### mlib.segment.getPerpendicularBisector\n- Gives the perpendicular bisector of a line.\n- Synopsis:\n  - `x, y, slope = mlib.segment.getPerpendicularBisector( x1, y1, x2, y2 )`\n- Arguments:\n  - `x1`, `y1`, `x2`, `y2`: Numbers. Two x and y coordinates.\n- Returns:\n  - `x`, `y`: Numbers. The midpoint of the line.\n  - `slope`:\n    - Number. The perpendicular slope of the line.\n\t- Boolean (`false`). The perpendicular slope of the line (if the original line was horizontal).\n\n##### mlib.segment.getIntersection\n- Checks if two line segments intersect.\n- Synopsis:\n  - `cx1, cy1, cx2, cy2 = mlib.segment.getIntersection( x1, y1, x2, y2, x3, y3 x4, y4 )`\n- Arguments:\n  - `x1`, `y1`, `x2`, `y2`: Numbers. Two x and y coordinates of the first line segment.\n  - `x3`, `y3`, `x4`, `y4`: Numbers. Two x and y coordinates of the second line segment.\n- Returns:\n  - `cx1`, `cy1`, `cx2`, `cy2`:\n    - Number, Number, Number, Number.\n\t  - The points of the resulting intersection if the line segments are collinear.\n\t- Number, Number, Boolean (`nil`), Boolean (`nil`).\n\t  - The point of the resulting intersection if the line segments are not collinear.\n\t- Boolean (`false`), Boolean (`nil`), Boolean (`nil`) , Boolean (`nil`).\n\t  - If the line segments don't intersect.\n\n#### mlib.polygon\n- Handles aspects involving polygons.\n\n##### mlib.polygon.checkPoint\n- Checks if a point is inside of a polygon.\n- Synopses:\n  - `inPolygon = mlib.polygon.checkPoint( px, py, vertices )`\n  - `inPolygon = mlib.polygon.checkPoint( px, py, ... )`\n- Arguments:\n  - `px`, `py`: Numbers. The x and y coordinate of the point being checked.\n  - `vertices`: Table. The vertices of the polygon in the format `{ x1, y1, x2, y2, x3, y3, ... }`\n  - `...`: Numbers. The x and y coordinates of the polygon. (Same as using `unpack( vertices )`)\n- Returns:\n  - `inPolygon`: Boolean.\n    - `true` if the point is inside the polygon.\n\t- `false` if the point is not inside the polygon.\n\n##### mlib.polygon.getCentroid\n- Returns the centroid of the polygon.\n- Synopses:\n  - `cx, cy = mlib.polygon.getCentroid( vertices )`\n  - `cx, cy = mlib.polygon.getCentroid( ... )`\n- Arguments:\n  - `vertices`: Table. The vertices of the polygon in the format `{ x1, y1, x2, y2, x3, y3, ... }`\n  - `...`: Numbers. The x and y coordinates of the polygon. (Same as using `unpack( vertices )`)\n- Returns:\n  - `cx`, `cy`: Numbers. The x and y coordinates of the centroid.\n\n##### mlib.polygon.getCircleIntersection\n- Returns the coordinates of where a circle intersects a polygon.\n- Synopses:\n  - `intersections = mlib.polygon.getCircleIntersection( cx, cy, radius, vertices )`\n  - `intersections = mlib.polygon.getCircleIntersection( cx, cy, radius, ... )\n- Arguments:\n  - `cx`, `cy`: Number. The coordinates of the center of the circle.\n  - `radius`: Number. The radius of the circle.\n  - `vertices`: Table. The vertices of the polygon in the format `{ x1, y1, x2, y2, x3, y3, ... }`\n  - `...`: Numbers. The x and y coordinates of the polygon. (Same as using `unpack( vertices )`)\n- Returns:\n  - `intersections`: Table. Contains the intersections and type.\n- Example:\n```lua\nlocal tab = _.polygon.getCircleIntersection( 5, 5, 1, 4, 4, 6, 4, 6, 6, 4, 6 )\nfor i = 1, # tab do\n\tprint( i .. ':', unpack( tab[i] ) )\nend\n-- 1: \ttangent\t\t5\t\t4\n-- 2: \ttangent\t\t6 \t\t5\n-- 3: \ttangent \t5\t\t6\n-- 4: \ttagnent \t4\t\t5\n```\n- For more see [mlib.circle.getSegmentIntersection](#mlibcirclegetsegmentintersection) or the [specs](spec.lua)\n\n##### mlib.polygon.getLineIntersection\n- Returns the coordinates of where a line intersects a polygon.\n- Synopses:\n  - `intersections = mlib.polygon.getLineIntersection( x1, y1, x2, y2, vertices )`\n  - `intersections = mlib.polygon.getLineIntersection( x1, y1, x2, y2, ... )\n- Arguments:\n  - `x1`, `y1`, `x2`, `y2`: Numbers. Two x and y coordinates.\n  - `vertices`: Table. The vertices of the polygon in the format `{ x1, y1, x2, y2, x3, y3, ... }`\n  - `...`: Numbers. The x and y coordinates of the polygon. (Same as using `unpack( vertices )`)\n- Returns:\n  - `intersections`: Table. Contains the intersections.\n- Notes:\n  - With collinear lines, they are actually broken up. i.e. `{ 0, 4, 0, 0 }` would become `{ 0, 4 }, { 0, 0 }`.\n\n##### mlib.polygon.getPolygonArea\n- Gives the area of a polygon.\n- Synopses:\n  - `area = mlib.polygon.getArea( vertices )`\n  - `area = mlib.polygon.getArea( ... )\n- Arguments:\n  - `vertices`: Table. The vertices of the polygon in the format `{ x1, y1, x2, y2, x3, y3, ... }`\n  - `...`: Numbers. The x and y coordinates of the polygon. (Same as using `unpack( vertices )`)\n- Returns:\n  - `area`: Number. The area of the polygon.\n\n##### mlib.polygon.getPolygonIntersection\n- Gives the intersection of two polygons.\n- Synopsis:\n  - `intersections = mlib.polygon.getPolygonIntersections( polygon1, polygon2 )`\n- Arguments:\n  - `polygon1`: Table. The vertices of the first polygon in the format `{ x1, y1, x2, y2, x3, y3, ... }`\n  - `polygon2`: Table. The vertices of the second polygon in the format `{ x1, y1, x2, y2, x3, y3, ... }`\n- Returns:\n  - `intersections`: Table. A table of the points of intersection.\n\n##### mlib.polygon.getSegmentIntersection\n- Returns the coordinates of where a line segmeing intersects a polygon.\n- Synopses:\n  - `intersections = mlib.polygon.getSegmentIntersection( x1, y1, x2, y2, vertices )`\n  - `intersections = mlib.polygon.getSegmentIntersection( x1, y1, x2, y2, ... )\n- Arguments:\n  - `x1`, `y1`, `x2`, `y2`: Numbers. Two x and y coordinates.\n  - `vertices`: Table. The vertices of the polygon in the format `{ x1, y1, x2, y2, x3, y3, ... }`\n  - `...`: Numbers. The x and y coordinates of the polygon. (Same as using `unpack( vertices )`)\n- Returns:\n  - `intersections`: Table. Contains the intersections.\n- Notes:\n  - With collinear line segments, they are __not__ broken up. See the [specs](spec.lua) for more.\n\n##### mlib.polygon.getSignedPolygonArea\n- Gets the signed area of the polygon. If the points are ordered counter-clockwise the area is positive. If the points are ordered clockwise the number is negative.\n- Synopses:\n  - `area = mlib.polygon.getLineIntersection( vertices )`\n  - `area = mlib.polygon.getLineIntersection( ... )\n- Arguments:\n  - `vertices`: Table. The vertices of the polygon in the format `{ x1, y1, x2, y2, x3, y3, ... }`\n  - `...`: Numbers. The x and y coordinates of the polygon. (Same as using `unpack( vertices )`)\n- Returns:\n  - `area`: Number. The __signed__ area of the polygon. If the points are ordered counter-clockwise the area is positive. If the points are ordered clockwise the number is negative.\n\n##### mlib.polygon.getTriangleHeight\n- Gives the height of a triangle.\n- Synopses:\n  - `height = mlib.polygon.getTriangleHeigh( base, x1, y1, x2, y2, x3, y3 )`\n  - `height = mlib.polygon.getTriangleHeight( base, area )`\n- Arguments:\n  - `base`: Number. The length of the base of the triangle.\n  - `x1`, `y1`, `x2`, `y2`, `x3`, `y3`: Numbers. The x and y coordinates of the triangle.\n  - `area`: Number. The regular area of the triangle. __Not__ the signed area.\n- Returns:\n  - `height`: Number. The height of the triangle.\n\n##### mlib.polygon.isCircleInside\n- Checks if a circle is inside the polygon.\n- Synopses:\n  - `inPolygon = mlib.polygon.isCircleInside( cx, cy, radius, vertices )`\n  - `inPolygon = mlib.polygon.isCircleInside( cx, cy, radius, ... )`\n- Arguments:\n  - `cx`, `cy`: Numbers. The x and y coordinates for the center of the circle.\n  - `radius`: Number. The radius of the circle.\n  - `vertices`: Table. The vertices of the polygon in the format `{ x1, y1, x2, y2, x3, y3, ... }`\n  - `...`: Numbers. The x and y coordinates of the polygon. (Same as using `unpack( vertices )`)\n- Returns:\n  - `inPolygon`: Boolean.\n    - `true` if the circle is inside the polygon.\n\t- `false` if the circle is not inside the polygon.\n- Notes:\n  - Only returns true if the center of the circle is inside the circle.\n\n##### mlib.polygon.isCircleCompletelyInside\n- Checks if a circle is completely inside the polygon.\n- Synopses:\n  - `inPolygon = mlib.polygon.isCircleCompletelyInside( cx, cy, radius, vertices )`\n  - `inPolygon = mlib.polygon.isCircleCompletelyInside( cx, cy, radius, ... )`\n- Arguments:\n  - `cx`, `cy`: Numbers. The x and y coordinates for the center of the circle.\n  - `radius`: Number. The radius of the circle.\n  - `vertices`: Table. The vertices of the polygon in the format `{ x1, y1, x2, y2, x3, y3, ... }`\n  - `...`: Numbers. The x and y coordinates of the polygon. (Same as using `unpack( vertices )`)\n- Returns:\n  - `inPolygon`: Boolean.\n    - `true` if the circle is __completely__ inside the polygon.\n\t- `false` if the circle is not inside the polygon.\n\n##### mlib.polygon.isPolygonInside\n- Checks if a polygon is inside a polygon.\n- Synopsis:\n  - `inPolygon = mlib.polygon.isPolygonInside( polygon1, polygon2 )`\n- Arguments:\n  - `polygon1`: Table. The vertices of the first polygon in the format `{ x1, y1, x2, y2, x3, y3, ... }`\n  - `polygon2`: Table. The vertices of the second polygon in the format `{ x1, y1, x2, y2, x3, y3, ... }`\n- Returns:\n  - `inPolygon`: Boolean.\n    - `true` if the `polygon2` is inside of `polygon1`.\n\t- `false` if `polygon2` is not inside of `polygon2`.\n- Notes:\n  - Returns true as long as any of the line segments of `polygon2` are inside of the `polygon1`.\n\n##### mlib.polygon.isPolygonCompletelyInside\n- Checks if a polygon is completely inside a polygon.\n- Synopsis:\n  - `inPolygon = mlib.polygon.isPolygonCompletelyInside( polygon1, polygon2 )`\n- Arguments:\n  - `polygon1`: Table. The vertices of the first polygon in the format `{ x1, y1, x2, y2, x3, y3, ... }`\n  - `polygon2`: Table. The vertices of the second polygon in the format `{ x1, y1, x2, y2, x3, y3, ... }`\n- Returns:\n  - `inPolygon`: Boolean.\n    - `true` if the `polygon2` is __completely__ inside of `polygon1`.\n\t- `false` if `polygon2` is not inside of `polygon2`.\n\n##### mlib.polygon.isSegmentInside\n- Checks if a line segment is inside a polygon.\n- Synopses:\n  - `inPolygon = mlib.polygon.isSegmentInside( x1, y1, x2, y2, vertices )`\n  - `inPolygon = mlib.polygon.isSegmentInside( x1, y1, x2, y2, ... )`\n- Arguments:\n  - `x1`, `y1`, `x2`, `y2`: Numbers. The x and y coordinates of the line segment.\n  - `vertices`: Table. The vertices of the polygon in the format `{ x1, y1, x2, y2, x3, y3, ... }`\n  - `...`: Numbers. The x and y coordinates of the polygon. (Same as using `unpack( vertices )`)\n- Returns:\n  - `inPolygon`: Boolean.\n    - `true` if the line segment is inside the polygon.\n\t- `false` if the line segment is not inside the polygon.\n- Note:\n  - Only one of the points has to be in the polygon to be considered 'inside' of the polygon.\n  - This is really just a faster version of [mlib.polygon.getPolygonIntersection](#mlibpolygongetpolygonintersection) that does not give the points of intersection.\n\n##### mlib.polygon.isSegmentCompletelyInside\n- Checks if a line segment is completely inside a polygon.\n- Synopses:\n  - `inPolygon = mlib.polygon.isSegmentCompletelyInside( x1, y1, x2, y2, vertices )`\n  - `inPolygon = mlib.polygon.isSegmentCompletelyInside( x1, y1, x2, y2, ... )`\n- Arguments:\n  - `x1`, `y1`, `x2`, `y2`: Numbers. The x and y coordinates of the line segment.\n  - `vertices`: Table. The vertices of the polygon in the format `{ x1, y1, x2, y2, x3, y3, ... }`\n  - `...`: Numbers. The x and y coordinates of the polygon. (Same as using `unpack( vertices )`)\n- Returns:\n  - `inPolygon`: Boolean.\n    - `true` if the line segment is __completely__ inside the polygon.\n\t- `false` if the line segment is not inside the polygon.\n\n#### mlib.circle\n- Handles aspects involving circles.\n\n##### mlib.circle.checkPoint\n- Checks if a point is on the inside or on the edge the circle.\n- Synopsis:\n  - `inCircle = mlib.circle.checkPoint( px, px, cx, cy, radius )`\n- Arguments:\n  - `px`, `py`: Numbers. The x and y coordinates of the point being tested.\n  - `cx`, `cy`: Numbers. The x and y coordinates of the center of the circle.\n  - `radius`: Number. The radius of the circle.\n- Returns:\n  - `inCircle`: Boolean.\n    - `true` if the point is inside or on the circle.\n\t- `false` if the point is outside of the circle.\n\n##### mlib.circle.getArea\n- Gives the area of a circle.\n- Synopsis:\n  - `area = mlib.circle.getArea( radius )`\n- Arguments:\n  - `radius`: Number. The radius of the circle.\n- Returns:\n  - `area`: Number. The area of the circle.\n\n##### mlib.circle.getCircleIntersection\n- Gives the intersections of two circles.\n- Synopsis:\n  - `intersections = mlib.circle.getCircleIntersection( c1x, c1y, radius1, c2x, c2y, radius2 )\n- Arguments:\n  - `c1x`, `c1y`: Numbers. The x and y coordinate of the first circle.\n  - `radius1`: Number. The radius of the first circle.\n  - `c2x`, `c2y`: Numbers. The x and y coordinate of the second circle.\n  - `radius2`: Number. The radius of the second circle.\n- Returns:\n  - `intersections`: Table. A table that contains the type and where the circle collides. See the [specs](spec.lua) for more.\n\n##### mlib.circle.getCircumference\n- Returns the circumference of a circle.\n- Synopsis:\n  - `circumference = mlib.circle.getCircumference( radius )`\n- Arguments:\n  - `radius`: Number. The radius of the circle.\n- Returns:\n  - `circumference`: Number. The circumference of a circle.\n\n##### mlib.circle.getLineIntersection\n- Returns the intersections of a circle and a line.\n- Synopsis:\n  - `intersections = mlib.circle.getLineIntersections( cx, cy, radius, x1, y1, x2, y2 )`\n- Arguments:\n  - `cx`, `cy`: Numbers. The x and y coordinates for the center of the circle.\n  - `radius`: Number. The radius of the circle.\n  - `x1`, `y1`, `x2`, `y2`: Numbers. Two x and y coordinates the lie on the line.\n- Returns:\n  - `intersections`: Table. A table with the type and where the intersections happened. Table is formatted:\n    - `type`, `x1`, `y1`, `x2`, `y2`\n\t  - String (`'secant'`), Number, Number, Number, Number\n\t    - The numbers are the x and y coordinates where the line intersects the circle.\n\t  - String (`'tangent'`), Number, Number, Boolean (`nil`), Boolean (`nil`)\n\t    - `x1` and `x2` represent where the line intersects the circle.\n\t  - Boolean (`false`), Boolean (`nil`), Boolean (`nil`), Boolean (`nil`), Boolean (`nil`)\n\t    - No intersection.\n    - For more see the [specs](spec.lua).\n\n##### mlib.circle.getSegmentIntersection\n- Returns the intersections of a circle and a line segment.\n- Synopsis:\n  - `intersections = mlib.circle.getSegmentIntersections( cx, cy, radius, x1, y1, x2, y2 )`\n- Arguments:\n  - `cx`, `cy`: Numbers. The x and y coordinates for the center of the circle.\n  - `radius`: Number. The radius of the circle.\n  - `x1`, `y1`, `x2`, `y2`: Numbers. The two x and y coordinates of the line segment.\n- Returns:\n  - `intersections`: Table. A table with the type and where the intersections happened. Table is formatted:\n    - `type`, `x1`, `y1`, `x2`, `y2`\n\t  - String (`'chord'`), Number, Number, Number, Number\n\t    - The numbers are the x and y coordinates where the line segment is on both edges of the circle.\n\t  - String (`'enclosed'`), Number, Number, Number, Number\n\t    - The numbers are the x and y coordinates of the line segment if it is fully inside of the circle.\n\t  - String (`'secant'`), Number, Number, Number, Number\n\t    - The numbers are the x and y coordinates where the line segment intersects the circle.\n\t  - String (`'tangent'`), Number, Number, Boolean (`nil`), Boolean (`nil`)\n\t    - `x1` and `x2` represent where the line segment intersects the circle.\n\t  - Boolean (`false`), Boolean (`nil`), Boolean (`nil`), Boolean (`nil`), Boolean (`nil`)\n\t    - No intersection.\n    - For more see the [specs](spec.lua).\n\n##### mlib.circle.isCircleCompletelyInside\n- Checks if one circle is completely inside of another circle.\n- Synopsis:\n  - `completelyInside = mlib.circle.isCircleCompletelyInside( c1x, c1y, c1radius, c2x, c2y, c2radius )`\n- Arguments:\n  - `c1x`, `c1y`: Numbers. The x and y coordinates of the first circle.\n  - `c1radius`: Number. The radius of the first circle.\n  - `c2x`, `c2y`: Numbers. The x and y coordinates of the second circle.\n  - `c2radius`: Number. The radius of the second circle.\n- Returns:\n  - `completelyInside`: Boolean.\n    - `true` if circle1 is inside of circle2.\n\t- `false` if circle1 is not __completely__ inside of circle2.\n\n##### mlib.circle.isCircleCompletelyInsidePolygon\n- Checks if a circle is completely inside the polygon.\n- Synopses:\n  - `inPolygon = mlib.polygon.isCircleCompletelyInside( cx, cy, radius, vertices )`\n  - `inPolygon = mlib.polygon.isCircleCompletelyInside( cx, cy, radius, ... )`\n- Arguments:\n  - `cx`, `cy`: Numbers. The x and y coordinates for the center of the circle.\n  - `radius`: Number. The radius of the circle.\n  - `vertices`: Table. The vertices of the polygon in the format `{ x1, y1, x2, y2, x3, y3, ... }`\n  - `...`: Numbers. The x and y coordinates of the polygon. (Same as using `unpack( vertices )`)\n- Returns:\n  - `inPolygon`: Boolean.\n    - `true` if the circle is __completely__ inside the polygon.\n\t- `false` if the circle is not inside the polygon.\n\n##### mlib.circle.isPointOnCircle\n- Checks if a point is __exactly__ on the edge of the circle.\n- Synopsis:\n  - `onCircle = mlib.circle.checkPoint( px, px, cx, cy, radius )`\n- Arguments:\n  - `px`, `py`: Numbers. The x and y coordinates of the point being tested.\n  - `cx`, `cy`: Numbers. The x and y coordinates of the center of the circle.\n  - `radius`: Number. The radius of the circle.\n- Returns:\n  - `onCircle`: Boolean.\n    - `true` if the point is on the circle.\n\t- `false` if the point is on the inside or outside of the circle.\n- Notes:\n  - Will return false if the point is inside __or__ outside of the circle.\n\n##### mlib.circle.isPolygonCompletelyInside\n- Checks if a polygon is completely inside of a circle.\n- Synopsis:\n  - `completelyInside = mlib.circle.isPolygonCompletelyInside( circleX, circleY, circleRadius, vertices )`\n  - `completelyInside = mlib.circle.isPolygonCompletelyInside( circleX, circleY, circleRadius, ... )`\n- Arguments:\n  - `circleX`, `circleY`: Numbers. The x and y coordinates of the circle.\n  - `circleRadius`: Number. The radius of the circle.\n  - `vertices`: Table. A table containing all of the vertices of the polygon.\n  - `...`: Numbers. All of the points of the polygon.\n- Returns:\n  - `completelyInside`: Boolean.\n    - `true` if the polygon is inside of the circle.\n\t- `false` if the polygon is not __completely__ inside of the circle.\n\n#### mlib.statistics\n- Handles statistical aspects of math.\n\n##### mlib.statistics.getCentralTendency\n- Gets the central tendency of the data.\n- Synopses:\n  - `modes, occurrences, median, mean = mlib.statistics.getCentralTendency( data )`\n  - `modes, occurrences, median, mean = mlib.statistics.getCentralTendency( ... )`\n- Arguments:\n  - `data`: Table. A table containing the values of data.\n  - `...`: Numbers. All of the numbers in the data set.\n- Returns:\n  - `modes, occurrences`: Table, Number. The modes of the data and the number of times it occurs. See [mlib.statistics.getMode](#mlibstatisticsgetmode).\n  - `median`: Number. The median of the data set.\n  - `mean`: Number. The mean of the data set.\n\n##### mlib.statistics.getDispersion\n- Gets the dispersion of the data.\n- Synopses:\n  - `variationRatio, range, standardDeviation = mlib.statistics.getDispersion( data )`\n  - `variationRatio, range, standardDeviation = mlib.statistics.getDispersion( ... )`\n- Arguments:\n  - `data`: Table. A table containing the values of data.\n  - `...`: Numbers. All of the numbers in the data set.\n- Returns:\n  - `variationRatio`: Number. The variation ratio of the data set.\n  - `range`: Number. The range of the data set.\n  - `standardDeviation`: Number. The standard deviation of the data set.\n\n##### mlib.statistics.getMean\n- Gets the arithmetic mean of the data.\n- Synopses:\n  - `mean = mlib.statistics.getMean( data )`\n  - `mean = mlib.statistics.getMean( ... )`\n- Arguments:\n  - `data`: Table. A table containing the values of data.\n  - `...`: Numbers. All of the numbers in the data set.\n- Returns:\n  - `mean`: Number. The arithmetic mean of the data set.\n\n##### mlib.statistics.getMedian\n- Gets the median of the data set.\n- Synopses:\n  - `median = mlib.statistics.getMedian( data )`\n  - `median = mlib.statistics.getMedian( ... )`\n- Arguments:\n  - `data`: Table. A table containing the values of data.\n  - `...`: Numbers. All of the numbers in the data set.\n- Returns:\n  - `median`: Number. The median of the data.\n\n##### mlib.statistics.getMode\n- Gets the mode of the data set.\n- Synopses:\n  - `mode, occurrences = mlib.statistics.getMode( data )`\n  - `mode, occurrences = mlib.statistics.getMode( ... )`\n- Arguments:\n  - `data`: Table. A table containing the values of data.\n  - `...`: Numbers. All of the numbers in the data set.\n- Returns:\n  - `mode`: Table. The mode(s) of the data.\n  - `occurrences`: Number. The number of time the mode(s) occur.\n\n##### mlib.statistics.getRange\n- Gets the range of the data set.\n- Synopses:\n  - `range = mlib.statistics.getRange( data )`\n  - `range = mlib.statistics.getRange( ... )`\n- Arguments:\n  - `data`: Table. A table containing the values of data.\n  - `...`: Numbers. All of the numbers in the data set.\n- Returns:\n  - `range`: Number. The range of the data.\n\n##### mlib.statistics.getStandardDeviation\n- Gets the standard deviation of the data.\n- Synopses:\n  - `standardDeviation = mlib.statistics.getStandardDeviation( data )`\n  - `standardDeviation = mlib.statistics.getStandardDeviation( ... )`\n- Arguments:\n  - `data`: Table. A table containing the values of data.\n  - `...`: Numbers. All of the numbers in the data set.\n- Returns:\n  - `standardDeviation`: Number. The standard deviation of the data set.\n\n##### mlib.statistics.getVariance\n- Gets the variation of the data.\n- Synopses:\n  - `variance = mlib.statistics.getVariance( data )`\n  - `variance = mlib.statistics.getVariance( ... )`\n- Arguments:\n  - `data`: Table. A table containing the values of data.\n  - `...`: Numbers. All of the numbers in the data set.\n- Returns:\n  - `variance`: Number. The variation of the data set.\n\n##### mlib.statistics.getVariationRatio\n- Gets the variation ratio of the data.\n- Synopses:\n  - `variationRatio = mlib.statistics.getVariationRatio( data )`\n  - `variationRatio = mlib.statistics.getVariationRatio( ... )`\n- Arguments:\n  - `data`: Table. A table containing the values of data.\n  - `...`: Numbers. All of the numbers in the data set.\n- Returns:\n  - `variationRatio`: Number. The variation ratio of the data set.\n\n#### mlib.math\n- Miscellaneous functions that have no home.\n\n##### mlib.math.getAngle\n- Gets the angle between three points.\n- Synopsis:\n  - `angle = mlib.math.getAngle( x1, y1, x2, y2, x3, y3 )`\n- Arguments:\n  - `x1`, `y1`: Numbers. The x and y coordinates of the first point.\n  - `x2`, `y2`: Numbers. The x and y coordinates of the vertex of the two points.\n  - `x3`, `y3`: Numbers. The x and y coordinates of the second point.\n\n##### mlib.math.getPercentage\n- Gets the percentage of a number.\n- Synopsis:\n  - `percentage = mlib.math.getPercentage( percent, number )`\n- Arguments:\n  - `percent`: Number. The decimal value of the percent (i.e. 100% is 1, 50% is .5).\n  - `number`: Number. The number to get the percentage of.\n- Returns:\n  - `percentage`: Number. The `percent`age or `number`.\n\n##### mlib.math.getPercentOfChange\n- Gets the percent of change from one to another.\n- Synopsis:\n  - `change = mlib.math.getPercentOfChange( old, new )`\n- Arguments:\n  - `old`: Number. The original number.\n  - `new`: Number. The new number.\n- Returns:\n  - `change`: Number. The percent of change from `old` to `new`.\n\n##### mlib.math.getQuadraticRoots\n- Gets the quadratic roots of the the equation.\n- Synopsis:\n  - `root1, root2 = mlib.math.getQuadraticRoots( a, b, c )`\n- Arguments:\n  - `a`, `b`, `c`: Numbers. The a, b, and c values of the equation `a * x ^ 2 + b * x ^ 2 + c`.\n- Returns:\n  - `root1`, `root2`: Numbers. The roots of the equation (where `a * x ^ 2 + b * x ^ 2 + c = 0`).\n\n##### mlib.math.getRoot\n- Gets the `n`th root of a number.\n- Synopsis:\n  - `x = mlib.math.getRoot( number, root )`\n- Arguments:\n  - `number`: Number. The number to get the root of.\n  - `root`: Number. The root.\n- Returns:\n  - `x`: The `root`th root of `number`.\n- Example:\n```lua\nlocal a = mlib.math.getRoot( 4, 2 ) -- Same as saying 'math.pow( 4, .5 )' or 'math.sqrt( 4 )' in this case.\nlocal b = mlib.math.getRoot( 27, 3 )\n\nprint( a, b ) --\u003e 2, 3\n```\n  - For more, see the [specs](spec.lua).\n\n##### mlib.math.getSummation\n- Gets the summation of numbers.\n- Synopsis:\n  - `summation = mlib.math.getSummation( start, stop, func )`\n- Arguments:\n  - `start`: Number. The number at which to start the summation.\n  - `stop`: Number. The number at which to stop the summation.\n  - `func`: Function. The method to add the numbers.\n    - Arguments:\n\t  - `i`: Number. Index.\n\t  - `previous`: Table. The previous values used.\n- Returns:\n  - `Summation`: Number. The summation of the numbers.\n  - For more, see the [specs](spec.lua).\n\n##### mlib.math.isPrime\n- Checks if a number is prime.\n- Synopsis:\n  - `isPrime = mlib.math.isPrime( x )`\n- Arguments:\n  - `x`: Number. The number to check if it's prime.\n- Returns:\n  - `isPrime`: Boolean.\n    - `true` if the number is prime.\n\t- `false` if the number is not prime.\n\n##### mlib.math.round\n- Rounds a number to the given decimal place.\n- Synopsis:\n  - `rounded = mlib.math.round( number, [place] )\n- Arguments:\n  - `number`: Number. The number to round.\n  - `place (1)`: Number. The decimal place to round to. Defaults to 1.\n- Returns:\n  - The rounded number.\n  - For more, see the [specs](spec.lua).\n\n#### Aliases\n| Alias                                         | Corresponding Function                                                            |\n| ----------------------------------------------|:---------------------------------------------------------------------------------:|\n| milb.line.getDistance                         | [mlib.line.getLength](#mliblinegetlength)                                         |\n| mlib.line.getCircleIntersection               | [mlib.circle.getLineIntersection](#mlibcirclegetlineintersection)                 |\n| milb.line.getPolygonIntersection              | [mlib.polygon.getLineIntersection](#mlibpolygongetlineintersection)               |\n| mlib.line.getLineIntersection                 | [mlib.line.getIntersection](#mliblinegetintersection)                             |\n| mlib.segment.getCircleIntersection            | [mlib.circle.getSegmentIntersection](#mlibcirclegetsegmentintersection)           |\n| milb.segment.getPolygonIntersection           | [mlib.pollygon.getSegmentIntersection](#mlibpollygongetsegmentintersection)       |\n| mlib.segment.getLineIntersection              | [mlib.line.getSegmentIntersection](#mliblinegetsegmentintersection)               |\n| mlib.segment.getSegmentIntersection           | [mlib.segment.getIntersection](#mlibsegmentgetintersection)                       |\n| milb.segment.isSegmentCompletelyInsideCircle  | [mlib.circle.isSegmentCompletelyInside](#mlibcircleissegmentcompletelyinside)     |\n| mlib.segment.isSegmentCompletelyInsidePolygon | [mlib.polygon.isSegmentCompletelyInside](#mlibpolygonissegmentcompletelyinside)   |\n| mlib.circle.getPolygonIntersection            | [mlib.polygon.getCircleIntersection](#mlibpolygongetcircleintersection)           |\n| mlib.circle.isCircleInsidePolygon             | [mlib.polygon.isCircleInside](#mlibpolygoniscircleinside)                         |\n| mlib.circle.isCircleCompletelyInsidePolygon   | [mlib.polygon.isCircleCompletelyInside](#mlibpolygoniscirclecompletelyinside)     |\n| mlib.polygon.isCircleCompletelyOver           | [mlib.circleisPolygonCompletelyInside](#mlibcircleispolygoncompletelyinside)      |\n\n## License\n\nzlib license. See LICENSE.md\n","funding_links":[],"categories":["Lua","Math"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdavisdude%2Fmlib","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdavisdude%2Fmlib","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdavisdude%2Fmlib/lists"}