ロゴ メインコンテンツへ
RSSフィード
「デジタルコンテンツ制作」に関連する記事一覧

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

2016/05/29
(この記事の文字数: 105)
MEL 

昔作った 最小二乗法で頂点等を整列する 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();


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

<<「デジタルコンテンツ制作」の記事一覧に戻る

コメント(0 件)



コンテンツロード: 0.0066 sec
Copyright(C)2006-2024 puarts All Rights Reserved