MEL 最小二乗法を用いた頂点群の1次関数直線への整列スクリプトの改良 | puarts.com
映像・CG・画像処理関連の技術情報、個人作品の創作記録、メモなど
Category

MEL 最小二乗法を用いた頂点群の1次関数直線への整列スクリプトの改良

公開日: 2016/05/29 | カテゴリ: Maya | タグ:

昔作った 最小二乗法で頂点等を整列する MEL スクリプト が使いづらかったので改良しました。

具体的には、以前は引数で整頓する軸を指定しなければいけなかったんですが、軸を自動で選ぶように改良しました。

ソースコード

global proc int[] findAxisesSortedByDispersion(string $targets[])
{
    float $sums[3] = {0.0, 0.0, 0.0};
    float $n = size($targets);
    for($target in $targets)
    {
        float $pos[] = `xform -q -ws -t $target`;
        $sums[0] += $pos[0];
        $sums[1] += $pos[1];
        $sums[2] += $pos[2];
    }
    
    float $averages[3] = {$sums[0] / $n, $sums[1] / $n, $sums[2] / $n};
    float $dispersions[3] = {0.0, 0.0, 0.0};
    for($target in $targets)
    {
        float $pos[] = `xform -q -ws -t $target`;
        $dispersions[0] += abs($pos[0] - $averages[0]);
        $dispersions[1] += abs($pos[1] - $averages[1]);
        $dispersions[2] += abs($pos[2] - $averages[2]);
    }
    
    float $sorted_dispersions[] = `sort $dispersions`;
    int $max_axises[3] = {0, 0, 0};
    int $axis = 0;
    for ($axis = 0; $axis < 3; ++$axis)
    {
        if ($sorted_dispersions[2] == $dispersions[$axis])
        {
            $max_axises[0] = $axis;
        }
        if ($sorted_dispersions[1] == $dispersions[$axis])
        {
            $max_axises[1] = $axis;
        }
        if ($sorted_dispersions[0] == $dispersions[$axis])
        {
            $max_axises[2] = $axis;
        }
    }
    return $max_axises;
}

global proc alignToMinimumDispersionLine(string $targets[], int $axis_x, int $axis_y)
{
    float $n = size($targets);
    float $a, $b;
    float $y, $pos[];
    float $sum_x, $sum_y, $sum_xy, $sum_xx;

    $sum_x = $sum_y = $sum_xy = $sum_xx = 0.0;
    for($target in $targets)
    {
        $pos = `xform -q -ws -t $target`;
        $sum_x += $pos[$axis_x];
        $sum_y += $pos[$axis_y];
        $sum_xy += $pos[$axis_x]*$pos[$axis_y];
        $sum_xx += $pos[$axis_x]*$pos[$axis_x];
    }

    $slope = ($n*$sum_xy-$sum_x*$sum_y) / ($n*$sum_xx - $sum_x*$sum_x);
    $offset = ($sum_xx*$sum_y-$sum_xy*$sum_x) / ($n*$sum_xx - $sum_x*$sum_x);

    for($target in $targets)
    {
        $pos = `xform -q -ws -t $target`;
        $pos[$axis_y] = $slope * $pos[$axis_x] + $offset;
        xform -ws -t $pos[0] $pos[1] $pos[2] $target;
    }
}

global proc alignSelectedToMinimumDispersionLine2d()
{
    string $sels[] = `ls -sl`;
    string $targets[] = `filterExpand -sm 31 $sels`;
    int $target_axises[] = findAxisesSortedByDispersion($targets);
    alignToMinimumDispersionLine($targets, $target_axises[0], $target_axises[2]);
}

global proc alignSelectedToMinimumDispersionLine1d()
{
    string $sels[] = `ls -sl`;
    string $targets[] = `filterExpand -sm 31 $sels`;
    int $target_axises[] = findAxisesSortedByDispersion($targets);
    alignToMinimumDispersionLine($targets, $target_axises[0], $target_axises[1]);
}

使用例

// 2次元平面に整列
alignSelectedToMinimumDispersionLine2d();

// 1本の線に整列
alignSelectedToMinimumDispersionLine1d();

  このエントリーをはてなブックマークに追加  


にほんブログ村 デザインブログ グラフィックアートへ
Links

参考になりそうなブログやサイトを見つけたら勝手にリンクを貼らせてもらっています。
リンク削除を希望の場合はお手数ですがメールにてご一報下さい。
Ke-Sen Huang's Home Page        Disney Research        VIDEO COPILOT        AbandonedArt.org
ryoji ikeda        チームラボ        トルク with AR三兄弟        DAITO MANABE

Copyright(C)2006-2017 wsp All Rights Reserved