diff --git a/init.moon b/init.moon index 68c5448..1a6c1ad 100644 --- a/init.moon +++ b/init.moon @@ -908,6 +908,48 @@ getAngle = (x1, y1, x2, y2, x3, y3) -> getPercentage = (percent, n) -> percent * n + +getCircleArea = (radius) -> + math = math + math.pi * (radius * radius) + +getCircumference = (radius) -> + math = math + 2 * math.pi * radius + +getCircleCircleIntersection = (circle1x, circle1y, radius1, circle2x, circle2y, radius2) -> + length = getLength(circle1x, circle1y, circle2x, circle2y) + if length > radius1 + radius2 then return false + + if checkFuzzy(length, 0) and checkFuzzy(radius1, radius2) then return 'equal' + if checkFuzzy(circle1x, circle2x) and checkFuzzy(circle1y, circle2y) then return 'collinear' + + a = (radius1 * radius1 - radius2 * radius2 + length * length) / (2 * length) + h = math.sqrt(radius1 * radius1 - a * a) + + p2x = circle1x + a * (circle2x - circle1x) / length + p2y = circle1y + a * (circle2y - circle1y) / length + p3x = p2x + h * (circle2y - circle1y) / length + p3y = p2y - h * (circle2x - circle1x) / length + p4x = p2x - h * (circle2y - circle1y) / length + p4y = p2y + h * (circle2x - circle1x) / length + + if validateNumber(p3x) == false or validateNumber(p3y) == false or + validateNumber(p4x) == false or + validateNumber( p4y ) == false + return 'inside' + + if checkFuzzy(length, radius1 + radius2) or + checkFuzzy(length, math.abs(radius1 - radius2)) + return 'tangent', p3x, p3y + + return 'intersection', p3x, p3y, p4x, p4y + +isCircleCompletelyInsideCircle = (circle1x, circle1y, circle1radius, circle2x, circle2y, circle2radius) -> + if checkCirclePoint(circle1x, circle1y, circle2x, circle2y, circle2radius) == false then return false + Type = getCircleCircleIntersection(circle2x, circle2y, circle2radius, circle1x, circle1y, circle1radius) + if (Type ~= 'tangent' and Type ~= 'collinear' and Type ~= 'inside') then return false + return true { point: { @@ -957,6 +999,23 @@ getPercentage = (percent, n) -> getPercentage: getPercentage } + circle: { + getArea: getCircleArea + checkPoint: checkCirclePoint + isPointOnCircle: isPointOnCircle + getCircumference: getCircumference + getLineIntersection: getCircleLineIntersection + getSegmentIntersection: getCircleSegmentIntersection + getCircleIntersection: getCircleCircleIntersection + isCircleCompletelyInside: isCircleCompletelyInsideCircle + isPolygonCompletelyInside: isPolygonCompletelyInsideCircle + isSegmentCompletelyInside: isSegmentCompletelyInsideCircle + + getPolygonIntersection: getPolygonCircleIntersection + isCircleInsidePolygon: isCircleInsidePolygon + isCircleCompletelyInsidePolygon: isCircleCompletelyInsidePolygon + } + vec2D: -> assert require 'vec2D' vec2DArr: -> assert require 'vec2DArr' diff --git a/mm_spec.moon b/mm_spec.moon index 7e6a05d..c4a57fb 100644 --- a/mm_spec.moon +++ b/mm_spec.moon @@ -534,4 +534,50 @@ describe "math.getAngle", -> it " :: Gives roots given a, b, and c.", -> math = mm.math assert.fuzzyEqual math.getAngle(1, 3, 1, 1, 3, 1), 1.57079633 - assert.fuzzyEqual math.getAngle(4, 4, 1, 1, 4, 1), 0.785398163 \ No newline at end of file + assert.fuzzyEqual math.getAngle(4, 4, 1, 1, 4, 1), 0.785398163 + + +describe "circle.getArea", -> + it " :: Gives the area of the circle.", -> + circle = mm.circle + assert.fuzzyEqual circle.getArea(1), 3.14159 + assert.fuzzyEqual circle.getArea(2), 12.56637 + assert.fuzzyEqual circle.getArea(5), 78.53981 + assert.fuzzyEqual circle.getArea(10), 314.15926 + assert.fuzzyEqual circle.getArea(20), 1256.63706 + + +describe "circle.getCircumference", -> + it " :: Gives the circumference of the circle.", -> + circle = mm.circle + assert.fuzzyEqual circle.getCircumference(1), 6.28318 + assert.fuzzyEqual circle.getCircumference(2), 12.56637 + assert.fuzzyEqual circle.getCircumference(5), 31.41592 + assert.fuzzyEqual circle.getCircumference(10), 62.83185 + assert.fuzzyEqual circle.getCircumference(20), 125.66370 + +describe "circle.getCircleIntersection", -> + it " :: Returns \'Equal\' if the circles are the same.", -> + circle = mm.circle + assert.equal circle.getCircleIntersection( 0, 0, 4, 0, 0, 4 ), 'equal' + + it " :: Returns \'collinear\' if circles have same x and y but not radii.", -> + circle = mm.circle + assert.equal circle.getCircleIntersection( 0, 0, 4, 0, 0, 8 ), 'collinear' + assert.equal circle.getCircleIntersection( 0, 0, 8, 0, 0, 4 ), 'collinear' + + it " :: Returns \'inside\' if the circles are inside but not touching one another.", -> + circle = mm.circle + assert.equal circle.getCircleIntersection( 1, 1, 2, 2, 1, 4 ), 'inside' + + it " :: Returns false if the point is not within the cirlce.", -> + circle = mm.circle + assert.false circle.getCircleIntersection( 4, 4, 1, 6, 6, 1 ) + + +describe "circle.isCircleCompletelyInside", -> + it " :: Returns if a circle is completely inside of another circle.", -> + circle = mm.circle + assert.true circle.isCircleCompletelyInside( 1, 1, 2, 2, 1, 4 ) + assert.true circle.isCircleCompletelyInside( 1, 1, 3, 2, 1, 4 ) + assert.false circle.isCircleCompletelyInside( 8, 2, .1, 2, 1, 4 )