2.3. 3각형면을 그리기

17389 단어 자바스크립트3D
3D의 기본적인 지식을 이해하고 싶어서, 「3차원 CG의 기초와 응용[신정판]( h tp //오. gl/G코 Q4y )」이라고 하는 서적을 구입했습니다. 얇고 읽기 쉬운 것 같은 책이지만 샘플 소스가 없기 때문에, 공부가 테라 샘플을 만들면서 읽어 나가려고 생각합니다. 누구나 즉시 추시를 할 수 있도록 HTML + Javascript로 샘플을 만들어갑니다.

완전한 샘플은 이쪽
htps : // 기주 b. 코 m / 나카 칸 0629 / 3ds dy

2.3. 3각형면을 그리기



가장 기본적인 다각형인 삼각형면을 2.1.에서 사용한 점을 그리는 처리를 사용하여 그리는 처리입니다. 2.2.에서 사용한 브레젠햄의 알고리즘을 사용하는 방법도 있습니다만, 그것은 나름대로 나중에 옮겨놓을 것이라고 하는 것으로, 이번은 실수가 나오는 나눗셈을 사용한 소박한 처리로 실장하고 있습니다. 실수가 얽힌 오차 탓인지, 그려진 폴리곤은 조금 투명한 장소도 나와 있습니다.



샘플 코드



session2_3.html에서
/* 共通処理 */

var canvas;
var ctx;

window.onload = function() {
    canvas = document.getElementById("myCanvas");
    ctx = canvas.getContext("2d");
    main();
};

var createRgb = function(red, green, blue) {
    return "#"
        + ("0" + red.toString(16)).substr(-2)
        + ("0" + green.toString(16)).substr(-2)
        + ("0" + blue.toString(16)).substr(-2)
    ;
};

var getRandomInt = function(min, max) {
      return Math.floor(Math.random() * (max - min + 1)) + min;
};

/* 個別処理 */

var main = function() {
    for(var i = 0; i < 5; i++) {
        x1 = getRandomInt(0, 319);
        y1 = getRandomInt(0, 199);
        x2 = getRandomInt(0, 319);
        y2 = getRandomInt(0, 199);
        x3 = getRandomInt(0, 319);
        y3 = getRandomInt(0, 199);
        red = getRandomInt(0, 255);
        green = getRandomInt(0, 255);
        blue = getRandomInt(0, 255);
        fillTriangle(x1, y1, x2, y2, x3, y3, createRgb(red, green, blue));
    }
};

var pset = function(x, y, rgb) {
    /* 1pxでは見づらいため、2pxとしている */
    ctx.fillStyle = rgb;
    ctx.fillRect(x * 2, y * 2, 2, 2);
};

var fillTriangle = function(x1, y1, x2, y2, x3, y3, rgb) {
    /* 素朴なアルゴリズム */
    var xmin = Math.min(x1, x2, x3);
    var ymin = Math.min(y1, y2, y3);
    var xmax = Math.max(x2, x2, x3);
    var ymax = Math.max(y1, y2, y3);

    for(var y = ymin; y <= ymax; y++) {
        /* y軸方向にスキャンする */
        var xl = null;  /* x left */
        var xr = null;  /* x right */
        var pairs = [[x1, y1, x2, y2], [x2, y2, x3, y3], [x3, y3, x1, y1]];
        for(var i = 0; i < pairs.length; i++) {
            /* 3本の直線とスキャンラインの交点を求める */
            var pair = pairs[i];
            var _x1 = pair[0];
            var _y1 = pair[1];
            var _x2 = pair[2];
            var _y2 = pair[3];
            var x;
            if(_x1 == _x2) {
                /* _x1と_x2が等しい時は水平な線分になるので、無視する */
                continue;
            }
            if(y < _y1 && y < _y2 || y > _y1 && y > _y2) {
                /* スキャンラインが線分の範囲外の時は、無視する */
                continue;
            }
            var x = (y - _y1) * (_x2 - _x1) / (_y2 - _y1) + _x1;
            if(xl == null || xl > x) {
                xl = x;
            }
            if(xr == null || xr < x) {
                xr = x;
            }
        }
        for(x = xl; x < xr; x++) {
            pset(x, y, rgb);
        }
    }
};            

좋은 웹페이지 즐겨찾기