카테고리 없음2022. 5. 11. 13:55


중학생이 될 때 익혀야 할 스킬 중 하나가 읽기 속도 향상 이다.
초등학생 때 보다 긴 글을 빠르게 읽어야 하기 때문이다.
이 때 참고 할 만한 것이 무협지에 자주 등장 하는 폐관수련 이다.

현대에는 이 읽기 능력 폐관 수련을 도와 줄 최적의 장소가 있다.
일명 만화방 혹은 만화카페 이다. 비록 공청석유와 영약으로 버무려진 벽곡단은 없지만, 그 보다 맛있는 만화방표 라면과 스낵이 있다.

1차 폐관 수련은 일주일간 만화책을 하루 16시간 씩 보는 거다.
16시간 × 7 = 112시간 이니, 120권을 1차 목표 삼고
드래곤 볼, 슬램덩크, 다이의 대모험을 보자.

2차 폐관 수련은 일주일간 무협지를 하루 16시간 씩 보는 거다.
영웅문 3부작, 사조영웅전, 신조협려, 의천도룡기를 보자.
그리고 녹정기 까지 보는거다.

3차 폐관 수련은 이제 판타지 소설에 도전하는 것이다.
해리포터 시리즈를 일독 한다.

4차 폐관 수련은 고전 소설 도전이다.
본 삼국지, 은하영웅전설, 한국 대표 고전 소설을 읽자.

이렇게 한 달에 걸친 독서 훈련으로 우리는 평생 할 이야기 소재와
더블어 속독이라는 기술을 얻을 수 있다.


Posted by chobocho

댓글을 달아 주세요

Coding/Python 삽질기2022. 4. 23. 00:49

C library 작성

#include <stdio.h>
int add(int left, int right) {
    return left+right;
}
 
C library 빌드
gcc -shared -o libaddnumber.so add_number.c
 

Python Code 작성

from ctypes import CDLL
 
def main():
    c_func = CDLL('./libaddnumber.so')
    print(c_func.add(10, 20))
 
if __name__ == '__main__':
    main()
 
 
실행결과
chobocho@Chobocho-Mint:~/github/python/sharedlib$ python3 add_number.py 
30

'Coding > Python 삽질기' 카테고리의 다른 글

[Python] C 함수 호출 하기  (0) 2022.04.23
[PyTorch] CUDA 설치기  (0) 2022.02.21
생일 문제  (0) 2021.06.21
[Python/C] 휴대폰 패턴의 가지수  (0) 2021.02.21
Posted by chobocho

댓글을 달아 주세요

Coding/좋은 사이트2022. 4. 18. 23:38


Airbnb 
https://medium.com/airbnb-engineering

Amazon
https://developer.amazon.com/blogs/appstore

AWS KR 기술 블로그
https://aws.amazon.com/ko/blogs/korea/

Dropbox
https://dropbox.tech/

Google
https://developers.googleblog.com/

Google KR
https://developers-kr.googleblog.com/

Instagram
https://instagram-engineering.com/

Netflix
https://netflixtechblog.com/

Slack
https://slack.engineering/


네이버
https://d2.naver.com/home

당근마켓 팀블로그
https://medium.com/daangn

라인
https://engineering.linecorp.com/ko/blog/

우아한형제들
https://techblog.woowahan.com/

카카오
https://tech.kakao.com/blog/

쿠팡 기술 블로그
https://medium.com/coupang-engineering

'Coding > 좋은 사이트' 카테고리의 다른 글

기술 블로그 모음  (0) 2022.04.18
하트 그리기  (0) 2018.03.07
함수의 그래프를 그려주는 사이트  (0) 2018.03.03
무료 에디터  (1) 2017.07.27
Posted by chobocho

댓글을 달아 주세요

My Life/version 6.12022. 4. 18. 00:19

프로그래밍 중급(?) 수준에 이르기 위해서 보면 좋을 책을 내 마음 대로 정리해 보았습니다.

재미로 읽어보시길 바랍니다.

좋은 책 있으시면 추천 부탁드립니다.

- 중급 -
Clean architecture
Clean code
Clean coder
Clean software
CODE
Code craft
Code complete 2
DNS 실전 교과서
Effective java 3/e
GoF의 디자인 패턴
Head First Design Pattern 2/e
Refactoring 2/e
가상 면접 사례로 배우는 대규모 시스템 설계 기초
개발자의 글쓰기
구글 엔지니어는 이렇게 일한다
김도형의 데이터 사이언스 스쿨 수학 편
모던 자바 인 액션
맨먼스 미신
밑바닥부터 만드는 컴퓨팅 시스템
밑바닥부터 시작하는 딥러닝 3/e
생각하는 프로그래밍
소프트웨어 장인
실용주의 프로그래밍
이펙티브 코틀린
조엘 온 소프트웨어
컴파일러 구조와 원리 - 컴파일러로 배우는 언어 처리 시스템
테스트 주도 개발
프로그래머의 길, 멘토에게 묻다
피플웨어
한 권으로 읽는 컴퓨터 구조와 프로그래밍
해커와 화가
핸즈온 머신러닝
헤커의 기쁨 2/e

- 초급 -
1일 1로그 100일 완성 IT 지식
그림으로 공부하는 TCP/IP 구조
파이썬 알고리즘 인터뷰

Posted by chobocho

댓글을 달아 주세요

My Life/version 19 (2019)2022. 3. 25. 21:20
.
오랜만에 책장속에 숨어있던, '어린왕자'를 꺼내 읽었다.
.
책을 다 읽고 관련 내용을 검색을 하다가 '어린왕자 명대사 명언 XX선'이란 글들을 보았다.
그런데 그 중에 '어린왕자'에서 못 본 문구들이 보였다.
.
나의 기억력에 문제가 있는게 아닐까 하는 불안감 속에, 기억
력 자가 검증을 위하여 전자책의 검색 기능을 활용하여 체크를 했는데,
다행히 내 기억이 옳았다.
내가 못봤다고 생각한 문구들은 책에 없었다.
.
많은 블로그와 브런치 글들에서 비슷한 오류가 보였다.
다들 책을 안 읽고 어디 비슷한 소스에서 Copy & Paste로 검증 없이 붙인것 같았다.
.
인터넷에서 찾은 자료는 잘못된 정보가 포함되었을 가능성이 높다는 걸 오늘도 배웠다.
.
결론: 인터넷 자료는 항상 검증이 필요하다.
Posted by chobocho

댓글을 달아 주세요

My Life/Mobile2022. 3. 1. 23:16

sharedate:*

로 검색 창에서 검색하면 된다.

Posted by chobocho

댓글을 달아 주세요

Coding/Python 삽질기2022. 2. 21. 23:37

PyTorch에서 GPU를 사용해보기로 하고, 삽질한 기록을

미래의 나를 위하여, 기록하였습니다.

1. 노트북 그래픽 카드 확인

 

2. Pytorch 사이트에서 CUDA 버전을 확인한다.

https://pytorch.org/get-started/locally/

 

PyTorch

An open source machine learning framework that accelerates the path from research prototyping to production deployment.

pytorch.org

 PyTorch 1.10.2에 Pip로 CUDA 10.2를 선택하면, 아래에 pip3 명령어가 보인다.  이를 사용하여 pytorch를 설치한다.

 

3. CUDA library 설치

PyTorch 사이트에서 확인한 CUDA 10.2 버전을 설치한다.

 

* 간혹 NVIDIA experience가 동작을 안하는 경우에는 아래와 같이

NVIDIA LocalSystem Controller 에서 로컬 시스템 계정 항목을 체크해 준다.

4. 파이썬을 실행해서 확인 해 본다.

 

'Coding > Python 삽질기' 카테고리의 다른 글

[Python] C 함수 호출 하기  (0) 2022.04.23
[PyTorch] CUDA 설치기  (0) 2022.02.21
생일 문제  (0) 2021.06.21
[Python/C] 휴대폰 패턴의 가지수  (0) 2021.02.21
Posted by chobocho

댓글을 달아 주세요

 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Mandelbrot</title>
    <meta name='viewport' content='width=device-width, initial-scale=1.0'>
    <style>
        canvas {
            height: 100%;
            width: 100%;
        }
    </style>
</head>
<body>
<div align='center'>
    <canvas id="canvas"></canvas>
</div>

<script language="JavaScript">
    // Start: 2022.02.02
    // Update: 2022.02.02

    let cvs;
    let canvas;
    let bufCanvas;
    let bufCtx;
    let imageData;

    let scaleX = 1.0;
    let scaleY = 1.0;
    let mx = 1.0;
    let my = 1.0;

    function InitCanvas() {
        height = window.innerHeight;
        width = window.innerWidth;

        canvas = document.getElementById("canvas");
        canvas.width = width;
        canvas.height = height;
        cvs = canvas.getContext("2d");

        bufCanvas = document.createElement("canvas");
        bufCanvas.width = canvas.width;
        bufCanvas.height = canvas.height;
        bufCtx = bufCanvas.getContext("2d");

        imageData = bufCtx.createImageData(canvas.width, canvas.height);
    }

    function _draw(x1, y1, x2, y2) {
        const MAX_COUNT = 256;

        // X = -3.0 ~ 3.0
        // Y = -2.0 ~ 2.0
        // Z = X + Yi

        mx = x1 < -3.0 ? -3.0 : x1;
        my = y1 < -2.0 ? -2.0 : y1;

        x2 = x2 > 3.0 ? 3.0 : x2;
        y2 = y2 > 2.0 ? 2.0 : y2;

        let mw = x2 - x1;
        let mh = y2 - y1;

        console.log(x1, y1, x2, y2, " : ", mx, my, " : ", mw, mh);

        scaleX = mw / imageData.width;
        scaleY = mh / imageData.height;

        for (let i = 0; i < imageData.height; i++) {
            for (let j = 0; j < imageData.width; j++) {

                let c = 0;
                let x = mx + j * scaleX;
                let y = my + i * scaleY;
                let sx = x;
                let sy = y;

                for (c = 0; c < MAX_COUNT; c++) {
                    if (x**2 + y**2 > 4) {
                        break;
                    }
                    let nx = x**2 - y**2;
                    let ny = 2 * x * y;
                    x = nx + sx;
                    y = ny + sy;
                }

                let pos = 4 * (i * imageData.width + j);
                let color = 3 * c / MAX_COUNT;

                if (color < 1) {
                    imageData.data[pos+0]  = 255 * color;
                    imageData.data[pos+1] = color;
                    imageData.data[pos+2] = color;
                }
                else if (color < 2 ) {
                    imageData.data[pos+0] = 255;
                    imageData.data[pos+1] = color;
                    imageData.data[pos+2] = 0;
                } else {
                    imageData.data[pos+0] = 255;
                    imageData.data[pos+1] = 255;
                    imageData.data[pos+2] = color;
                }

                imageData.data[pos+3] = 255;
            }
        }

        bufCtx.putImageData(imageData, 0, 0);
        console.log("_OnDraw2()");
    }

    function OnDraw() {
        _draw(-3.0, -2.0, 3.0, 2.0);
        cvs.clearRect(0, 0, canvas.width, canvas.height);
        cvs.drawImage(bufCanvas, 0, 0);
    }

    function rectMouseMove(event) {
        // console.log("rectMouseMove");
        var currentPos = getMousePosition(event);
        cvs.beginPath();

        cvs.clearRect(0, 0, canvas.width, canvas.height);
        cvs.drawImage(bufCanvas, 0, 0);

        cvs.strokeStyle = pos.color;
        var box = {
            W: currentPos.X - pos.sx,
            H: currentPos.Y - pos.sy
        };

        cvs.strokeRect(pos.sx, pos.sy, box.W, box.H);

        cvs.stroke();
        cvs.closePath();
    }

    function rectMouseUp(event) {
        if (pos.isDraw) {
            console.log("rectMouseUp");
            var currentPos = getMousePosition(event);

            pos.ex = currentPos.X;
            pos.ey = currentPos.Y;

            if (pos.sx > pos.ex) {
                let t = pos.sx;
                pos.sx = pos.ex;
                pos.ex = t;
            }

            if (pos.sy > pos.ey) {
                let t = pos.sy;
                pos.sy = pos.ey;
                pos.ey = t;
            }

            let sx = mx + pos.sx * scaleX;
            let sy = my + pos.sy * scaleY;
            let ex = mx + pos.ex * scaleX;
            let ey = my + pos.ey * scaleY ;

            _draw(sx, sy, ex, ey);
            cvs.clearRect(0, 0, canvas.width, canvas.height);
            cvs.drawImage(bufCanvas, 0, 0);

            pos.isDraw = false;
        }
    }

    function rectMouseDown(event) {
        console.log("rectMouseDown");
        if (pos.isDraw) {
            return;
        }
        bufCtx.putImageData(imageData, 0, 0);
        //bufCtx.drawImage(canvas, 0, 0);
        pos.isDraw = true;
        var startPos = getMousePosition(event);
        pos.sx = startPos.X;
        pos.sy = startPos.Y;
    }

    function mouseListener(event) {
        switch (event.type) {
            case "mousedown":
                if (!pos.isDraw) {
                    pos.mouseDownAction(event);
                }
                break;
            case "mousemove":
                if (pos.isDraw) {
                    pos.mouseMoveAction(event);
                }
                break;
            case "mouseup":
            case "mouseout":
                if (pos.isDraw) {
                    pos.mouseUpAction(event);
                }
                break;
        }
    }

    function InitMouseEvent() {
        canvas.addEventListener("mousedown", mouseListener);
        canvas.addEventListener("mousemove", mouseListener);
        canvas.addEventListener("mouseout", mouseListener);
        canvas.addEventListener("mouseup", mouseListener);
    }

    function getMousePosition(event) {
        var x = event.pageX - canvas.offsetLeft;
        var y = event.pageY - canvas.offsetTop;
        return { X: x, Y: y };
    }

    var pos = {
        isDraw: false,
        mouseDownAction: rectMouseDown,
        mouseUpAction: rectMouseUp,
        mouseMoveAction: rectMouseMove,
        color: "rgb(255,211,25,255)",
        sx: 0,
        sy: 0,
        ex: 0,
        ey: 0
    }

    function onLoadPage() {
        InitCanvas();
        InitMouseEvent();
        OnDraw();
    }

    window.onload = onLoadPage();
</script>
</body>
</html>
Posted by chobocho

댓글을 달아 주세요

자바스크립트로 만델브로트 집합을 구현해 보았다.

만델브로트 집합

 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Mandelbrot</title>
    <meta name='viewport' content='width=device-width, initial-scale=1.0'>
    <style>
        canvas {
            height: 100%;
            width: 100%;
        }
    </style>
</head>
<body>
<div align='center'>
    <canvas id="canvas"></canvas>
</div>

<script language="JavaScript">
    // Start: 2022.02.02
    // Update: 2022.02.02

    let cvs;
    let canvas;
    let bufCanvas;
    let bufCtx;

    function InitCanvas() {
        height = window.innerHeight;
        width = window.innerWidth;

        canvas = document.getElementById("canvas");
        canvas.width = width;
        canvas.height = height;
        cvs = canvas.getContext("2d");

        bufCanvas = document.createElement("canvas");
        bufCanvas.width = canvas.width;
        bufCanvas.height = canvas.height;
        bufCtx = bufCanvas.getContext("2d");
    }

    function _draw() {
        let imageData = bufCtx.createImageData(canvas.width, canvas.height);
        const MAX_COUNT = 255;

        // X = -3.0 ~ 3.0
        // Y = -2.0 ~ 2.0
        // Z = X + Yi

        let mx = -3.0;
        let my = -2.0;
        let mw = 6.0;
        let mh = 4.0;
        let scaleX = mw / imageData.width;
        let scaleY = mh / imageData.height;

        for (let i = 0; i < imageData.height; i++) {
            for (let j = 0; j < imageData.width; j++) {

                let c = 0;
                let x = mx + j * scaleX;
                let y = my + i * scaleY;
                let sx = x;
                let sy = y;

                for (c = 0; c < MAX_COUNT; c++) {
                    if (x**2 + y**2 > 4) {
                        break;
                    }
                    let nx = x**2 - y**2;
                    let ny = 2 * x * y;
                    x = nx + sx;
                    y = ny + sy;
                }

                let pos = 4 * (i * imageData.width + j);

                imageData.data[pos+0] = c;
                imageData.data[pos+1] = c;
                imageData.data[pos+2] = c;
                imageData.data[pos+3] = 255;
            }
        }

        bufCtx.putImageData(imageData, 0, 0);
    }

    function OnDraw() {
        _draw();
        cvs.beginPath();
        cvs.clearRect(0, 0, canvas.width, canvas.height);
        cvs.drawImage(bufCanvas, 0, 0);
    }

    function onLoadPage() {
        InitCanvas();
        OnDraw();
    }

    window.onload = onLoadPage();
</script>
</body>
</html>
Posted by chobocho

댓글을 달아 주세요

Coding/JavsScript 삽질기2022. 1. 20. 00:12
Sphere

 


 

소스는 아래와 같다.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Sphere</title>
    <meta name='viewport' content='width=device-width, initial-scale=1.0'>
    <style>
        canvas {
            height: 100%;
            width: 100%;
        }
    </style>
</head>
<body>
<div align='center'>
    <canvas id="canvas"></canvas>
</div>
<script language="JavaScript">
    // Start: 2022.01.16
    // Update: 2022.01.18

    let cvs;
    let canvas;
    let bufCanvas;
    let bufCtx;
    let thetaX = 0;
    let thetaZ = 0;

    let maxSize = 0;
    let dimen = 12;
    let ox = 0;
    let oy = 0;
    let R1 = 1;  // 원의 반지름
    let R2 = 1;  // 회전 중심과의 거리
    let R3 = 1;
    let ZZ2 = 5000;

    let SIN = [];
    let COS = [];

    function InitValue() {
        for (let i = 0; i < 628; i++) {
            SIN[i] = Math.sin(i / 100);
            COS[i] = Math.cos(i / 100);
        }
    }

    function InitCanvas() {
        height = window.innerHeight;
        width = window.innerWidth;

        console.log(">Width:", width);
        console.log(">Heigth:", height);

        canvas = document.getElementById("canvas");
        canvas.width = width;
        canvas.height = height;
        cvs = canvas.getContext("2d");

        bufCanvas = document.createElement("canvas");
        bufCanvas.width = canvas.width;
        bufCanvas.height = canvas.height;
        bufCtx = bufCanvas.getContext("2d");

        maxSize = canvas.height < canvas.width ? canvas.height : canvas.width;

        ox = canvas.width / 2;
        oy = canvas.height / 2;
        R1 = maxSize/20;  // 원의 반지름
        R2 = maxSize/10;  // 회전 중심과의 거리
        R3 = maxSize/10;
    }

    function drawCircle(x, y, c, r) {
        if (c <= 0 || c >= 255){
            console.log(c);
        }

        bufCtx.beginPath();
        bufCtx.fillStyle = "rgb(" + c + "," + c + "," + c + ")";
        bufCtx.strokeStyle = "rgb(255, 255, 255)";
        bufCtx.arc(x, y, r, 0, Math.PI * 2);
        bufCtx.stroke();
        bufCtx.fill();
        bufCtx.closePath();
    }

    function _draw() {
        if (maxSize == 0) {
            return;
        }
        // 카메라와 스크린의 거리를 z'라 하고, 그 투영되는 상을 x',y'
        // z:x = z':x'
        // z:y = z':y'
        // x' = xz'/z, y' = yz'/z
        // z' = z1
        // x', y' = xz1/z, yz1/z
        // z의 최대거리 z2 = 1000이라 하면
        // x' <= (height/2 * 0.8) (화면 중앙 위치, 마진 0.1)
        // x 의 최대 값은 R1 + R2
        // x' = Z1(R1+R2)/z2 = height * 0.4
        // Z1 = Z2 * height * 0.4 / (R1+R2)

        let points = [];
        _drawDoughnut(points);
        _drawSphere(points);

        bufCtx.strokeStyle = "black";
        bufCtx.fillStyle = "black";
        bufCtx.fillRect(0, 0, canvas.width, canvas.height);
        points.forEach(e => drawCircle(e[0], e[1], e[2], 1));

        thetaX = (thetaX + 2) % 629;
        thetaZ = (thetaZ + 2) % 629;
    }


    function _drawDoughnut(points) {
        // 카메라와 스크린의 거리를 z'라 하고, 그 투영되는 상을 x',y'
        // z:x = z':x'
        // z:y = z':y'
        // x' = xz'/z, y' = yz'/z
        // z' = z1
        // x', y' = xz1/z, yz1/z
        // z의 최대거리 z2 = 5000이라 하면
        // x' <= (height/2 * 0.8) (화면 중앙 위치, 마진 0.1)
        // x 의 최대 값은 R1 + R2
        // x' = Z1(R1+R2)/z2 = height * 0.4
        // Z1 = Z2 * height * 0.4 / (R1+R2)
        let ZZ1 = maxSize * ZZ2 * 0.4 / (R1 + R2);

        for (let i = 0; i < 628; i += dimen) {
            let x1 = COS[i] * R1 + R2;
            let y1 = SIN[i] * R1;
            let nx1 = COS[i];
            let ny1 = SIN[i];

            for (let j = 0; j < 628; j += dimen) {
                // Y축 회전
                let x2 = x1 * COS[j];
                let y2 = y1;
                let z2 = x1 * SIN[j];

                let nx2 = nx1 * COS[j];
                let ny2 = ny1;
                let nz2 = nx1 * SIN[j];

                // X축 회전
                let x3 = x2;
                let y3 = y2 * COS[thetaX] - z2 * SIN[thetaX];
                let z3 = y2 * SIN[thetaX] + z2 * COS[thetaX];

                let nx3 = nx2;
                let ny3 = ny2 * COS[thetaX] - nz2 * SIN[thetaX];
                let nz3 = ny2 * SIN[thetaX] + nz2 * COS[thetaX];

                // Z축 회전
                let x4 = x3 * COS[thetaZ] - y3 * SIN[thetaZ];
                let y4 = x3 * SIN[thetaZ] + y3 * COS[thetaZ];
                let z4 = ZZ2 * 2 + z3;

                let nx4 = nx3 * COS[thetaZ] - ny3 * SIN[thetaZ];
                let ny4 = nx3 * SIN[thetaZ] + ny3 * COS[thetaZ];
                let nz4 = nz3;

                // 법선 벡터 (nx4, ny4, nz)와 광원의 백터 내적 계산
                // 광원 위치는 (0, 0, -1)
                let lx = 0;
                let ly = 0;
                let lz = -1;
                let light = nx4 * lx + ny4 * ly + nz4 * lz;

                if (light > 0) {
                    let color = Math.round(light * 255);

                    // x' = xz'/z, y' = yz'/z
                    let xp = Math.floor(x4 * ZZ1 / z4);
                    let yp = Math.floor(-y4 * ZZ1 / z4);

                    points.push([xp + ox, yp + oy, 255-color]);
                }
            }
        }
    }


    function _drawSphere(points) {
        // 카메라와 스크린의 거리를 z'라 하고, 그 투영되는 상을 x',y'
        // z:x = z':x'
        // z:y = z':y'
        // x' = xz'/z, y' = yz'/z
        // z' = z1
        // x', y' = xz1/z, yz1/z
        // z의 최대거리 z2 = 1000이라 하면
        // x' <= (height/2 * 0.8) (화면 중앙 위치, 마진 0.1)
        // x 의 최대 값은 R1 + R2
        // x' = Z1(R1+R2)/z2 = height * 0.4
        // Z1 = Z2 * height * 0.4 / (R1+R2)

        ZZ1 = maxSize * ZZ2 * 0.4 / (R1 + R2 + R3);

        for (let i = 0; i < 628; i += dimen) {
            let x1 = COS[i] * R1;
            let y1 = SIN[i] * R1;
            let nx1 = COS[i];
            let ny1 = SIN[i];

            for (let j = 0; j < 628; j += dimen) {
                // Y축 회전
                let x2 = x1 * COS[j];
                let y2 = y1;
                let z2 = x1 * SIN[j];

                let nx2 = nx1 * COS[j];
                let ny2 = ny1;
                let nz2 = nx1 * SIN[j];

                // Z축 회전
                let x3 = x2 * COS[thetaX] - y2 * SIN[thetaX];
                let y3 = x2 * SIN[thetaX] + y2 * COS[thetaX];
                let z3 = z2;

                let nx3 = nx2 * COS[thetaX] - ny2 * SIN[thetaX];
                let ny3 = nx2 * SIN[thetaX] + ny2 * COS[thetaX];
                let nz3 = nz2;

                // X축 회전
                let x4 = x3 + R2 + R3;
                let y4 = y3 * COS[thetaX] - z3 * SIN[thetaX];
                let z4 = y3 * SIN[thetaX] + z3 * COS[thetaX];

                let nx4 = nx3;
                let ny4 = ny3 * COS[thetaX] - nz3 * SIN[thetaX];
                let nz4 = ny3 * SIN[thetaX] + nz3 * COS[thetaX];

                // Z축 시계 방향 회전
                let x5 = x4 * COS[thetaZ] + y4 * SIN[thetaZ];
                let y5 = -x4 * SIN[thetaZ] + y4 * COS[thetaZ];
                let z5 = ZZ2 + z4;

                let nx5 = nx4 * COS[thetaZ] + ny4 * SIN[thetaZ];
                let ny5 = -nx4 * SIN[thetaZ] + ny4 * COS[thetaZ];
                let nz5 = nz4;

                // 법선 벡터 (nx4, ny4, nz)와 광원의 백터 내적 계산
                // 광원 위치는 (0, 0, -1)
                let lx = 0;
                let ly = 0;
                let lz = -1;
                let light = nx5 * lx + ny5 * ly + nz5 * lz;

                if (light > 0) {
                    let color = Math.round(light * 255);

                    // x' = xz'/z, y' = yz'/z
                    let xp = Math.floor(x5 * ZZ1 / z5);
                    let yp = Math.floor(-y5 * ZZ1 / z5);

                    points.push([xp + ox, yp + oy, 255-color]);
                }
            }
        }
    }

    function OnDraw() {
        _draw();

        cvs.clearRect(0, 0, canvas.width, canvas.height);
        cvs.drawImage(bufCanvas, 0, 0);
    }


    function onLoadPage() {
        InitValue();
        InitCanvas();
        OnDraw();
        setInterval(OnDraw, 50);
    }

    window.onload = onLoadPage();
</script>
</body>
</html>
Posted by chobocho

댓글을 달아 주세요