0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

2.3. 3角形面を描く

Last updated at Posted at 2015-12-15

3Dの基本的な知識を理解したくて、『3次元CGの基礎と応用[新訂版]( http://goo.gl/GKoQ4y )』という書籍を購入しました。薄くて読みやすそうな本なのですがサンプルソースがないので、勉強がてらサンプルを作りながら読み進めようと思います。誰でもすぐに追試ができるよう、HTML + Javascriptでサンプルを作っていきます。

完全なサンプルはこちら
https://github.com/nakaken0629/3dstudy

2.3. 3角形面を描く

一番基本的なポリゴンである3角形面を、2.1.で使った点を描く処理を使って描く処理です。2.2.で使ったブレゼンハムのアルゴリズムを使う方法もあるのですが、それはそれなりに後で置き換えられるだろうということで、今回は実数が出てくる割り算を使った素朴な処理で実装しています。実数が絡む誤差のせいか、描画されたポリゴンは少し透明な場所も出ています。

session2_3.png

サンプルコード

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);
        }
    }
};            
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?