2017年3月11日土曜日

3D等高線グラフデータの傾きを補正するHTA

こんなヤツ(↓)を


こんな風(↓)にするために


三角関数を駆使するサンプルを作成しました。

傾き補正の基準点は上下左右の四つ角のみです。四つ角のうち2つ以上が0になるように補正します。

以下ソース
<html>
<title>傾き補正</title>
<body style="text-align:center;overflow:hidden">
<textarea id=ta0 wrap=off style="width:100%;height:42%"></textarea>
<button id=btn style="width:100%;height:16%">↓</button>
<textarea id=ta1 wrap=off style="width:100%;height:42%"></textarea>
</body>
<script>
resizeTo(300,300)
btn.onclick=function(){
var arr2D=ta0.value.split('\r\n')
for0L(arr2D, function(i,str){ arr2D[i] = str.split('\t') })
if(arr2D[arr2D[LEN]-1][LEN]==1){arr2D.pop()}
var arr2D_ = 傾き補正(arr2D)
for0L(arr2D_, function(i,arr){ arr2D_[i] = arr.join('\t') })
ta1.value = arr2D_.join('\r\n')
}
整数化=function(){
var reg=/\.(\d+)/, arr, arrL, obj0
var getObj=function(num){
var str=num+'', obj={元:num, str:str.replace(reg,'$1'), 桁数:arr[arrL++]=RegExp.$1.length}
return obj
}
return function(obj, func){
arr = []
arrL = 0
obj0 = {}
forIn(obj,function(name, v){ obj0[name] = getObj(v) })
var max=Math.max.apply(null, arr), obj1={}
forIn(obj0,function(name, v){
obj1[name] = (v.str + Array(max-v.桁数+1).join(0)) - 0
// 万が一整数化に失敗した場合はどのような値で失敗したのか通知する。
if(0<(''+obj1[name]).indexOf('.')){ alert('整数化失敗\n'+obj1[name]+'\nstr:'+v.str) }
})
return func(obj1) / (1+Array(max+1).join(0))
}
}()
me=function(){return arguments.callee.caller}
傾き補正=function(arr2D){
// 2次元配列内部の左上、右上、左下、右下のうち2箇所以上が0になるように配列全体の値を補正する。
var lenX=arr2D[0][LEN]-1, lenY=arr2D[LEN]-1
var get四つ角=function(arr){ return {LT:arr[0][0], RT:arr[0][lenX], LB:arr[lenY][0], RB:arr[lenY][lenX]} }
var get補正係数=function(v00, v01, v10, v11, 軸max){
var obj
if(Math.abs(v00-v01) < Math.abs(v10-v11)){ obj={v0:v00, v1:v01} }else{ obj={v0:v10, v1:v11} }
obj.rad=Math.atan2(整数化(obj, function(obj){return obj.v0-obj.v1}), 軸max)
obj.min=Math.min(obj.v0,obj.v1)
return obj
}
// X軸
with(get四つ角(arr2D)){var obj係数=get補正係数(RT,LT,RB,LB,lenX), newArr0=[]}
for0L(arr2D, function(Y, arrX){
newArr0[Y] = []
for0L(arrX, function(X, v){
newArr0[Y][X] = 整数化({v:v, min:obj係数.min}, function(o){return o.v - o.min}) - X*Math.tan(obj係数.rad)
})
})
// Y軸
with(get四つ角(newArr0)){var obj係数=get補正係数(RT,RB,LT,LB,lenY), newArr1=[]}
for0L(newArr0, function(Y){newArr1[Y] = []})
for0L(newArr0[0], function(X){
for0L(newArr0, function(Y){
newArr1[Y][X] = 整数化({v:newArr0[Y][X], min:obj係数.min}, function(o){return o.v - o.min}) - Y*Math.tan(-obj係数.rad)
})
})
// 最小値を0にする
var arrMin=[]
for0L(newArr1, function(Y,arrX){ arrMin[Y] = Math.min.apply(null,arrX) })
var min=Math.min.apply(null, arrMin)
for0L(newArr1,function(Y,arrX){
for0L(arrX,function(X,v){
arrX[X] = 整数化({min:min, v:v}, function(o){return o.v-o.min})
})
})
return newArr1
}
LEN='length'
for0L = function(arr,fun){for(var i=0,L=arr[LEN],res;i<L;i++){if(res=fun(i,arr[i])){return res}}}
forIn = function(obj,fun){var name,res; for(name in obj){if(res=fun(name, obj[name])){return res}}}
</script>
</html>



実行画面

上のテキストエリアに補正前の値を貼りつけて「↓」ボタンを押すと下のテキストエリアに補正後の値が表示されます。

0 件のコメント:

コメントを投稿