# Khan/khan-exercises

Add exercises: Graphing circles 1 & 2

Test Plan: Tested multiple problem seeds outside devappserver

Reviewers: stephanie, yunfangjuan

Reviewed By: yunfangjuan

Differential Revision: http://phabricator.khanacademy.org/D777
1 parent a5882e3 commit d1f63a4759e703fd39ffda7bd75f113c9abd3ed2 beneater committed Oct 2, 2012
Showing with 461 additions and 1 deletion.
1. +110 −0 exercises/graphing_circles.html
2. +183 −0 exercises/graphing_circles_2.html
3. +168 −1 utils/interactive.js
110 exercises/graphing_circles.html
 @@ -0,0 +1,110 @@ + + + + + Graphing circles + + + + +
+
+
+
+ randRange(-5, 5) + randRange(-5, 5) + randRange(1, 5) + H === 0 ? "x^2" : + expr(["^", ["+", "x", -H], 2]) + + K === 0 ? "y^2" : + expr(["^", ["+", "y", -K], 2]) + +
+ +

+ Graph the circle expr(["+", X2T, Y2T]) + = R * R. +

+ +
+
+
+ graphInit({ + range: 11, + scale: 20, + axisArrows: "<->", + tickStep: 1, + labelStep: 1, + gridOpacity: 0.05, + axisOpacity: 0.2, + tickOpacity: 0.4, + labelOpacity: 0.5 + }); + + label( [ 0, 11 ], "y", "above" ); + label( [ 11, 0 ], "x", "right" ); + + addMouseLayer(); + graph.circle = addCircleGraph(); +
+
+ +
+
+ Drag the center point and perimeter of the circle + to graph the equation. +
+
[ + graph.circle.center[0], + graph.circle.center[1], + graph.circle.radius] +
+
+ if (_.isEqual(guess, [0, 0, 2])) { + return ""; + } + return _.isEqual(guess, [H, K, R]); +
+
+ graph.circle.setCenter(guess[0], guess[1]); + graph.circle.setRadius(guess[2]); +
+
+ +
+

+ The equation of a circle with center + (\blue{h}, \green{k}) and radius + \pink{r} is + (x - \blue{h})^2 + (y - \green{k})^2 = + \pink{r}^2. +

+

+ We can rewrite the given equation as + (x - \blue{negParens(H)})^2 + (y - + \green{negParens(K)})^2 = + \pink{R}^2. +

+
+

+ Thus, the center of the circle should be + (\blue{H}, \green{K}) + and the radius should be + \pink{R}. +

+
+ circle([H, K], R, { + stroke: PURPLE, + strokeWidth: 1, + strokeDasharray: "- " + }).toBack(); +
+
+
+
+
+
+ +
183 exercises/graphing_circles_2.html
 @@ -0,0 +1,183 @@ + + + + + Graphing circles 2 + + + + +
+
+
+
+ randRange(-5, 5) + randRange(-5, 5) + randRange(1, 5) + H === 0 ? "x^2" : + expr(["^", ["+", "x", -H], 2]) + + K === 0 ? "y^2" : + expr(["^", ["+", "y", -K], 2]) + + -2 * H + -2 * K + H * H + K * K - R * R +
+ +

+ Graph the circle expr(["+", "x^2", "y^2", + D === 0 ? null : ["*", D, "x"], + E === 0 ? null : ["*", E, "y"], + F === 0 ? null : F]) + = 0. +

+ +
+
+
+ graphInit({ + range: 11, + scale: 20, + axisArrows: "<->", + tickStep: 1, + labelStep: 1, + gridOpacity: 0.05, + axisOpacity: 0.2, + tickOpacity: 0.4, + labelOpacity: 0.5 + }); + + label( [ 0, 11 ], "y", "above" ); + label( [ 11, 0 ], "x", "right" ); + + addMouseLayer(); + graph.circle = addCircleGraph(); +
+
+ +
+
+ Drag the center point and perimeter of the circle + to graph the equation. +
+
[ + graph.circle.center[0], + graph.circle.center[1], + graph.circle.radius] +
+
+ if (_.isEqual(guess, [0, 0, 2])) { + return ""; + } + return _.isEqual(guess, [H, K, R]); +
+
+ graph.circle.setCenter(guess[0], guess[1]); + graph.circle.setRadius(guess[2]); +
+
+ +
+

+ First, convert the equation to standard form by + completing the square. +

+
+

+ Group the \blue{x} and + \green{y} terms on the left side and + move the constant term to the right side. +

+

\qquad + \blue{ + (expr(["+", "x^2", ["*", D, "x"]])) + + (x^2) + } + + \green{ + (expr(["+", "y^2", ["*", E, "y"]])) + + (y^2) + } + \quad = \quad -F +

+
+
+

+ Add + + \blue{H * H} to both + sides to complete the square for the + \blue{x} term and + \green{K * K} to both + sides to complete the square for the + \green{y} term. +

+

\qquad + \blue{ + ( + expr(["+", "x^2", ["*", D, "x"], H * H]) + ) + + (x^2) + } + + \green{ + ( + expr(["+", "y^2", ["*", E, "y"], K * K]) + ) + + (y^2) + } \quad = \quad -F + + + \blue{H * H} + + + + \green{K * K} + +

+
+
+

Simplify and write each term as a square:

+

+

+
+

+ The equation of a circle with center + (\blue{h}, \green{k}) and radius + \pink{r} is + (x - \blue{h})^2 + (y - \green{k})^2 = + \pink{r}^2. +

+
+

+ Thus, the center of the circle should be + (\blue{H}, \green{K}) + and the radius should be + \pink{R}. +

+
+ circle([H, K], R, { + stroke: PURPLE, + strokeWidth: 1, + strokeDasharray: "- " + }).toBack(); +
+
+
+
+
+
+ +
169 utils/interactive.js
 @@ -1120,8 +1120,175 @@ $.extend(KhanUtil, { return sorter; - } + }, + + // center: movable point + // radius: int + // circ: graphie circle + // perim: invisible mouse target for dragging/changing radius + addCircleGraph: function(options) { + var graphie = KhanUtil.currentGraph; + var circle =$.extend({ + center: [0, 0], + radius: 2 + }, options); + + circle.centerPoint = KhanUtil.addMovablePoint({ + graph: graphie, + coord: circle.center, + normalStyle: { + stroke: KhanUtil.BLUE, + fill: KhanUtil.BLUE + }, + snapX: 0.5, + snapY: 0.5 + }); + circle.circ = graphie.circle(circle.center, circle.radius, { + stroke: KhanUtil.BLUE, + fill: KhanUtil.ORANGE, + fillOpacity: 0 + }); + circle.perim = graphie.mouselayer.circle( + graphie.scalePoint(circle.center)[0], + graphie.scalePoint(circle.center)[1], + graphie.scaleVector(circle.radius)[0]).attr({ + "stroke-width": 20, + "opacity": 0.0 + }); + + $(circle.centerPoint.mouseTarget[0]).on( + "vmouseover vmouseout", function(event) { + if (circle.centerPoint.highlight) { + circle.circ.animate({ + stroke: KhanUtil.ORANGE, + "fill-opacity": 0.05 + }, 50); + } else { + circle.circ.animate({ + stroke: KhanUtil.BLUE, + "fill-opacity": 0 + }, 50); + } + }); + + circle.toFront = function() { + circle.circ.toFront(); + circle.perim.toFront(); + circle.centerPoint.visibleShape.toFront(); + circle.centerPoint.mouseTarget.toFront(); + }; + + circle.centerPoint.onMove = function(x, y) { + circle.toFront(); + circle.circ.attr({ + cx: graphie.scalePoint(x)[0], + cy: graphie.scalePoint(y)[1], + }); + circle.perim.attr({ + cx: graphie.scalePoint(x)[0], + cy: graphie.scalePoint(y)[1], + }); + }; + + circle.centerPoint.onMoveEnd = function(x, y) { + circle.center = [x, y]; + }; + + // circle.setCenter(x, y) moves the circle to the specified + // x, y coordinate as if the user had dragged it there. + circle.setCenter = function(x, y) { + circle.centerPoint.setCoord([x, y]); + circle.centerPoint.onMove(x, y); + circle.center = [x, y]; + }; + + // circle.setRadius(r) sets the circle's radius to the specified + // value as if the user had dragged it there. + circle.setRadius = function(r) { + circle.radius = r; + circle.perim.attr({ + r: graphie.scaleVector(r)[0], + }); + circle.circ.attr({ + rx: graphie.scaleVector(r)[0], + ry: graphie.scaleVector(r)[1] + }); + }; + +$(circle.perim[0]).css("cursor", "move"); + $(circle.perim[0]).on( + "vmouseover vmouseout vmousedown", function(event) { + if (event.type === "vmouseover") { + circle.highlight = true; + if (!KhanUtil.dragging) { + circle.circ.animate({ + stroke: KhanUtil.ORANGE, + "fill-opacity": 0.05 + }, 50); + circle.centerPoint.visibleShape.animate({ + stroke: KhanUtil.ORANGE, + fill: KhanUtil.ORANGE + }, 50); + } + + } else if (event.type === "vmouseout") { + circle.highlight = false; + if (!circle.dragging) { + circle.circ.animate({ + stroke: KhanUtil.BLUE, + "fill-opacity": 0 + }, 50); + circle.centerPoint.visibleShape.animate({ + stroke: KhanUtil.BLUE, + fill: KhanUtil.BLUE + }, 50); + } + + } else if (event.type === "vmousedown" && + (event.which === 1 || event.which === 0)) { + event.preventDefault(); + circle.toFront(); + +$(document).on("vmousemove vmouseup", function(event) { + event.preventDefault(); + circle.dragging = true; + KhanUtil.dragging = true; + + if (event.type === "vmousemove") { + // mouse{X|Y} are in pixels relative to the SVG + var mouseX = event.pageX - $(graphie.raphael. + canvas.parentNode).offset().left; + var mouseY = event.pageY -$(graphie.raphael. + canvas.parentNode).offset().top; + // can't go beyond 10 pixels from the edge + mouseX = Math.max(10, Math.min(graphie.xpixels - 10, + mouseX)); + mouseY = Math.max(10, Math.min(graphie.ypixels - 10, + mouseY)); + + // coord{X|Y} are the scaled coordinate values + var coordX = mouseX / graphie.scale[0] + + graphie.range[0][0]; + var coordY = graphie.range[1][1] - mouseY / + graphie.scale[1]; + + var radius = KhanUtil.getDistance( + circle.centerPoint.coord, [coordX, coordY]); + radius = Math.max(1, + Math.round(radius / 0.5) * 0.5); + circle.setRadius(radius); + } else if (event.type === "vmouseup") { + \$(document).off("vmousemove vmouseup"); + circle.dragging = false; + KhanUtil.dragging = false; + } + }); + } + }); + + return circle; + } });