Construct a line going through P
, tangent to the circle.
init({
range: [[-5, 5], [-5, 5]],
scale: 50
});
addMouseLayer();
addConstruction("construction");
addDummyCircle(C, SIZE);
addDummyPoint(C);
addDummyPoint(P);
label(P, "P", POSITION);
label(C, "C", POSITION2);
getToolProperties(construction)
if (guess.length === 0) {
return "";
}
// Find tangent line
var tangent = _.filter(guess, function(tool) {
if (tool.first != null) {
if (isPointOnLineSegment([tool.first.coord, tool.second.coord], P, 0.2)) {
return angleEqual(tool, TANGENT_ANGLES[0], 4) || angleEqual(tool, TANGENT_ANGLES[1], 5);
}
}
});
if (tangent.length < 1) {
return false;
}
// Get lines going through X
var lines = _.filter(guess, function(tool) {
if (tool.first != null) {
return isPointOnLineSegment([tool.first.coord, tool.second.coord], X, 0.2);
}
});
if (lines.length < 2) {
return "Make sure you keep the straightedges you used in place.";
}
// Check there is a line going through P and C
var connectingLine = _.filter(lines, function(tool) {
return isPointOnLineSegment([tool.first.coord, tool.second.coord], P, 0.2) &&
isPointOnLineSegment([tool.first.coord, tool.second.coord], C, 0.2);
});
// Check there is a perpendicular bisector of the line PC
var bisectingLine = _.filter(lines, function(tool) {
return angleEqual(tool, (ANGLE + 90) % 180, 5);
});
if (connectingLine.length * bisectingLine.length === 0) {
return "Make sure you keep the straightedges you used in place.";;
}
// Test whether there is a compass centered on X with the correct radius
var compass = findCompass(guess, {center: X, radius: D / 2});
if (compass.length === 0) {
return "Make sure you keep the compasses you used in place.";
} else {
return true;
}
showConstructionGuess(guess);
var angle = TANGENT_ANGLES[0] * Math.PI / 180;
graph.dx = 10 * cos(angle);
graph.dy = 10 * sin(angle);
graph.hintLines = raphael.set();
graph.hintLines.push(line([P[0] - graph.dx, P[1] - graph.dy], [P[0] + graph.dx, P[1] + graph.dy],{
strokeWidth: 1,
stroke: BLUE
})).toBack();
We could just draw a line through P
and try to get it right,
but then we have no guarantee that it's actually perfectly tangent.
How can you guarantee that a line is really tangent?
var angle1 = RAD - asin(SIZE / D);
var angle2 = RAD + asin(SIZE / D);
var d = Math.sqrt(D * D - SIZE * SIZE)
graph.tangent1 = [P[0] + d * cos(angle1), P[1] + d * sin(angle1)];
graph.tangent2 = [P[0] + d * cos(angle2), P[1] + d * sin(angle2)];
graph.hintLines.push(drawHintLine(C, P)).toBack();
style({
strokeWidth: 1,
stroke: BLUE
}, function() {
graph.hintLines.push(line(C, graph.tangent1));
graph.hintLines.push(line(C, graph.tangent2));
graph.hintLines.push(line(P, graph.tangent2));
});
graph.hintLines.push(circle(X, D / 2, {
stroke: BLUE,
strokeWidth: 1,
fill: "none",
strokeDasharray: "- "
}));
graph.hintLines.push(circle(X, 0.08, {
fill: BLUE,
stroke: null
}));
If we can draw a quadrilateral inscribed in a circle, its opposite angles must sum to 180^\circ
.
If the two angles are equal, then both must be 90^\circ
.
Therefore we need to find a circle for which P
and C
are on opposite sides.
graph.hintLines.remove();
line(C, P, {
strokeWidth: 2,
stroke: GRAY
}).toBack();
First draw a line connecting the center of the circle, C
, to P
.
graph.d = D * 0.65;
circle(C, graph.d, {
fill: "none",
strokeDasharray: "- ",
strokeWidth: 1,
stroke: GRAY
});
circle(P, graph.d, {
fill: "none",
strokeDasharray: "- ",
strokeWidth: 1,
stroke: GRAY
});
Now we want to bisect the line CP
.
So create two compasses with the same radius, one centered at C
and one centered at P
.
var dAngle = acos(D / graph.d / 2);
var p1 = [C[0] - graph.d * cos(RAD - dAngle), C[1] - graph.d * sin(RAD - dAngle)];
var p2 = [C[0] - graph.d * cos(RAD + dAngle), C[1] - graph.d * sin(RAD + dAngle)];
line(p1, p2, {
strokeWidth: 2,
stroke: GRAY
});
circle(p1, 0.08, {
fill: GRAY,
stroke: null
});
circle(p2, 0.08, {
fill: GRAY,
stroke: null
});
Join the points where these two compasses intersect to the bisect line CP
.
circle(X, 0.08, {
fill: GRAY,
stroke: null
});
circle(X, D / 2, {
fill: "none",
strokeDasharray: "- ",
strokeWidth: 1,
stroke: GRAY
});
Now we can draw a circle halfway between C
and P
with a radius that goes through both.
circle(graph.tangent1, 0.08, {
fill: GRAY,
stroke: null
});
circle(graph.tangent2, 0.08, {
fill: GRAY,
stroke: null
});
if (graph.tangent1[1] > C[1]) {
label(graph.tangent1, "A", "above");
} else {
label(graph.tangent1, "A", "below");
}
if (graph.tangent2[1] > C[1]) {
label(graph.tangent2, "B", "above");
} else {
label(graph.tangent2, "B", "below");
}
path([C, graph.tangent1, P, graph.tangent2, C], {
fill: GREEN,
'fill-opacity': 0.4,
stroke: GREEN,
strokeWidth: 2
}).toBack();
var drawRightAngleMarker = function(p, flip) {
var x = p[0];
var y = p[1];
var dx = x - P[0];
var dy = y - P[1];
var norm = sqrt(dx * dx + dy * dy);
dx /= norm * 5;
dy /= norm * 5;
//circle([x - dx, y - dy], 0.1);
path([[x, y], [x - dx, y - dy], [x - dx - dy * flip, y + dx * flip - dy], [x - dy * flip, y + dx * flip]], {
fill: null,
stroke: BLACK,
strokeWidth: 1
})
}
drawRightAngleMarker(graph.tangent1, 1);
drawRightAngleMarker(graph.tangent2, -1);
This circle intersects the original circle at points A
and B
.
\green{PACB}
forms a quadrilateral inscribed inside this circle so its opposite angles sum to 180^\circ
.
\triangle PAC
and \triangle PBC
are congruent triangles,
so \angle PAC = \angle PBC
. Therefore both angles are 90^\circ
.
var angle = TANGENT_ANGLES[1] * Math.PI / 180;
var dx = 10 * cos(angle);
var dy = 10 * sin(angle);
graph.hintLines.push(line([P[0] - graph.dx, P[1] - graph.dy], [P[0] + graph.dx, P[1] + graph.dy],{
strokeWidth: 2,
stroke: GRAY
}))
graph.hintLines.push(line([P[0] - dx, P[1] - dy], [P[0] + dx, P[1] + dy],{
strokeWidth: 2,
stroke: GRAY
}))
Therefore a line from P
to either A
or B
will be tangent to the original circle.