日経ソフトウェア2013年7月号のコードを若干アレンジ
3点を使って円を描画.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>3点を使って円を描画</title>
<style>canvas { background-color: #d0d0d0; }</style>
</head>
<body onload="draw()">
<canvas id="canvas" width="600" height="600"></canvas>
<script>
xx = new Array(3);
yy = new Array(3);
var cx, cy; // 円の中心
var n = 0; // クリック回数のカウンタ
function draw() {
var canvas = document.getElementById("canvas"); // 描画対象の canvas を選択
var context = canvas.getContext("2d"); // 描画コンテキストを取得
// マウスダウンイベント処理
canvas.onmousedown = function(e) {
// canvas 内でのマウス座標を計算
var rect = e.target.getBoundingClientRect();
var mouseX = e.clientX - rect.left;
var mouseY = e.clientY - rect.top;
context.beginPath();
context.strokeStyle = "rgb(128, 128, 128)";
xx[n] = mouseX;
yy[n] = mouseY;
context.rect(xx[n], yy[n], 2, 2); // 点を描画
if( n >= 2 ) {
drawLine(); // 3点を結ぶ直線を描画
calcCenter(); // 垂直二等分線の交点を計算
drawCircle(); // 3点を通る円を描画
n = 0;
} else {
n++;
}
context.stroke();
}
// 3点を結ぶ直線を描画
function drawLine() {
context.beginPath();
context.strokeStyle = "rgb(128, 128, 128)";
context.moveTo(xx[0], yy[0]);
context.lineTo(xx[1], yy[1]);
context.lineTo(xx[2], yy[2]);
context.closePath();
context.stroke();
}
// 垂直二等分線の交点を求める
function calcCenter() {
// 2点間の垂直2等分線を求める
f = function (x1, y1, x2, y2) {
// 直線の係数を求める
var a = (y2 - y1) / (x2 - x1);
var b = y1 - (a * x1);
// 直線の中点を求める
var mx = x1 + ((x2 - x1) / 2);
var my = y1 + ((y2 - y1) / 2);
// 直線の垂直二等分線の係数を求める
var aa = -1 / a;
var bb = my - (aa * mx);
return [mx, my, aa, bb];
}
ret = f(xx[0], yy[0], xx[1], yy[1]);
m1 = [ret[0], ret[1]]; // 中点座標
ab = [ret[2], ret[3]]; // 垂直二等分線の係数
ret = f(xx[1], yy[1], xx[2], yy[2]);
m2 = [ret[0], ret[1]];
cd = [ret[2], ret[3]];
// 二つの垂直二等分線の交点を求める
// 解法)x = (-1/(-a+c) * -b) + (1/(-a+c) * -d)
// y = (-c/(-a+c) * -b) + (a/(-a+c) * -d)
var z = 1 / (-ab[0] + cd[0]); // z = 1/(-a+c)
cx = z * (-1 * -ab[1] + 1 * -cd[1]); // x = z * (-1 * -b + 1 * -d)
cy = z * (-cd[0] * -ab[1] + ab[0] * -cd[1]); // y = z * (-c * -b + a * -d)
// 垂直二等分線を描画
context.strokeStyle = "rgb(0, 255, 0)"
context.beginPath();
context.moveTo(cx, cy);
context.lineTo(m1[0], m1[1]);
context.stroke();
//
context.beginPath();
context.moveTo(cx, cy);
context.lineTo(m2[0], m2[1]);
context.stroke();
}
// 3点を通る円を描画
function drawCircle() {
// 円の半径を求める
var r = Math.sqrt(Math.pow(cx - xx[0], 2) + Math.pow(cy - yy[0], 2));
// 円を描画
context.beginPath();
context.strokeStyle = "rgb(255, 0, 0)";
context.arc(cx, cy, r, 0, 2 * Math.PI, true);
context.stroke();
}
}
</script>
</html>