예제 #1
0
/*
* By using the associative property of the barycenter, we can get the barycenter of 2 triangles as the barrycenter of the barycenters of each triangle;
*/
  PersCamera Triangle::getPersCamParamsBarycentricTwo(cv::Mat equi_image, Vec9f triangle3D1, Vec9f triangle3D2){
  
  EquiTrans equi;
  	//First convert the triangle to get spheric coordinates of vertices
  	
  	//cv::Vec6f triangle1 = triangle2SphericSacht(equi_image.rows, equi_image.cols,1,triangle3D1);
  	cv::Vec6f triangle1 = convToSphericTriangle(triangle3D1);
  	
  	//cv::Vec6f triangle2 = triangle2SphericSacht(equi_image.rows, equi_image.cols,1,triangle3D2);
  	cv::Vec6f triangle2 = convToSphericTriangle(triangle3D2);
  	//Get the 3 Vertices as points 
  	Point2f p1,p2,p3,q1,q2,q3;
  	//Centers for each triangle
  	Point2f center, center1, center2;
  	
  	
  	//First vertice
  	p1.x = triangle1[0];
  	p1.y = triangle1[1];
  	q1.x = triangle2[0];
  	q1.y = triangle2[1];
  	
  	//Second vertice
  	p2.x = triangle1[2];
  	p2.y = triangle1[3];
  	q2.x = triangle2[2];
  	q2.y = triangle2[3];
  	
  	//Third vertice
  	p3.x = triangle1[4];
  	p3.y = triangle1[5];
  	q3.x = triangle2[4];
  	q3.y = triangle2[5];
  	
  	/********************************************************************************/
  	//Horizontal 
  	/*******************************************************************************/
  	
  	// Get the maximum angular difference between the points in terms of theta (horizontal)
  	// in order to make correct viewing direction we have to make sure that the points are all
  	// in correct order and interval. We take the first point as anchor and cheick the angular 		// distance with the other points
  	double t1_thetad1_2, t1_thetad1_3, t1_thetad2_3, t2_thetad1_2, t2_thetad1_3, t2_thetad2_3, t1_max_thetad, t2_max_thetad;
  	t1_thetad1_2 = abs(p2.x - p1.x);
  	t2_thetad1_2 = abs(q2.x - q1.x);
  	
  	t1_thetad1_3 = abs(p3.x - p1.x);
  	t2_thetad1_2 = abs(q2.x - q1.x);
  	
  	t1_thetad2_3 = abs(p3.x - p2.x);
  	t2_thetad2_3 = abs(q3.x - q2.x);
  	
  	t1_max_thetad = max(t1_thetad1_2, max(t1_thetad1_3,t1_thetad2_3));
  	t2_max_thetad = max(t2_thetad1_2, max(t2_thetad1_3,t2_thetad2_3));
  	
  	
  	
  	
  	
  	/***************************************************************************************/
  	//Vertical
  	/**************************************************************************************/
  	//Get the angular phi difference between points
  	double t1_phid1_2, t1_phid1_3, t1_phid2_3, t2_phid1_2, t2_phid1_3, t2_phid2_3, t1_max_phid,t2_max_phid;
  	//Triangle1
  	t1_phid1_2 = abs(p2.y - p1.y);
  	t1_phid1_3 = abs(p3.y - p1.y);
  	t1_phid2_3 = abs(p3.y - p2.y);
  	//t1_max_phid = max(t1_phid1_2, max(t1_phid1_3,t1_phid2_3));
  	
  	//Triangle2
  	t2_phid1_2 = abs(p2.y - p1.y);
  	t2_phid1_3 = abs(p3.y - p1.y);
  	t2_phid2_3 = abs(p3.y - p2.y);
  	//t2_max_phid = max(t2_phid1_2, max(t2_phid1_3,t2_phid2_3));
  	
  	//Make sure there are no loopings in the point angle calculations
  	//If the angle is larger than PI then we have to shift the point to the other side
  	// depending on the sign of p1, we either add or remove 2PI
  	//For first Triangle
  	if(abs(t1_thetad1_2) > M_PI) {
  		p2.y += (p1.y/abs(p1.y))*2*M_PI;
  		triangle1[3] = p2.y;
  	}
  	if(abs(t1_thetad1_3) > M_PI){
  		p3.y += (p1.y/abs(p1.y))*2*M_PI;
  		triangle1[5] = p3.y;
  	}
  	
  	//For Second Triangle
  	if(abs(t2_thetad1_2) > M_PI) {
  		q2.y += (q1.y/abs(q1.y))*2*M_PI;
  		triangle2[3] = q2.y;
  	}
  	if(abs(t2_thetad1_3) > M_PI){
  		q3.y += (q1.y/abs(q1.y))*2*M_PI;
  		triangle2[5] = q3.y;
  	}
  	//Recalculate the new maxes and mins
  	t1_phid1_2 = abs(p2.y - p1.y);
  	t1_phid1_3 = abs(p3.y - p1.y);
  	t1_phid2_3 = abs(p3.y - p2.y);
  	t1_max_phid = max(t1_phid1_2, max(t1_phid1_3,t1_phid2_3));
  	
  	//Triangle2
  	t2_phid1_2 = abs(p2.y - p1.y);
  	t2_phid1_3 = abs(p3.y - p1.y);
  	t2_phid2_3 = abs(p3.y - p2.y);
  	t2_max_phid = max(t2_phid1_2, max(t2_phid1_3,t2_phid2_3));
  	
  	
  	//Get barycenters for each triangle
  	center1 = triangleCenter(triangle1);
  	center2 = triangleCenter(triangle2);
  	
  	//Get the barycenter of the centers
  	center.x = (center1.x + center2.x)/2;
  	center.y = (center1.y + center2.y)/2;
  	
  	//Set Viewing direction as the barycenter of the triangles
  	ViewDirection vd;
  	vd.pan = center.y;
  	vd.tilt = center.x;
  	
  	//Calculate the field of view as the difference between the barycenters to which we add the radius 
  	// of the circumcircles
  	double bary_theta = abs(center1.x - center2.x);
  	double bary_phi = abs(center2.y - center2.y);
  	
  	//Get pan and tilt angles by finding max angle distance and adding to barycenter difference
  	double v_angle, h_angle;
  	h_angle = bary_phi + t1_max_phid + t2_max_phid;
  	v_angle = bary_theta + t1_max_thetad + t2_max_thetad;
  	
  	//Finally make the Perspective camera
  	PersCamera cam;
  	cam.setCamera(equi_image, h_angle, v_angle, vd);

  	return cam;
  }
예제 #2
0
/*
  what is constant:

  variant==CHANGE_RATIO_KEEP_COM_CONSTANT:

  - length of longest edge (WF 030726: Incorrect. The smallest edge of the
    original triangle will be the longest edge of the new triangle. Intended?)
  - center of mass
  - triangle normal

  variant==CHANGE_RATIO_KEEP_LONGEST_EDGE_CONSTANT:

  - length of longest edge
  - vertices adjacent to longest edge
  - triangle normal
*/
int changeRatio(double *ratio, TriangleSet *mesh, int trId, int variant,
                BOOL doNotChange, TinyVector *resultVectors)
{
    double      s, r, a, b, c;
    double      alpha, beta, gamma;
    double      h, p;
    double      lengths[3], dsav;
    TinyVector  v[3];
    int         i, j;
    int         vIds[3], index[3], isav, index2[3];
    TinyVector  n1, n2, sp, com;
    double      scaleFactor;
    double      comX, comY;
    double      rvA[2], rvB[2], rvC[2];
    TinyVector  newVertices[3];
    BOOL        edgeACisShortest;

    normalizeRatios(ratio);

    if(!validTriangleEdgeLengths(ratio[0], ratio[1], ratio[2]))
        return -1;

    a = ratio[0];
    b = ratio[1];
    c = ratio[2];

    // ----------------------------------------------------------
    // Calculate properties of the "ratio triangle".
    // Triangle is supposed lie with A in origin, c on x-axis
    // ----------------------------------------------------------
    /* half of triangle border length */
    s = (a + b + c) / 2;

    /* radius of inner circle */
    r = sqrt(((s - a) * (s - b) * (s - c)) / s);

    /* angles */
    alpha = 2 * atan(r / (s - a));
    beta = 2 * atan(r / (s - b));
    gamma = 2 * atan(r / (s - c));

    h = sin(alpha) * b;
    p = cos(alpha) * b;

    /* Retrieve vertices of triangle to be changed */
    for(i = 0; i < 3; i++)
    {
        vIds[i] = mesh->getTriangleVertex(trId, i);
        v[i] = mesh->getVertex(vIds[i]);
    }

    // Original edge lengths
    lengths[0] = tv_abs(v[0] - v[1]);
    lengths[1] = tv_abs(v[1] - v[2]);
    lengths[2] = tv_abs(v[2] - v[0]);

    for(i = 0; i < 3; i++)
        index[i] = i;

    // Sort original edge lenghts in ascending order
    for(i = 0; i < 2; i++)
    {
        for(j = i + 1; j < 3; j++)
        {
            if(lengths[i] > lengths[j])
            {
                dsav = lengths[i];
                lengths[i] = lengths[j];
                lengths[j] = dsav;
                isav = index[i];
                index[i] = index[j];
                index[j] = isav;
            }
        }
    }

    /*
    For constructing the new start triangle from the ratio triangle,
    sort vertices so that edge from first to second (c) is longest,
    second to third (a) is shortest edge.
    This configuration matches the ratio triple configuration.
    a < b < c (e.g. 1:1.5:2).
    */
    if((index[2] == 1) && (index[0] == 0))
    {
        /* 2->1->0 */
        index2[0] = 2;
        index2[1] = 1;
        index2[2] = 0;
    }
    else if((index[2] == 0) && (index[0] == 1))
    {
        /* 0->1->2 */
        index2[0] = 0;
        index2[1] = 1;
        index2[2] = 2;
    }
    else if((index[2] == 1) && (index[0] == 2))
    {
        /* 1->2->0 */
        index2[0] = 1;
        index2[1] = 2;
        index2[2] = 0;
    }
    else if((index[2] == 2) && (index[0] == 1))
    {
        /* 0->2->1 */
        index2[0] = 0;
        index2[1] = 2;
        index2[2] = 1;
    }
    else if((index[2] == 0) && (index[0] == 2))
    {
        /* 1->0->2 */
        index2[0] = 1;
        index2[1] = 0;
        index2[2] = 2;
    }
    else if((index[2] == 2) && (index[0] == 0))
    {
        /* 2->0->1 */
        index2[0] = 2;
        index2[1] = 0;
        index2[2] = 1;
    }

    n1 = v[index2[1]] - v[index2[0]];

    lotPointLine(v[index2[2]], v[index2[1]], v[index2[0]] - v[index2[1]], &sp);
    n2 = v[index2[2]] - sp;

    n1.normalize();
    n2.normalize();

    // WF 030801: Largest edge length value and maximum of ratio.
    // This means the longest edge of the original triangle
    // will be the longest edge of the new triangle.
    scaleFactor = lengths[index[2]] / ratio[2];

    //scaleFactor=lengths[index[0]] / ratio[2]; // maintains smallest edge of original.
    //scaleFactor=lengths[index[0]];
    if(variant == CHANGE_RATIO_KEEP_COM_CONSTANT)
    {
        /* calculate center of mass of "ratio-triangle" */
        comX = (c + p) / 3;
        comY = h / 3;

        /* center of mass of real triangle remains the same */
        /* PRECONDITION:
        edge AB (aka edge c) must be longest, BC (aka edge a) shortest !! */
        /* c is longest,a shortest */
        rvA[0] = -comX;
        rvA[1] = -comY;

        rvB[0] = c - comX;
        rvB[1] = -comY;

        rvC[0] = p - comX;
        rvC[1] = h - comY;

        com = triangleCenter(trId, mesh);

        /* New vertices A,B,C */
        newVertices[0] = com +
                         n1 *
                         scaleFactor *
                         rvA[0] +
                         n2 *
                         scaleFactor *
                         rvA[1];
        newVertices[1] = com +
                         n1 *
                         scaleFactor *
                         rvB[0] +
                         n2 *
                         scaleFactor *
                         rvB[1];
        newVertices[2] = com +
                         n1 *
                         scaleFactor *
                         rvC[0] +
                         n2 *
                         scaleFactor *
                         rvC[1];

        /* replace vertices in mesh with new ones */
        for(i = 0; i < 3; i++)
        {
            if(!doNotChange)
            {
                mesh->setVertex(vIds[index2[i]], newVertices[i]);
            }
        }

        for(i = 0; i < 3; i++)
        {
            resultVectors[index2[i]] = newVertices[i];
        }
    }                   /* CHANGE_RATIO_KEEP_COM_CONSTANT */
    else if(variant == CHANGE_RATIO_KEEP_LONGEST_EDGE_CONSTANT)
    {
        com = triangleCenter(trId, mesh);

        newVertices[2] = v[index2[0]] +
                         n1 *
                         p *
                         scaleFactor +
                         n2 *
                         h *
                         scaleFactor;

        if(!doNotChange)
        {
            mesh->setVertex(vIds[index2[2]], newVertices[2]);
        }

        resultVectors[index2[2]] = newVertices[2];
        for(i = 0; i < 2; i++)
            resultVectors[i] = v[index2[i]];
    }                   /* CHANGE_RATIO_KEEP_LONGEST_EDGE_CONSTANT */
    else
        return -1;

    com = triangleCenter(trId, mesh);

    triangleEdgeLengths(trId, mesh, lengths);

    double  lengthsNew[3];
    lengthsNew[0] = tv_abs(resultVectors[0] - resultVectors[1]);
    lengthsNew[1] = tv_abs(resultVectors[1] - resultVectors[2]);
    lengthsNew[2] = tv_abs(resultVectors[2] - resultVectors[0]);

    TinyVector  newCom = triangleCenter(resultVectors[0], resultVectors[1],
                                        resultVectors[2]);

    return 0;
}
예제 #3
0
   /*
 * Get the perpective camera that includes a triangle by using the barycenter as point and the 
 * radius of the circumcircle
 */
  PersCamera Triangle::getPersCamParamsBarycentric(cv::Mat equi_image, Vec9f vertices){
  
  	EquiTrans equi;
  	//First convert the triangle to get spheric coordinates of vertices
  	//cv::Vec6f triangle = triangle2SphericSacht(equi_image.rows, equi_image.cols,1,vertices);
  	cv::Vec6f triangle = convToSphericTriangle(vertices);
  	//Get the 3 Vertices as points in 3D then convert to angular position
  	//Point3f p3d1,p3d2,p3d3;
  	
  	
  	Point2f p1,p2,p3;
  	

  	
  	//First vertice
  	//p3d1.x = triangle[0];
  	//p3d1.y = triangle[1];
  	//p3d1.z = triangle[2];
  	
  	//Second vertice
  	//p3d2.x = triangle[3];
  	//p3d2.y = triangle[4];
  	//p3d2.z = triangle[5];
  	
  	//Theturn cam;ird vertice
  	//p3d3.x = triangle[6];
  	//p3d3.y = triangle[7];
  	//p3d3.z = triangle[8];
  	
  	//double x=0.0,y=0.0;
  	//equi.convSpherePointToAngles(p3d1, &x,&y);
  	
  	///equi.convSpherePointToAngles(p3d2, &x,&y);
  	//p2.x = x;
  	//p2.y = y;
  	
  	//equi.convSpherePointToAngles(p3d3, &x,&y);
  	//p3.x = x;
  	//p3.y = y;
  	
  	p1.x = triangle[0];
  	p1.y = triangle[1];
  	p2.x = triangle[2];
  	p2.y = triangle[3];
  	p3.x = triangle[4];
  	p3.y = triangle[5];
  	
  	// Horizontal
  	// Get the maximum angular difference between the points in terms of theta (horizontal)
  	// in order to make correct viewing direction we have to make sure that the points are all
  	// in correct order and interval. We take the first point as anchor and cheick the angular 		// distance with the other points
  	double thetad1_2, thetad1_3, thetad2_3, max_thetad;
  	thetad1_2 = abs(p2.x - p1.x);
  	thetad1_3 = abs(p3.x - p1.x);
  	thetad2_3 = abs(p3.x - p2.x);
  	max_thetad = max(thetad1_2, max(thetad1_3,thetad2_3));
  	
  	
  	
  	
  	//Get the angular phi difference between points
  	double phid1_2, phid1_3, phid2_3, max_phid;
  	phid1_2 = abs(p2.y - p1.y);
  	phid1_3 = abs(p3.y - p1.y);
  	phid2_3 = abs(p3.y - p2.y);
  	//max_phid = max(phid1_2, max(phid1_3,phid2_3));
  	
  	//If the angle is larger than PI then we have to shift the point to the other side
  	// depending on the sign of p1, we either add or remove 2PI
  	if(abs(thetad1_2) > M_PI) {
  		p2.y += (p1.y/abs(p1.y))*2*M_PI;
  		triangle[3] = p2.y;
  	}
  	if(abs(thetad1_3) > M_PI){
  		p3.y += (p1.y/abs(p1.y))*2*M_PI;
  		triangle[5] = p3.y;
  	}
  	
  	//Recalculate the angular phi difference between points
  	phid1_2 = abs(p2.y - p1.y);
  	phid1_3 = abs(p3.y - p1.y);
  	phid2_3 = abs(p3.y - p2.y);
  	max_phid = max(phid1_2, max(phid1_3,phid2_3));
  	
  	//Get the barycenter
  	cv::Point2f center = triangleCenter(triangle);
  	
  	//Get pan and tilt angles by finding max angle distance
  	double v_angle, h_angle;
  	h_angle = max_phid;
  	v_angle = max_thetad;
  	cout << "getPersCamParamsBarycentric: Cam image: (" << h_angle << "," << v_angle << ")" << endl;
  	//Set Viewing direction as the barycenter of the triangle
  	ViewDirection vd;
  	vd.pan = center.y;
  	vd.tilt = center.x;
  	//vd.pan = 0.164793;
  	//vd.tilt = -0.276993;
  	cout << "getPersCamParamsBarycentric: Viewing Direction: (" << vd.pan << "," << vd.tilt << ")" << endl;
  	//Finally make the Perspective camera
  	PersCamera cam;
  	
  	if(h_angle!=h_angle || v_angle!=v_angle){
  		h_angle = v_angle = 0;
  	}
  	else{
  		cam.setCamera(equi_image, h_angle, v_angle, vd);
	}
  	return cam;
  	
  }