void LinearAlgebra::QRDecomposition(const Mat2F32 &m, Mat2F32 &Q, Mat2F32 &R){
    Q = LinearAlgebra::orthogonalGramSchmidt(m);
    R.clear();
    R.resize(m.sizeI(),m.sizeJ());


    std::vector<VecF32> v_a(m.sizeI(),VecF32(m.sizeI()));
    for(unsigned int j =0;j<m.sizeJ();j++)
        v_a[j]=m.getCol(j);

    for(unsigned int i =0;i<m.sizeI();i++){
        VecF32 e = Q.getCol(i);
        for(unsigned int j =i;j<m.sizeJ();j++){
            R(i,j)=productInner(e,v_a[j]);
        }
    }
}
Example #2
0
// This routine tries to find the 'grain' of a block by a weighting of dot 
// products relative to all sides.  A few notes:
// 1. It tries to first run wiht a handy-cap to take only street-level roads.
//    It then tries again if the filter is too harsh.
// 2. It does an intentionally bad job when there are a huge number of sides
//    since such high-count polygons aren't sane AGB candidates.
// 3. It ALWAYS returns some answer, no matter how goofy the polygon.
void find_major_axis(vector<block_pt>&	pts,
				Segment2 *			out_segment,
				Vector2 *			out_major,
				Vector2 *			out_minor,
				double *			bounds)
{
	double best_v = -1.0;
	Vector2	temp_a, temp_b;
	double bounds_temp[4];
	
	if(out_major == NULL) out_major = &temp_a;
	if(out_minor == NULL) out_minor = &temp_b;
	if(bounds == NULL) bounds = bounds_temp;

	bool elev_ok = false;
		
	for(int tries = 0; tries < 2; ++tries)
	{	
		
		for(int i = 0; i < pts.size(); ++i)
		if(elev_ok || ground_road_access_for_he(pts[i].orig))
		{
			int j = (i + 1) % pts.size();
			Vector2	v_a(pts[i].loc,pts[j].loc);
			v_a.normalize();
			Vector2 v_b(v_a.perpendicular_ccw());
			
			double total = 0.0;
			int max_k = min(pts.size(),PTS_LIM);
			for(int k = 0; k < max_k; ++k)
			{
				int l = (k + 1) % pts.size();
				Vector2	s(pts[k].loc,pts[l].loc);
				
				total += max(fabs(v_a.dot(s)),fabs(v_b.dot(s)));			
			}
			
			if(total >= best_v)
			{
				best_v = total;
				if(out_segment) *out_segment = Segment2(pts[i].loc,pts[j].loc);
				*out_major = v_a;
				*out_minor = v_b;			
			}	
		}
		
		if(best_v != -1)
			break;
		elev_ok = true;
	}
	
	
	{
		int longest = -1;
		double corr_len = -1;
		for(int i = 0; i < pts.size(); ++i)
		if(/*elev_ok ||*/ ground_road_access_for_he(pts[i].orig))
		{
			int j = (i + 1) % pts.size();
			Vector2 this_side(pts[i].loc,pts[j].loc);
			double len = this_side.normalize();
			double my_corr = fltmax2(fabs(this_side.dot(*out_major)), fabs(this_side.dot(*out_minor)));
			if(my_corr > 0.996194698091746)
			{
				my_corr *= len;
				if(my_corr > corr_len)
				{
					longest = i;
					corr_len = my_corr;
				}			
			}
		}
		if(longest >= 0)
		{
			int i = longest;
			int j = (longest + 1) % pts.size();
			Vector2	v_a(pts[i].loc,pts[j].loc);
			v_a.normalize();
			Vector2 v_b(v_a.perpendicular_ccw());

			if(out_segment) *out_segment = Segment2(pts[i].loc,pts[j].loc);
			*out_major = v_a;
			*out_minor = v_b;			
		}
	}
	
	
	
	
	bounds[2] = bounds[0] = out_major->dot(Vector2(pts[0].loc));
	bounds[3] = bounds[1] = out_minor->dot(Vector2(pts[0].loc));
	for(int n = 1; n < pts.size(); ++n)
	{
		double ca = out_major->dot(Vector2(pts[n].loc));
		double cb = out_minor->dot(Vector2(pts[n].loc));
		bounds[0] = min(bounds[0],ca);
		bounds[1] = min(bounds[1],cb);
		bounds[2] = max(bounds[2],ca);
		bounds[3] = max(bounds[3],cb);
	}
	
//	if(fabs(bounds[3] - bounds[1]) > fabs(bounds[2] - bounds[0]))
//	{
//		*out_major = out_major->perpendicular_ccw();
//		*out_minor = out_minor->perpendicular_ccw();
//
//		bounds[2] = bounds[0] = out_major->dot(Vector2(pts[0].loc));
//		bounds[3] = bounds[1] = out_minor->dot(Vector2(pts[0].loc));
//		for(int n = 1; n < pts.size(); ++n)
//		{
//			double ca = out_major->dot(Vector2(pts[n].loc));
//			double cb = out_minor->dot(Vector2(pts[n].loc));
//			bounds[0] = min(bounds[0],ca);
//			bounds[1] = min(bounds[1],cb);
//			bounds[2] = max(bounds[2],ca);
//			bounds[3] = max(bounds[3],cb);
//		}
//
//	}
}