Coding Challenge/오늘의 코드

html canvas로 별찍기

인생마린 2020. 9. 21. 08:05
반응형

백준 별찍기문제를 canvas로 그려봤습니다

 

https://www.acmicpc.net/problem/2448

 

그리려고 하는 형태

이 문제는 재귀방식으로 세모를 그리고 위, 아래왼쪽, 아래오른쪽에 그림 그리기를 이어나가는 방식입니다. 그렇다면 재귀 깊이를 n이라고 했을때 3(n-1)번 재귀가 들어간다는걸 알 수 있습니다.

 

그런데 무한정 재귀를 들어 갈수는 없으니 몇번 재귀로 이러한 그림을 그릴지 input을 넣을 수 있게 inputbox를 만들어주도록 합시다.

 

재귀문에 넘겨줄 데이터는 삼각형의 꼭지점중 하나의 (x, y) 좌표, 한변의 길이, 몇번 재귀를 들어갈건지입니다. 우리가 그릴건 정삼각형이기 때문에 sin60, cos60과 한변의 길이를 이용하여 나머지 두 좌표도 구할수 있습니다.

 

 

 

아래는 전체 소스입니다

<html>
    <head>
        <script type="application/javascript">

            function recursive(ctx, x, y, sz, cnt){
                if(cnt === 0)return;
                let x1, x2, y1, y2;
                ctx.beginPath();
                ctx.moveTo(x, y);
                x1 = x - Math.cos(Math.PI/3)*sz;
                y1 = y + Math.sin(Math.PI/3)*sz;
                ctx.lineTo(x1, y1)
                x2 = x + Math.cos(Math.PI/3)*sz;
                y2 = y + Math.sin(Math.PI/3)*sz;
                ctx.lineTo(x2, y2)
                ctx.closePath();
                ctx.stroke();
                if(cnt%2 === 1){
                    ctx.fillStyle = "rgba(100, 100, 100, 0.5)";
                    ctx.fill();
                }
                else{
                    ctx.fillStyle = "rgba(255, 255, 255, 1)";
                    ctx.fill();
                }
                cnt--;
                sz /= 2;
                recursive(ctx, x, y, sz, cnt);
                recursive(ctx, (x+x1)/2, (y+y1)/2, sz, cnt);
                recursive(ctx, (x+x2)/2, (y+y2)/2, sz, cnt);
            }

            function draw(cnt) {
                var canvas = document.getElementById("canvas");
                if(canvas.getContext){
                    var ctx = canvas.getContext("2d");
                    recursive(ctx, 400, 0, 800, cnt);
                }
            }

            function getEvent(event){
                event.preventDefault();
                var input = document.getElementById("myinput").value;
                draw(parseInt(input));
            }
        </script>
    </head>
    <body> <!-- body요소가 전부 로드되고 한번 호출-->
        <form onsubmit="getEvent(event)">
            <input id="myinput" type="text">
        </form>
        <canvas id="canvas" width="900" height="900"></canvas>
    </body>
</html>
반응형