/**********************************************************************
 
	Copyright (C) 2003 Hirohisa MORI <joshua@nichibun.ac.jp>
 
	This program is free software; you can redistribute it 
	and/or modify it under the terms of the GLOBALBASE 
	Library General Public License (G-LGPL) as published by 

	http://www.globalbase.org/
 
	This program is distributed in the hope that it will be 
	useful, but WITHOUT ANY WARRANTY; without even the 
	implied warranty of MERCHANTABILITY or FITNESS FOR A 
	PARTICULAR PURPOSE.

**********************************************************************/



#include	"u_math.h"
#include	"gbgraph.h"
#include	"viewindex.h"


void
wf_rotate_matrix(
	AFFEN2D * inv_a,
	GB_POINT from,
	GB_POINT to,
	int width,
	int height)
{
REAL1 A,B;
double d;
GB_POINT center;

	center.x = width/2;
	center.y = height/2;
	from = p_sub(from,center);
	to = p_sub(to,center);
	d = sqrt(inner(from,from) * inner(to,to));
	A = inner(from,to)/d;
	B = (to.x * from.y - from.x * to.y)/d;
	inv_a->matrix[0][0] = A;
	inv_a->matrix[0][1] = -B;
	inv_a->matrix[1][0] = B;
	inv_a->matrix[1][1] = A;

	inv_a->org = p_sub(center,mp_mul(inv_a->matrix,center));

}


void
wf_make_rotate_index(
	VPOINT * index,
	GB_POINT from,
	GB_POINT to,
	int width,
	int height)
{
AFFEN2D a;
int x,y,xx,yy;
GB_POINT p,q;
VPOINT vp;
	wf_rotate_matrix(&a,from,to,width,height);
	for ( y = 0 ; y < height ; y ++ )
		for ( x = 0 ; x < width ; x ++ ) {
			p.x = x;
			p.y = y;
			q = caffen2d(&a,p);
			xx = rint(q.x);
			yy = rint(q.y);
			if ( xx < 0 )
				goto out;
			if ( yy < 0 )
				goto out;
			if ( xx >= width )
				goto out;
			if ( yy >= height )
				goto out;
			vp.x = xx;
			vp.y = yy;
			*index ++ = vp;
			continue;
		out:
			vp.x = vp.y = -1;
			*index ++ = vp;
			continue;
		}
}


void
wf_make_zoom_index(int * index_x,int * index_y,REAL1 zoom,int w,int h)
{
double inv_a;
int h2,w2,i;
int xx,yy,t;
unsigned long b;

	inv_a = 1/zoom;
	h2 = h/2;
	w2 = w/2;
	for ( xx = 0 ; xx < w ; xx ++ ) {
		t = rint(inv_a*(xx-w2) + w2);
		if ( t < 0 || t >= w )
			t = -1;
		index_x[xx] = t;
	}
	for ( yy = 0 ; yy < h ; yy ++ ) {
		t = rint(inv_a*(yy-h2) + h2);
		if ( t < 0 || t >= h )
			t = -1;
		index_y[yy] = t;
	}
}
