- [002] d3.Delaunay2022년 06월 13일
- 루루개발자
- 작성자
- 2022.06.13.:23
반응형d3.Delaunay
d3.Delaunay 는 "2차원 점 집합의 Voronoi 다이어그램을 계산하기 위한 라이브러리" 라고 합니다.
* Voronoi 다이어그램 : 평면에 놓인 점들을 기준으로 수학적 공식을 적용하여 다각형을 이루는 영역으로 채워진 그림
예제
먼저 html 파일의 내용을 다음과 같이 작성합니다.
<div class="box"></div>
css 는 다음과 같이 작성합니다.
.box { width: 400px; height: 400px; display: block; margin: 20px; padding: 0; position: relative; border: 1px solid #ccc; }
js 파일은 다음과 같이 작성합니다.
window.addEventListener('load', function() { // canvas 의 크기입니다. const w = 400; const h = 400; // canvas element 를 생성합니다. const canvas = document.createElement('canvas'); // canvas context 를 가져옵니다. const context = canvas.getContext('2d'); // canvas의 너비, 높이를 지정합니다. canvas.width = w; canvas.height = h; // 400 x 400 크기의 canvas 에 표시될 좌표 데이터 입니다. const pointsData = [ { x: 14, y: 23 }, { x: 100, y: 100 }, { x: 30, y: 250 }, { x: 222, y: 65 }, { x: 301, y: 274 }, { x: 274, y: 288 }, { x: 274, y: 351 }, { x: 300, y: 300 }, { x: 400, y: 380 }, ]; // canvas 에 좌표를 그립니다. for (const point of pointsData) { console.log('point', point); // 좌표 위치에 좌표의 x, y 값의 텍스트를 그립니다. context.beginPath(); context.font = '12px serif'; context.fillStyle = '#000'; context.fillText(`(${point.x}, ${point.y})`, point.x + 5, point.y); context.closePath(); // 좌표 위치에 원을 그립니다. context.beginPath(); context.arc(point.x, point.y, 2, 0, Math.PI * 2); context.strokeStyle = '#f00'; context.fillStyle = '#f00'; context.stroke(); context.fill(); context.closePath(); } // d3.Delaunay 의 from 함수를 통해 delaunay 객체를 가져옵니다. const delaunay = d3.Delaunay.from( pointsData, (d) => { // x 좌표에 해당하는 값 리턴 return d.x; }, (d) => { // y 좌표에 해당하는 값 리턴 return d.y; }, ); // delaunay 객체의 voronoi 함수를 통해 voronoi 객체를 가져옵니다. const voronoi = delaunay.voronoi([0, 0, 400, 400]); // x 좌표의 최소값, y 좌표의 최소값, x 좌표의 최대값, y 좌표의 최대값 // voronoi 다이어그램을 이루는 다각형의 선들을 그립니다. const pathInfo = voronoi.render(); for (const path of pathInfo.split('M').slice(1)) { context.beginPath(); context.strokeStyle = d3.hsl(360 * Math.random(), 0.7, 0.5); // 선 색상은 랜덤 context.stroke(new Path2D('M' + path)); context.closePath(); } // voronoi 다이어그램을 이루는 다격형에 색을 입힙니다. pointsData.forEach((point, index) => { const cellPolygonPoints = voronoi.cellPolygon(index); // i 번째 좌표를 기준으로 형성된 다각형의 선 좌표 정보 const randomColor = d3.rgb(Math.random() * 255, Math.random() * 255, Math.random() * 255, 0.5); // 랜덤 색상 context.beginPath(); context.strokeStyle = 'rgba(255, 255, 255, 0)'; cellPolygonPoints.forEach((cellPolygonPoint, cellPolygonPointIndex) => { if (cellPolygonPointIndex === 0) { context.moveTo(cellPolygonPoint[0], cellPolygonPoint[1]); } else { context.lineTo(cellPolygonPoint[0], cellPolygonPoint[1]); } }); context.fillStyle = `rgba(${randomColor.r}, ${randomColor.g}, ${randomColor.b}, ${randomColor.opacity})`; context.stroke(); context.fill(); context.closePath(); }); // canvas 를 특정 element 안에 추가합니다. document.querySelector(".box").appendChild(canvas); });
결과는 다음과 같습니다.
색상을 랜덤으로 주었기에, 새로고침할 때마다 색이 바뀌는 걸 확인 하실 수 있을겁니다.
참고자료
https://runebook.dev/ko/docs/d3/d3-delaunay
https://stackoverflow.com/questions/68694527/d3-js-d3-delaunay-how-to-get-started
https://www.visualcinnamon.com/2015/07/voronoi/
https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=tnmeschool&logNo=40167826908
반응형'Node.js & Javascript & Typescript > d3.js' 카테고리의 다른 글
[006] d3.Voronoi (0) 2022.06.29 [005] d3.InternSet (0) 2022.06.28 [004] d3.InternMap (0) 2022.06.27 [003] d3.FormatSpecifier (0) 2022.06.20 [001] d3.Adder (0) 2022.06.12 다음글이전글이전 글이 없습니다.댓글
스킨 업데이트 안내
현재 이용하고 계신 스킨의 버전보다 더 높은 최신 버전이 감지 되었습니다. 최신버전 스킨 파일을 다운로드 받을 수 있는 페이지로 이동하시겠습니까?
("아니오" 를 선택할 시 30일 동안 최신 버전이 감지되어도 모달 창이 표시되지 않습니다.)