Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

352 lines (303 sloc) 11.102 kB
<!DOCTYPE html>
<html data-require="math math-format graphie time interactive angles word-problems">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Telling time 2</title>
<script src="../khan-exercise.js"></script>
</head>
<body>
<div class="exercise">
<div class="problems">
<div id="set-hands" data-weight="3">
<div class="vars">
<div data-ensure="!( HOUR === 1 && MINUTE === 0 )">
<var id="HOUR">randRange( 1, 12 )</var>
<var id="MINUTE_INCREMENT">15</var>
<var id="MINUTE">randRange( 0, (60 / MINUTE_INCREMENT) - 1 ) * MINUTE_INCREMENT</var>
</div>
<var id="MINUTE_IS_ZERO">MINUTE === 0</var>
<var id="NICE_MINUTE"> MINUTE &gt; 5 ? MINUTE : "0" + MINUTE</var>
<var id="TIME">HOUR + ":" + NICE_MINUTE</var>
</div>
<p class="question">Set the clock to <var>TIME</var>. The <span class="hint_blue" style="font-weight: bold">hour</span> hand is <span class="hint_blue" style="font-weight: bold">blue</span> and the <span class="hint_orange" style="font-weight: bold">minute</span> hand is <span class="hint_orange" style="font-weight: bold">orange</span>.</p>
<div class="problem">
<div class="graphie" id="clock">
init({ range: [ [-4, 4 ], [ -4, 4 ] ], scale: 45 });
var clockRadius = 3.75;
var minuteSnapPoints = 12;
var hourSnapPoints = 12 * 60 / MINUTE_INCREMENT;
var outerPointRadius = clockRadius * 1.01;
var minuteRadius = clockRadius * 0.6;
var hourRadius = clockRadius * 0.45;
minuteStartAngle = 90;
hourStartAngle = 60;
minuteSnapDegrees = 360 / minuteSnapPoints;
hourSnapDegrees = 360 / hourSnapPoints;
var clock = addAnalogClock( { radius: clockRadius, minuteTicks: hourSnapPoints } );
clock.draw();
addMouseLayer();
function movePartnerPoint( options ) {
var x = options.x;
var y = options.y;
var point = options.point;
var outerPoint = options.outerPoint;
var isOuterPoint = options.isOuterPoint;
var ratio = outerPoint.constraints.fixedDistance.dist / point.constraints.fixedDistance.dist;
if (isOuterPoint) {
ratio = 1 / ratio;
point.setCoord( [ x * ratio , y * ratio ] );
outerPoint.setCoord( [ x, y ] );
} else {
point.setCoord( [ x, y ] );
outerPoint.setCoord( [ x * ratio, y * ratio ] );
}
point.updateLineEnds();
return true;
}
minutePoint = addMovablePoint({
coord: polar( minuteRadius, minuteStartAngle ),
constraints: {
fixedDistance: {
dist: minuteRadius,
point: [ 0, 0 ],
snapPoints: 12
}
},
onMove: function( x, y ) {
return movePartnerPoint( { x: x, y: y, point: this, outerPoint: outerMinutePoint, isOuterPoint: false } );
},
normalStyle: {
fill: ORANGE,
stroke: ORANGE
},
highlightStyle: {
fill: ORANGE,
stroke: ORANGE
}
});
outerMinutePoint = addMovablePoint({
coord: polar( outerPointRadius, minuteStartAngle ),
constraints: {
fixedDistance: {
dist: outerPointRadius,
point: [ 0, 0 ],
snapPoints: 12
}
},
onMove: function( x, y ) {
return movePartnerPoint( { x: x, y: y, point: minutePoint, outerPoint: this, isOuterPoint: true } );
},
normalStyle: {
fill: ORANGE,
stroke: ORANGE
},
highlightStyle: {
fill: ORANGE,
stroke: ORANGE
}
});
hourPoint = addMovablePoint({
coord: polar( hourRadius, hourStartAngle ),
constraints: {
fixedDistance: {
dist: hourRadius,
point: [ 0, 0 ],
snapPoints: hourSnapPoints
}
},
onMove: function( x, y ) {
return movePartnerPoint( { x: x, y: y, point: this, outerPoint: outerHourPoint, isOuterPoint: false } );
},
normalStyle: {
fill: BLUE,
stroke: BLUE
},
highlightStyle: {
fill: BLUE,
stroke: BLUE
}
});
outerHourPoint = addMovablePoint({
coord: polar( outerPointRadius, hourStartAngle ),
constraints: {
fixedDistance: {
dist: outerPointRadius,
point: [ 0, 0 ],
snapPoints: hourSnapPoints
}
},
onMove: function( x, y ) {
return movePartnerPoint( { x: x, y: y, point: hourPoint, outerPoint: this, isOuterPoint: true } );
},
normalStyle: {
fill: BLUE,
stroke: BLUE
},
highlightStyle: {
fill: BLUE,
stroke: BLUE
}
});
minuteHand = addMovableLineSegment({
pointA: minutePoint,
coordZ: [ 0, 0 ],
fixed: true,
normalStyle: {
stroke: ORANGE,
"stroke-width": 10
}
});
hourHand = addMovableLineSegment({
pointA: hourPoint,
coordZ: [ 0, 0 ],
fixed: true,
normalStyle: {
stroke: BLUE,
"stroke-width": 10
}
});
centerPoint = addMovablePoint({
coord: [ 0, 0 ],
constraints: {
fixed: true
},
normalStyle: {
fill: "#fff",
stroke: "#000",
"stroke-width": 2
}
});
correctMinuteAngle = timeToDegrees( MINUTE );
correctHourAngle = timeToDegrees( 5 * (HOUR + MINUTE/60) );
correctMinuteAngle = roundToNearest( minuteSnapDegrees, correctMinuteAngle );
correctHourAngle = roundToNearest( hourSnapDegrees, correctHourAngle );
</div>
</div>
<div class="solution" data-type="custom">
<div class="instruction">
Drag the two hands so the clock reads <var>HOUR</var>:<var>NICE_MINUTE</var>.
</div>
<div class="guess">
[ minutePoint.coord, hourPoint.coord ]
</div>
<div class="validator-function">
var minuteAngle = cartToPolar( guess[0] )[1];
var hourAngle = cartToPolar( guess[1] )[1];
minuteAngle = roundToNearest( minuteSnapDegrees, minuteAngle );
hourAngle = roundToNearest( hourSnapDegrees, hourAngle );
// if hands have not been moved, return `""`
if ( minuteAngle === minuteStartAngle &amp;&amp; hourAngle === hourStartAngle) {
return "";
}
return (minuteAngle === correctMinuteAngle) &amp;&amp; (hourAngle === correctHourAngle);
</div>
<div class="show-guess">
minutePoint.moveTo( guess[0][0], guess[0][1], true );
hourPoint.moveTo( guess[1][0], guess[1][1], true );
</div>
</div>
<div class="hints">
<p>The number after the <code>\Large{:}</code> symbol represents the number of minutes past the hour. So <code><var>TIME</var></code> represents <code><var>MINUTE</var></code> minutes past hour <code><var>HOUR</var></code>.</p>
<p>First, let's set the <span class="hint_orange" style="font-weight: bold">minute</span> hand.</p>
<div>
<p>Each long tick mark is an increment of 5 minutes, because 60 minutes / 12 tick marks = 5 minutes per tick mark.</p>
<p>Since we are <code><var>MINUTE</var></code> minutes past the hour, <span data-if="MINUTE_IS_ZERO">the minute hand should be at the mark numbered <code class="hint_orange">12</code>, which is the first tick mark on the clock and represents <code>0</code> minutes past the hour</span><span data-else>and there are 5 minutes per tick mark, the minute hand should be at the mark numbered <code class="hint_orange"><var>fraction(MINUTE, 5)</var> = <var>MINUTE/5</var></code></span>.</p>
</div>
<p>Next, let's set the <span class="hint_blue" style="font-weight: bold">hour</span> hand.</p>
<div>
<p>The 12 long tick marks correspond to the hours in the day (assuming AM/PM time).</p>
<p>If it is <code>0</code> minutes, the hour hand belongs directly on the corresponding hour mark. However, for any other number of minutes, the hour hand should be proportionally past the hour mark.</p>
</div>
<div>
<p data-if="MINUTE_IS_ZERO">
Since it's <code><var>HOUR</var></code> hour<code><var>plural(HOUR)</var></code> and <code>0</code> minutes, the hour hand should be right on the <code class="hint_blue"><var>HOUR</var></code> hour mark.
</p>
<p data-else>
Since it's <code><var>HOUR</var></code> hour<var>plural(HOUR)</var> and <code><var>MINUTE</var></code> minutes, the hour hand should be <code class="hint_blue"><var>fraction(MINUTE, 60)</var> = <var>fraction(MINUTE, 60, false, true)</var></code> of the way past the <code class="hint_blue"><var>HOUR</var></code> hour mark.
</p>
</div>
<div class="graphie" data-update="clock">
var minuteRadius = minutePoint.constraints.fixedDistance.dist;
var hourRadius = hourPoint.constraints.fixedDistance.dist;
var minuteCoord = polar( minuteRadius, correctMinuteAngle );
var hourCoord = polar( hourRadius, correctHourAngle );
var dotOpacity = 0.4;
var handOpacity = 0.3;
addMovableLineSegment({
coordA: minuteCoord,
coordZ: [ 0, 0 ],
fixed: true,
normalStyle: {
stroke: ORANGE,
"stroke-width": 10,
"stroke-dasharray": ".",
"stroke-linecap": "round",
"stroke-opacity": dotOpacity
},
});
addMovableLineSegment({
coordA: minuteCoord,
coordZ: [ 0, 0 ],
fixed: true,
normalStyle: {
stroke: ORANGE,
"stroke-width": 10,
"stroke-linecap": "round",
"stroke-opacity": handOpacity
},
});
addMovableLineSegment({
coordA: hourCoord,
coordZ: [ 0, 0 ],
fixed: true,
normalStyle: {
stroke: BLUE,
"stroke-width": 10,
"stroke-dasharray": ".",
"stroke-linecap": "round",
"stroke-opacity": dotOpacity
},
});
addMovableLineSegment({
coordA: hourCoord,
coordZ: [ 0, 0 ],
fixed: true,
normalStyle: {
stroke: BLUE,
"stroke-width": 10,
"stroke-linecap": "round",
"stroke-opacity": handOpacity
},
});
// for some reason this doesn't work, so for now, create another center point
// centerPoint.toFront();
addMovablePoint({
coord: [ 0, 0 ],
constraints: {
fixed: true
},
normalStyle: {
fill: "#fff",
stroke: "#000",
"stroke-dasharray": "",
"stroke-width": 2,
"stroke-opacity": 1
}
});
</div>
</div>
</div>
<div id="set-hands-20-minutes" data-type="set-hands" data-weight="2">
<div class="vars">
<var id="MINUTE_INCREMENT">20</var>
</div>
</div>
<div id="set-hands-30-minutes" data-type="set-hands" data-weight="2">
<div class="vars">
<var id="MINUTE_INCREMENT">30</var>
</div>
</div>
</div>
</div>
</body>
</html>
Jump to Line
Something went wrong with that request. Please try again.