MLib is a math and shape-intersection detection library written in Lua. It's aim is to be robust and easy to use.
NOTE:
If you are looking for a library that handles updating/collision responses for you, take a look at hxdx. It uses MLib functions as well as Box2d to handle physics calculations.
You can download the latest stable version of MLib by downloading the latest release. You can download the latest working version of MLib by downloading the latest commit. Documentation will only be updated upon releases, not upon commits.
To use MLib, simply place mlib.lua inside the desired folder in your project. Then use the require 'path.to.mlib'
to use any of the functions.
If you don't have LÖVE installed, you can download the .zip of the demo from the Executables folder and extract and run the .exe that way. You can see some examples of the code in action here. All examples are done using the awesome engine of LÖVE. To run them properly, download the .love file and install LÖVE to your computer. After that, make sure you set .love files to open with "love.exe". For more, see here.
If you run Windows and have Telescope in %USERPROFILE%\Documents\GitHub
(you can also manually change the path in test.bat) you can simply run test.bat and it will display the results, and then clean up after it's finished.
Alternatively, you can find the tests here. Keep in mind that you may need to change certain semantics to suit your OS. You can run them via Telescope and type the following command in the command-line of the root folder:
tsc -f specs.lua
If that does not work, you made need to put a link to Lua inside of the folder for telescope
and run the following command:
lua tsc -f specs.lua
If 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
cd C:\Path\to\telescope\
And 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. ![Success](Reference Pictures/Success.png)
mlib.line.checkPoint
onPoint = mlib.line.checkPoint( px, px, x1, y1, x2, y2 )
px
, py
: Numbers. The x and y coordinates of the point being tested.x1
, y1
, x2
, y2
: Numbers. Two x and y coordinates of the line being tested.onPoint
: Boolean.true
if the point is on the line.false
if it does not.mlib.line.checkPoint( px, px, slope, intercept )
because this would lead to errors on vertical lines.mlib.line.getClosestPoint
cx, cy = mlib.line.getClosestPoint( px, py, x1, y1, x2, y2 )
cx, cy = mlib.line.getClosestPoint( px, py, slope, intercept )
x
, y
: Numbers. The x and y coordinates of the point.x1
, y1
, x2
, y2
: Numbers. Two x and y coordinates on the line.slope
, intercept
:false
). The slope and y-intercept of a vertical line.cx
, cy
: Numbers. The closest points that lie on the line to the point.mlib.line.getYIntercept
intercept, isVertical = mlib.line.getYIntercept( x1, y1, x2, y2 )
intercept, isVertical = mlib.line.getYIntercept( x1, y1, slope )
x1
, y1
, x2
, y2
: Numbers. Two x and y coordinates that lie on the line.slope
:intercept
:x1
coordinate of the line if the line is vertical.isVertical
:true
if the line is vertical, false
if the line is not vertical.mlib.line.getIntersection
x, y = mlib.line.getIntersection( x1, y1, x2, y2, x3, y3, x4, y4 )
x, y = mlib.line.getIntersection( slope1, intercept1, x3, y3, x4, y4 )
x, y = mlib.line.getIntersection( slope1, intercept1, slope2, intercept2 )
x1
, y1
, x2
, y2
: Numbers. Two x and y coordinates that lie on the first line.x3
, y3
, x4
, y4
: Numbers. Two x and y coordinates that lie on the second line.slope1
, intercept1
:false
). The slope and y-intercept of the first line (if the first line is vertical).slope2
, intercept2
:false
). The slope and y-intercept of the second line (if the second line is vertical).x
, y
:true
, nil
: The lines are collinear.false
, nil
: The lines are parallel and not collinear.mlib.line.getLength
x1
, y1
, x2
, y2
: Numbers. Two x and y coordinates.length
: Number. The distance between the two points.mlib.line.getMidpoint
x, y = mlib.line.getMidpoint( x1, y1, x2, y2 )
x1
, y1
, x2
, y2
: Numbers. Two x and y coordinates.x
, y
: Numbers. The midpoint x and y coordinates.mlib.line.getPerpendicularSlope
perpSlope = mlib.line.getPerpendicularSlope( x1, y1, x2, y2 )
perpSlope = mlib.line.getPerpendicularSlope( slope )
x1
, y1
, x2
, y2
: Numbers. Two x and y coordinates.slope
: Number. The slope of the line.perpSlope
:false
). The perpendicular slope of the line (if the original line was horizontal).mlib.line.getSegmentIntersection
x1, y1, x2, y2 = mlib.line.getSegmentIntersection( x1, y1, x2, y2, x3, y3, x4, y4 )
x1, y1, x2, y2 = mlib.line.getSegmentIntersection( x1, y1, x2, y2, slope, intercept )
x1
, y1
, x2
, y2
: Numbers. Two x and y coordinates that lie on the line segment.x3
, y3
, x4
, y4
: Numbers. Two x and y coordinates that lie on the line.slope
, intercept
:false
). The slope and y-intercept of the line (if the line is vertical).x1
, y1
, x2
, y2
:nil
), Boolean (nil
).false
), Boolean (nil
), Boolean (nil
),nil
). If the line and segment don't intersect.mlib.line.getSlope
x1
, y1
, x2
, y2
: Numbers. Two x and y coordinates.slope
:false
). The slope of the line (if the line is vertical).mlib.segment.checkPoint
onSegment = mlib.segment.checkPoint( px, py, x1 y1, x2, y2 )
px
, py
: Numbers. The x and y coordinates of the point being checked.x1
, y1
, x2
, y2
: Numbers. Two x and y coordinates.onSegment
: Boolean.true
if the point lies on the line segment.false
if the point does not lie on the line segment.mlib.segment.getPerpendicularBisector
x, y, slope = mlib.segment.getPerpendicularBisector( x1, y1, x2, y2 )
x1
, y1
, x2
, y2
: Numbers. Two x and y coordinates.x
, y
: Numbers. The midpoint of the line.slope
:false
). The perpendicular slope of the line (if the original line was horizontal).mlib.segment.getIntersection
cx1, cy1, cx2, cy2 = mlib.segment.getIntersection( x1, y1, x2, y2, x3, y3 x4, y4 )
x1
, y1
, x2
, y2
: Numbers. Two x and y coordinates of the first line segment.x3
, y3
, x4
, y4
: Numbers. Two x and y coordinates of the second line segment.cx1
, cy1
, cx2
, cy2
:nil
), Boolean (nil
).false
), Boolean (nil
), Boolean (nil
) , Boolean (nil
).mlib.polygon.checkPoint
inPolygon = mlib.polygon.checkPoint( px, py, vertices )
inPolygon = mlib.polygon.checkPoint( px, py, ... )
px
, py
: Numbers. The x and y coordinate of the point being checked.vertices
: Table. The vertices of the polygon in the format { x1, y1, x2, y2, x3, y3, ... }
...
: Numbers. The x and y coordinates of the polygon. (Same as using unpack( vertices )
)inPolygon
: Boolean.true
if the point is inside the polygon.false
if the point is not inside the polygon.mlib.polygon.getCentroid
cx, cy = mlib.polygon.getCentroid( vertices )
cx, cy = mlib.polygon.getCentroid( ... )
vertices
: Table. The vertices of the polygon in the format { x1, y1, x2, y2, x3, y3, ... }
...
: Numbers. The x and y coordinates of the polygon. (Same as using unpack( vertices )
)cx
, cy
: Numbers. The x and y coordinates of the centroid.mlib.polygon.getCircleIntersection
intersections = mlib.polygon.getCircleIntersection( cx, cy, radius, vertices )
cx
, cy
: Number. The coordinates of the center of the circle.radius
: Number. The radius of the circle.vertices
: Table. The vertices of the polygon in the format { x1, y1, x2, y2, x3, y3, ... }
...
: Numbers. The x and y coordinates of the polygon. (Same as using unpack( vertices )
)intersections
: Table. Contains the intersections and type.local tab = _.polygon.getCircleIntersection( 5, 5, 1, 4, 4, 6, 4, 6, 6, 4, 6 )
for i = 1, # tab do
print( i .. ':', unpack( tab[i] ) )
end
-- 1: tangent 5 4
-- 2: tangent 6 5
-- 3: tangent 5 6
-- 4: tagnent 4 5
mlib.polygon.getLineIntersection
intersections = mlib.polygon.getLineIntersection( x1, y1, x2, y2, vertices )
x1
, y1
, x2
, y2
: Numbers. Two x and y coordinates.vertices
: Table. The vertices of the polygon in the format { x1, y1, x2, y2, x3, y3, ... }
...
: Numbers. The x and y coordinates of the polygon. (Same as using unpack( vertices )
)intersections
: Table. Contains the intersections.{ 0, 4, 0, 0 }
would become { 0, 4 }, { 0, 0 }
.mlib.polygon.getPolygonArea
area = mlib.polygon.getArea( vertices )
vertices
: Table. The vertices of the polygon in the format { x1, y1, x2, y2, x3, y3, ... }
...
: Numbers. The x and y coordinates of the polygon. (Same as using unpack( vertices )
)area
: Number. The area of the polygon.mlib.polygon.getPolygonIntersection
intersections = mlib.polygon.getPolygonIntersections( polygon1, polygon2 )
polygon1
: Table. The vertices of the first polygon in the format { x1, y1, x2, y2, x3, y3, ... }
polygon2
: Table. The vertices of the second polygon in the format { x1, y1, x2, y2, x3, y3, ... }
intersections
: Table. A table of the points of intersection.mlib.polygon.getSegmentIntersection
intersections = mlib.polygon.getSegmentIntersection( x1, y1, x2, y2, vertices )
x1
, y1
, x2
, y2
: Numbers. Two x and y coordinates.vertices
: Table. The vertices of the polygon in the format { x1, y1, x2, y2, x3, y3, ... }
...
: Numbers. The x and y coordinates of the polygon. (Same as using unpack( vertices )
)intersections
: Table. Contains the intersections.mlib.polygon.getSignedPolygonArea
area = mlib.polygon.getLineIntersection( vertices )
vertices
: Table. The vertices of the polygon in the format { x1, y1, x2, y2, x3, y3, ... }
...
: Numbers. The x and y coordinates of the polygon. (Same as using unpack( vertices )
)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.mlib.polygon.getTriangleHeight
height = mlib.polygon.getTriangleHeigh( base, x1, y1, x2, y2, x3, y3 )
height = mlib.polygon.getTriangleHeight( base, area )
base
: Number. The length of the base of the triangle.x1
, y1
, x2
, y2
, x3
, y3
: Numbers. The x and y coordinates of the triangle.area
: Number. The regular area of the triangle. Not the signed area.height
: Number. The height of the triangle.mlib.polygon.isCircleInside
inPolygon = mlib.polygon.isCircleInside( cx, cy, radius, vertices )
inPolygon = mlib.polygon.isCircleInside( cx, cy, radius, ... )
cx
, cy
: Numbers. The x and y coordinates for the center of the circle.radius
: Number. The radius of the circle.vertices
: Table. The vertices of the polygon in the format { x1, y1, x2, y2, x3, y3, ... }
...
: Numbers. The x and y coordinates of the polygon. (Same as using unpack( vertices )
)inPolygon
: Boolean.true
if the circle is inside the polygon.false
if the circle is not inside the polygon.mlib.polygon.isCircleCompletelyInside
inPolygon = mlib.polygon.isCircleCompletelyInside( cx, cy, radius, vertices )
inPolygon = mlib.polygon.isCircleCompletelyInside( cx, cy, radius, ... )
cx
, cy
: Numbers. The x and y coordinates for the center of the circle.radius
: Number. The radius of the circle.vertices
: Table. The vertices of the polygon in the format { x1, y1, x2, y2, x3, y3, ... }
...
: Numbers. The x and y coordinates of the polygon. (Same as using unpack( vertices )
)inPolygon
: Boolean.true
if the circle is completely inside the polygon.false
if the circle is not inside the polygon.mlib.polygon.isPolygonInside
inPolygon = mlib.polygon.isPolygonInside( polygon1, polygon2 )
polygon1
: Table. The vertices of the first polygon in the format { x1, y1, x2, y2, x3, y3, ... }
polygon2
: Table. The vertices of the second polygon in the format { x1, y1, x2, y2, x3, y3, ... }
inPolygon
: Boolean.true
if the polygon2
is inside of polygon1
.false
if polygon2
is not inside of polygon2
.polygon2
are inside of the polygon1
.mlib.polygon.isPolygonCompletelyInside
inPolygon = mlib.polygon.isPolygonCompletelyInside( polygon1, polygon2 )
polygon1
: Table. The vertices of the first polygon in the format { x1, y1, x2, y2, x3, y3, ... }
polygon2
: Table. The vertices of the second polygon in the format { x1, y1, x2, y2, x3, y3, ... }
inPolygon
: Boolean.true
if the polygon2
is completely inside of polygon1
.false
if polygon2
is not inside of polygon2
.mlib.polygon.isSegmentInside
inPolygon = mlib.polygon.isSegmentInside( x1, y1, x2, y2, vertices )
inPolygon = mlib.polygon.isSegmentInside( x1, y1, x2, y2, ... )
x1
, y1
, x2
, y2
: Numbers. The x and y coordinates of the line segment.vertices
: Table. The vertices of the polygon in the format { x1, y1, x2, y2, x3, y3, ... }
...
: Numbers. The x and y coordinates of the polygon. (Same as using unpack( vertices )
)inPolygon
: Boolean.true
if the line segment is inside the polygon.false
if the line segment is not inside the polygon.mlib.polygon.isSegmentCompletelyInside
inPolygon = mlib.polygon.isSegmentCompletelyInside( x1, y1, x2, y2, vertices )
inPolygon = mlib.polygon.isSegmentCompletelyInside( x1, y1, x2, y2, ... )
x1
, y1
, x2
, y2
: Numbers. The x and y coordinates of the line segment.vertices
: Table. The vertices of the polygon in the format { x1, y1, x2, y2, x3, y3, ... }
...
: Numbers. The x and y coordinates of the polygon. (Same as using unpack( vertices )
)inPolygon
: Boolean.true
if the line segment is completely inside the polygon.false
if the line segment is not inside the polygon.mlib.circle.checkPoint
inCircle = mlib.circle.checkPoint( px, px, cx, cy, radius )
px
, py
: Numbers. The x and y coordinates of the point being tested.cx
, cy
: Numbers. The x and y coordinates of the center of the circle.radius
: Number. The radius of the circle.inCircle
: Boolean.true
if the point is inside or on the circle.false
if the point is outside of the circle.mlib.circle.getArea
area = mlib.circle.getArea( radius )
radius
: Number. The radius of the circle.area
: Number. The area of the circle.mlib.circle.getCircleIntersection
c1x
, c1y
: Numbers. The x and y coordinate of the first circle.radius1
: Number. The radius of the first circle.c2x
, c2y
: Numbers. The x and y coordinate of the second circle.radius2
: Number. The radius of the second circle.intersections
: Table. A table that contains the type and where the circle collides. See the [specs](spec.lua# L698) for more.mlib.circle.getCircumference
circumference = mlib.circle.getCircumference( radius )
radius
: Number. The radius of the circle.circumference
: Number. The circumference of a circle.mlib.circle.getLineIntersection
intersections = mlib.circle.getLineIntersections( cx, cy, radius, x1, y1, x2, y2 )
cx
, cy
: Numbers. The x and y coordinates for the center of the circle.radius
: Number. The radius of the circle.x1
, y1
, x2
, y2
: Numbers. Two x and y coordinates the lie on the line.intersections
: Table. A table with the type and where the intersections happened. Table is formatted:type
, x1
, y1
, x2
, y2
'secant'
), Number, Number, Number, Number'tangent'
), Number, Number, Boolean (nil
), Boolean (nil
)x1
and x2
represent where the line intersects the circle.false
), Boolean (nil
), Boolean (nil
), Boolean (nil
), Boolean (nil
)mlib.circle.getSegmentIntersection
intersections = mlib.circle.getSegmentIntersections( cx, cy, radius, x1, y1, x2, y2 )
cx
, cy
: Numbers. The x and y coordinates for the center of the circle.radius
: Number. The radius of the circle.x1
, y1
, x2
, y2
: Numbers. The two x and y coordinates of the line segment.intersections
: Table. A table with the type and where the intersections happened. Table is formatted:type
, x1
, y1
, x2
, y2
'chord'
), Number, Number, Number, Number'enclosed'
), Number, Number, Number, Number'secant'
), Number, Number, Number, Number'tangent'
), Number, Number, Boolean (nil
), Boolean (nil
)x1
and x2
represent where the line segment intersects the circle.false
), Boolean (nil
), Boolean (nil
), Boolean (nil
), Boolean (nil
)mlib.circle.isCircleCompletelyInside
completelyInside = mlib.circle.isCircleCompletelyInside( c1x, c1y, c1radius, c2x, c2y, c2radius )
c1x
, c1y
: Numbers. The x and y coordinates of the first circle.c1radius
: Number. The radius of the first circle.c2x
, c2y
: Numbers. The x and y coordinates of the second circle.c2radius
: Number. The radius of the second circle.completelyInside
: Boolean.true
if circle1 is inside of circle2.false
if circle1 is not completely inside of circle2.mlib.circle.isCircleCompletelyInsidePolygon
inPolygon = mlib.polygon.isCircleCompletelyInside( cx, cy, radius, vertices )
inPolygon = mlib.polygon.isCircleCompletelyInside( cx, cy, radius, ... )
cx
, cy
: Numbers. The x and y coordinates for the center of the circle.radius
: Number. The radius of the circle.vertices
: Table. The vertices of the polygon in the format { x1, y1, x2, y2, x3, y3, ... }
...
: Numbers. The x and y coordinates of the polygon. (Same as using unpack( vertices )
)inPolygon
: Boolean.true
if the circle is completely inside the polygon.false
if the circle is not inside the polygon.mlib.circle.isPointOnCircle
onCircle = mlib.circle.checkPoint( px, px, cx, cy, radius )
px
, py
: Numbers. The x and y coordinates of the point being tested.cx
, cy
: Numbers. The x and y coordinates of the center of the circle.radius
: Number. The radius of the circle.onCircle
: Boolean.true
if the point is on the circle.false
if the point is on the inside or outside of the circle.mlib.circle.isPolygonCompletelyInside
completelyInside = mlib.circle.isPolygonCompletelyInside( circleX, circleY, circleRadius, vertices )
completelyInside = mlib.circle.isPolygonCompletelyInside( circleX, circleY, circleRadius, ... )
circleX
, circleY
: Numbers. The x and y coordinates of the circle.circleRadius
: Number. The radius of the circle.vertices
: Table. A table containing all of the vertices of the polygon....
: Numbers. All of the points of the polygon.completelyInside
: Boolean.true
if the polygon is inside of the circle.false
if the polygon is not completely inside of the circle.mlib.statistics.getCentralTendency
modes, occurrences, median, mean = mlib.statistics.getCentralTendency( data )
modes, occurrences, median, mean = mlib.statistics.getCentralTendency( ... )
data
: Table. A table containing the values of data....
: Numbers. All of the numbers in the data set.modes, occurrences
: Table, Number. The modes of the data and the number of times it occurs. See mlib.statistics.getMode.median
: Number. The median of the data set.mean
: Number. The mean of the data set.mlib.statistics.getDispersion
variationRatio, range, standardDeviation = mlib.statistics.getDispersion( data )
variationRatio, range, standardDeviation = mlib.statistics.getDispersion( ... )
data
: Table. A table containing the values of data....
: Numbers. All of the numbers in the data set.variationRatio
: Number. The variation ratio of the data set.range
: Number. The range of the data set.standardDeviation
: Number. The standard deviation of the data set.mlib.statistics.getMean
mean = mlib.statistics.getMean( data )
mean = mlib.statistics.getMean( ... )
data
: Table. A table containing the values of data....
: Numbers. All of the numbers in the data set.mean
: Number. The arithmetic mean of the data set.mlib.statistics.getMedian
median = mlib.statistics.getMedian( data )
median = mlib.statistics.getMedian( ... )
data
: Table. A table containing the values of data....
: Numbers. All of the numbers in the data set.median
: Number. The median of the data.mlib.statistics.getMode
mode, occurrences = mlib.statistics.getMode( data )
mode, occurrences = mlib.statistics.getMode( ... )
data
: Table. A table containing the values of data....
: Numbers. All of the numbers in the data set.mode
: Table. The mode(s) of the data.occurrences
: Number. The number of time the mode(s) occur.mlib.statistics.getRange
range = mlib.statistics.getRange( data )
range = mlib.statistics.getRange( ... )
data
: Table. A table containing the values of data....
: Numbers. All of the numbers in the data set.range
: Number. The range of the data.mlib.statistics.getStandardDeviation
standardDeviation = mlib.statistics.getStandardDeviation( data )
standardDeviation = mlib.statistics.getStandardDeviation( ... )
data
: Table. A table containing the values of data....
: Numbers. All of the numbers in the data set.standardDeviation
: Number. The standard deviation of the data set.mlib.statistics.getVariance
variance = mlib.statistics.getVariance( data )
variance = mlib.statistics.getVariance( ... )
data
: Table. A table containing the values of data....
: Numbers. All of the numbers in the data set.variance
: Number. The variation of the data set.mlib.statistics.getVariationRatio
variationRatio = mlib.statistics.getVariationRatio( data )
variationRatio = mlib.statistics.getVariationRatio( ... )
data
: Table. A table containing the values of data....
: Numbers. All of the numbers in the data set.variationRatio
: Number. The variation ratio of the data set.mlib.math.getAngle
angle = mlib.math.getAngle( x1, y1, x2, y2, x3, y3 )
x1
, y1
: Numbers. The x and y coordinates of the first point.x2
, y2
: Numbers. The x and y coordinates of the vertex of the two points.x3
, y3
: Numbers. The x and y coordinates of the second point.mlib.math.getPercentage
percentage = mlib.math.getPercentage( percent, number )
percent
: Number. The decimal value of the percent (i.e. 100% is 1, 50% is .5).number
: Number. The number to get the percentage of.percentage
: Number. The percent
age or number
.mlib.math.getPercentOfChange
change = mlib.math.getPercentOfChange( old, new )
old
: Number. The original number.new
: Number. The new number.change
: Number. The percent of change from old
to new
.mlib.math.getQuadraticRoots
root1, root2 = mlib.math.getQuadraticRoots( a, b, c )
a
, b
, c
: Numbers. The a, b, and c values of the equation a * x ^ 2 + b * x ^ 2 + c
.root1
, root2
: Numbers. The roots of the equation (where a * x ^ 2 + b * x ^ 2 + c = 0
).mlib.math.getRoot
n
th root of a number.x = mlib.math.getRoot( number, root )
number
: Number. The number to get the root of.root
: Number. The root.x
: The root
th root of number
.local a = mlib.math.getRoot( 4, 2 ) -- Same as saying 'math.pow( 4, .5 )' or 'math.sqrt( 4 )' in this case.
local b = mlib.math.getRoot( 27, 3 )
print( a, b ) --> 2, 3
mlib.math.getSummation
summation = mlib.math.getSummation( start, stop, func )
start
: Number. The number at which to start the summation.stop
: Number. The number at which to stop the summation.func
: Function. The method to add the numbers.i
: Number. Index.previous
: Table. The previous values used.Summation
: Number. The summation of the numbers.mlib.math.isPrime
isPrime = mlib.math.isPrime( x )
x
: Number. The number to check if it's prime.isPrime
: Boolean.true
if the number is prime.false
if the number is not prime.mlib.math.round
number
: Number. The number to round.place (1)
: Number. The decimal place to round to. Defaults to 1.Alias | Corresponding Function |
---|---|
milb.line.getDistance | mlib.line.getLength |
mlib.line.getCircleIntersection | mlib.circle.getLineIntersection |
milb.line.getPolygonIntersection | mlib.polygon.getLineIntersection |
mlib.line.getLineIntersection | mlib.line.getIntersection |
mlib.segment.getCircleIntersection | mlib.circle.getSegmentIntersection |
milb.segment.getPolygonIntersection | mlib.pollygon.getSegmentIntersection |
mlib.segment.getLineIntersection | mlib.line.getSegmentIntersection |
mlib.segment.getSegmentIntersection | mlib.segment.getIntersection |
milb.segment.isSegmentCompletelyInsideCircle | mlib.circle.isSegmentCompletelyInside |
mlib.segment.isSegmentCompletelyInsidePolygon | mlib.polygon.isSegmentCompletelyInside |
mlib.circle.getPolygonIntersection | mlib.polygon.getCircleIntersection |
mlib.circle.isCircleInsidePolygon | mlib.polygon.isCircleInside |
mlib.circle.isCircleCompletelyInsidePolygon | mlib.polygon.isCircleCompletelyInside |
mlib.polygon.isCircleCompletelyOver | mlib.circleisPolygonCompletelyInside |
Author: Davisdude
Source Code: https://github.com/davisdude/mlib
License: Zlib license