reduce( randRangeNonZero( -5, 5 ), randRange( 1, 5 ) ) randRangeNonZero( max( -10, -10 - SLOPE_FRAC[0] ), min( 10, 10 - SLOPE_FRAC[0] ) ) SLOPE_FRAC[0] / SLOPE_FRAC[1] SLOPE === 1 ? "" : ( SLOPE === -1 ? "-" : fraction( SLOPE_FRAC[0], SLOPE_FRAC[1], true, true ) ) randRangeNonZero( -3, 3 ) SLOPE_FRAC[0] * -MULT SLOPE_FRAC[1] * MULT SLOPE_FRAC[1] * YINT * MULT random() < 0.2

Graph the following equation:

expr([ "+", [ "*", A, "x" ], [ "*", B, "y" ] ]) = C

y = PRETTY_SLOPE x + YINT

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.pointA = addMovablePoint({ coord: [ -5, 5 ], snapX: 0.5, snapY: 0.5, normalStyle: { stroke: KhanUtil.BLUE, fill: KhanUtil.BLUE } }); graph.pointB = addMovablePoint({ coord: [ 5, 5 ], snapX: 0.5, snapY: 0.5, normalStyle: { stroke: KhanUtil.BLUE, fill: KhanUtil.BLUE } }); graph.line1 = addMovableLineSegment({ pointA: graph.pointA, pointZ: graph.pointB, fixed: true, extendLine: true }); // A and B can't be in the same place graph.pointA.onMove = function( x, y ) { return ( x != graph.pointB.coord[0] || y != graph.pointB.coord[1] ); } graph.pointB.onMove = function( x, y ) { return ( x != graph.pointA.coord[0] || y != graph.pointA.coord[1] ); } graph.pointA.toFront(); graph.pointB.toFront();
Drag the two points to move the line into the correct position.
[ graph.pointA.coord, graph.pointB.coord ]
var slope = ( guess[1][1] - guess[0][1] ) / ( guess[1][0] - guess[0][0] ); var yint = slope * ( 0 - guess[0][0] ) + guess[0][1]; return abs( SLOPE - slope ) < 0.001 && abs( YINT - yint ) < 0.001;
graph.pointA.setCoord( guess[0] ); graph.pointB.setCoord( guess[1] ); graph.line1.transform( true );

Convert expr([ "+", [ "*", A, "x" ], [ "*", B, "y" ] ]) = C to slope-intercept form by solving for y.

A < 0 ? "Add" : "Subtract" abs( A )x A < 0 ? "to" : "from" both sides:

\qquad expr( [ "*", B, "y" ] ) = expr([ "+", [ "*", -A, "x" ], C ])

Divide both sides by B:

\qquad y = expr([ "+", "\\dfrac{" + expr([ "*", -A, "x" ]) + "}{" + B + "}", "\\dfrac{" + C + "}{" + B + "}" ])

\qquad y = \color{purple}{PRETTY_SLOPE} x \color{GREEN}{+ YINT}

The y-intercept is YINT and the slope is decimalFraction( SLOPE, true, true ).

The y-intercept is YINT, so the line must pass through the point (0, YINT).

style({ stroke: GREEN, fill: GREEN }, function() { graph.yint = circle( [ 0, YINT ], 0.2 ).toBack(); });

The slope is decimalFraction( SLOPE, true, true ). Remember that the slope tells you rise over run. So in this case for every abs( SLOPE_FRAC[0] ) "position" + ( abs( SLOPE_FRAC[0] ) !== 1 ? "s" : "" ) you move down (because it's negative) up you must also move SLOPE_FRAC[1] "position" + ( abs( SLOPE_FRAC[1] ) !== 1 ? "s" : "" ) to the right.

style({ stroke: "purple", strokeWidth: 2, arrows: "->" }, function() { path([ [ 0, YINT ], [ 0, YINT + SLOPE_FRAC[0] ] ]).toBack(); path([ [ 0, YINT + SLOPE_FRAC[0] ], [ SLOPE_FRAC[1], YINT + SLOPE_FRAC[0] ] ]).toBack(); }); label( [ 0, YINT + SLOPE_FRAC[0] / 2 ], abs( SLOPE_FRAC[0] ) + " \\text{ " + ( SLOPE_FRAC[0] < 0 ? "down" : "up" ) + "} \\quad", "left", { color: "purple" } ); label( [ 0, YINT + SLOPE_FRAC[0] ], SLOPE_FRAC[1] + " \\text{ right}", ( SLOPE_FRAC[0] < 0 ? "below right" : "above right" ), { color: "purple" } ); graph.yint.toBack();

So the line must also pass through (SLOPE_FRAC[1], YINT + SLOPE_FRAC[0])

style({ stroke: BLUE, strokeWidth: 2, strokeDasharray: "." }, function() { plot( function( x ) { return x * SLOPE + YINT; }, [ -11, 11 ] ).toBack(); });