3개의 점을 알고 있을 때 해당 점을 지나는 원호를 그리고 싶다.

우리는 A,B,C 3개의 점 위치를 알고 있다

A에서 시작하여 B를 통과하여 C로 끝나는 호를 어떻게 그릴 수 있을까. 중심좌표와 반지름 r을 어떻게 구할 수 있을까?

 

## 풀이 아이디어

A와 B 사이의 직각선을 구할 수 있고,

B와 C 사이의 직각선을 구할 수 있다.

이 2개의 선이 교차하는 부분이 원의 중심이다.

자세한 설명은 아래와 같다.

 

 

이에 대한 자바스크립트 소스는 아래와 같다.

  •  
<!DOCTYPE html>
<head>
	<meta charset="utf-8">
	<style>canvas { border:2px solid magenta; }</style>
</head>
<body>
	<canvas id="canvas" width="400" height="400"></canvas>
	<script>
window.onload = function() {

  var canvas = document.getElementById("canvas");
  var ctx = canvas.getContext("2d");

  // 3점의좌표
  let p1 = {x:0, y:200}
  let p2 = {x:300, y:320}
  let p3 = {x:400, y:200}
  
  // 두 수직 이등분선의 기울기
  let d1 = (p2.x - p1.x) / (p2.y - p1.y)
  let d2 = (p3.x - p2.x) / (p3.y - p2.y)

  // 원의중심
  let c = {x:0, y:0}
  c.x = ((p3.y - p1.y) + (p2.x + p3.x) * d2 - (p1.x + p2.x) * d1) / (2 * (d2 - d1))
  c.y = -d1 * (c.x - (p1.x + p2.x) / 2) + (p1.y + p2.y) / 2

  // 원의 반지름
  // let r = sqrt(( p1.x - c.x) ^ 2 + ( p1.y - c.y) ^ 2);
  let radius = Math.sqrt( Math.pow(( p1.x - c.x) , 2) + Math.pow(( p1.y - c.y) , 2));
  console.log(c, radius)
 
  // p1~p3 각도 구하기
  let startAngle = Math.atan2(p1.y - c.y, p1.x - c.x)
  let endAngle   = Math.atan2(p3.y - c.y, p3.x - c.x)
  if(startAngle > endAngle){
    let tmp = endAngle
    endAngle = startAngle
    startAngle = tmp
  } 
  console.log(startAngle, endAngle)

  // 세점 그리기
  ctx.beginPath();
  ctx.moveTo(p1.x, p1.y)
  ctx.arc(p1.x, p1.y, 5, 0, 2*Math.PI);
  ctx.moveTo(p2.x, p2.y)
  ctx.arc(p2.x, p2.y, 5, 0, 2*Math.PI);
  ctx.moveTo(p3.x, p3.y)
  ctx.arc(p3.x, p3.y, 5, 0, 2*Math.PI);
  ctx.strokeStyle = 'red';
  ctx.fill();
  ctx.stroke();

  // 원호 arc로 그리기
  // ctx.beginPath();
  // ctx.arc(c.x, c.y, radius, startAngle, endAngle);
  // ctx.moveTo(p3.x, p3.y);
  // ctx.lineTo(c.x, c.y);
  // ctx.lineTo(p1.x, p1.y);
  // ctx.strokeStyle = "blue";
  // ctx.stroke();

  // 원호를 점으로 그리기
  var obj = {};
  // startAngle ~ endAngle 까지 n개의 라디언 으로 표시
  let gab = (endAngle - startAngle) / 20
  for (var i = startAngle; i <= endAngle; i += gab) {
    obj.x = Math.floor(radius * Math.cos( i ));
    obj.y = Math.floor(radius * Math.sin( i ));
    ctx.strokeRect( c.x+obj.x , c.y+obj.y, 2,2);
  }


}
function toRadians(degrees) {	
  return degrees * (Math.PI / 180);
}
	</script>
</body>
</html>

 

 

+ Recent posts