コード例 #1
0
ファイル: spline.cpp プロジェクト: 3dptv/3dptv_streaks
int Spline::Get_new_hnode(Path* path, double r, double f)
{
	//this routine calculates new points laying on the "skeleton line"
	//of the path line by intersecting perpendicular lines to the initial spline
	//with the path line segments

	//calculate the perpendicular line defined by a point p on the spline 
	//and the slope dy/dx at the parameter r
	double dx,dy;
	CamPoint p;

	Get_point(&p, r);
	Get_derivative(r, &dx, &dy);

	//now intersect the path with the line defined by p and (dy,-dx)
	//(the line pependicular to the b-spline) by calculating the 
	//distance between a pixel and the line and
	//convert the line into a form ax+by+c=0 where -m*x - y-m*x_p +y_p = 0
	double a = -dx/dy;
	double b = -1;
	double c = p.y - a*p.x;

	int i_p1,i_p2;
	bool found1=FALSE, found2=FALSE;
	double nenner = sqrt(a*a+b*b);
	//tolerance is the maximal distance between a point of a line and a point of a 
	//path segment so that the line is defined to intersect the boundary of the path
	//segment. sqrt(2)*0.009/f/2.0 is half of the diagonal length of a normalized pixel
	double tolerance=sqrt(2)*0.009/f/2.0;

	//get the relevant segment number
	double j_p;
	modf(r,&j_p);
	double d;
	for(int i=0; i< path->path_seg[(int)j_p].p_nr; i++)
	{
		d= fabs(a*path->path_seg[(int)j_p].hpixel[i].x + b*path->path_seg[(int)j_p].hpixel[i].y + c) / nenner;
		if(d < tolerance && found1)
		{
			i_p2 = i;
			found2=TRUE;
			break;
		}	
		if(d < tolerance && found1 == FALSE)
		{
			i_p1 = i;
			found1=TRUE;
			//go two pixel further because a wrong intersection on the same segment line might be found
			i+=2;
		}
	}
	if(found1 && found2 && i_p1 != i_p2)
	{
		node[m].x = (path->path_seg[(int)j_p].hpixel[i_p1].x + path->path_seg[(int)j_p].hpixel[i_p2].x)/2.0;
		node[m].y = (path->path_seg[(int)j_p].hpixel[i_p1].y + path->path_seg[(int)j_p].hpixel[i_p2].y)/2.0;
		parameter[m]=r;
		m++;
		if(m>=2500)
			return 2;
	}
	return 0;
}
コード例 #2
0
ファイル: spline.cpp プロジェクト: 3dptv/3dptv_streaks
int Spline::Line_intersect(double a, double b, double c, CamPoint *hp, double *r_l, double r_u)
{
	//if a solution (intersection is found) TRUE is returned otherwise FALSE
	//*************************************************************************************
	//***************************Interval sectioning***************************************
	// *r_l is the lower limit and r_u is the upper limit of the intersection 
	// parameter window
	//the routine returns
	//0   if a regular solution was found
	//1   if a solution with a critical intersection angle was found
	//3   if no or a wrong solution was found
	int i=0,solution=1;
	const int max_iter=100;			//the maximal number of iterations
	double aa=*r_l;
	double bb= r_u;
	double cc;
	double res_a,res_b,res_c=1;
	CamPoint p;
	const double angle_tol=0;//3.14159/25

	Get_point(&p, *r_l);
	res_a=a*p.x + b*p.y + c;
	Get_point(&p, r_u);
	res_b=a*p.x + b*p.y + c;

	if(res_a <0 && res_b>0)
	{
		while(fabs(res_c) > 0.00001)
		{
			cc=(aa+bb)/2.0;
			Get_point(&p, cc);
			res_c=a*p.x + b*p.y + c;
			if(res_c<0)
				aa=cc;
			else 
				bb=cc;
			if(++i > max_iter)   //no solution found
			{
				hp->x=-1;
				return 3;
			}
		}
		//check solution
		if(*r_l == cc)
		{
			hp->x=-1;   //wrong solution
			return 3;
		}
		else
		{
			*r_l=cc;
			//get the intersection angle at the parameter *r_l
			//-first calculate dy/dx of the spline
			//angle of the epiline
			double dx=Get_x_derivative(*r_l);
			double dy=Get_y_derivative(*r_l);
			double m_spline=dy/dx;
			double m_epi   =-a/b;
			double gamma=atan(fabs((m_spline-m_epi)/(1+m_spline+m_epi)));
			if(gamma>angle_tol) //if the intersection angle is large enough: regular solution found
			{
				hp->x=p.x;
				hp->y=p.y;
				hp->w=1.0;
				return 0;
			}
			else
			{
				return 1;
			}
		}


	}
	else if(res_a > 0 && res_b < 0) //change
	{
		res_c=res_a;
		res_a=res_b;
		res_b=res_c;

		res_c=1;
		aa=	r_u;
		bb=*r_l;

		while(fabs(res_c) > 0.00001)
		{
			cc=(aa+bb)/2.0;
			Get_point(&p, cc);
			res_c=a*p.x + b*p.y + c;
			if(res_c<0)
				aa=cc;
			else 
				bb=cc;
			if(++i > max_iter)   //no solution found
			{
				hp->x=-1;
				return 3;
			}
		}
		//check solution
		if(*r_l == cc)
		{
			//wrong solution
			hp->x=-1;
			return 3;
		}
		else
		{
			*r_l=cc;

			//get the intersection angle at the parameter *r_l
			//-first calculate dy/dx of the spline
			//angle of the epiline
			double dx=Get_x_derivative(*r_l);
			double dy=Get_y_derivative(*r_l);
			double m_spline=dy/dx;
			double m_epi   =-a/b;
			double gamma=atan(fabs((m_spline-m_epi)/(1+m_spline+m_epi)));
			if(gamma>angle_tol)  //if the intersection angle is large enough: regular solution found
			{
				hp->x=p.x;
				hp->y=p.y;
				hp->w=1.0;
				return 0;
			}
			else
			{
				return 1;
			}
		}
	
	}
	else //there is no or more than one intersection-divide the domain and repeat search
	{
		hp->x=-1;
		return 3;
	}
	return 0;
}
コード例 #3
0
void Polyhedron_demo_convex_hull_plugin::on_actionConvexHull_triggered()
{
  const Scene_interface::Item_id index = scene->mainSelectionIndex();
  
  Scene_polyhedron_item* poly_item = 
    qobject_cast<Scene_polyhedron_item*>(scene->item(index));

  Scene_points_with_normal_item* pts_item =
    qobject_cast<Scene_points_with_normal_item*>(scene->item(index));
  
  Scene_polylines_item* lines_item = 
    qobject_cast<Scene_polylines_item*>(scene->item(index));
  
  Scene_polyhedron_selection_item* selection_item = 
    qobject_cast<Scene_polyhedron_selection_item*>(scene->item(index));

  if(poly_item || pts_item || lines_item || selection_item)
  {
    // wait cursor
    QApplication::setOverrideCursor(Qt::WaitCursor);
    
    QTime time;
    time.start();
    std::cout << "Convex hull...";

    // add convex hull as new polyhedron
    Polyhedron *pConvex_hull = new Polyhedron;
    if(selection_item) {
      CGAL::convex_hull_3(
        boost::make_transform_iterator(selection_item->selected_vertices.begin(), Get_point()),
        boost::make_transform_iterator(selection_item->selected_vertices.end(), Get_point()),
        *pConvex_hull);
    }
    else if ( poly_item ){
      Polyhedron* pMesh = poly_item->polyhedron();  
      CGAL::convex_hull_3(pMesh->points_begin(),pMesh->points_end(),*pConvex_hull);
    }
    else{
      if (pts_item)
        CGAL::convex_hull_3(pts_item->point_set()->begin(),pts_item->point_set()->end(),*pConvex_hull);
      else{
        std::size_t nb_points=0;
        for(std::list<std::vector<Kernel::Point_3> >::const_iterator it = lines_item->polylines.begin();
            it != lines_item->polylines.end();
            ++it)  nb_points+=it->size();

        std::vector<Kernel::Point_3> all_points;
        all_points.reserve( nb_points );

        for(std::list<std::vector<Kernel::Point_3> >::const_iterator it = lines_item->polylines.begin();
            it != lines_item->polylines.end();
            ++it)  std::copy(it->begin(), it->end(),std::back_inserter( all_points ) );
        
        CGAL::convex_hull_3(all_points.begin(),all_points.end(),*pConvex_hull);
      }
    }
    std::cout << "ok (" << time.elapsed() << " ms)" << std::endl;

    Scene_polyhedron_item* new_item = new Scene_polyhedron_item(pConvex_hull);
    new_item->setName(tr("%1 (convex hull)").arg(scene->item(index)->name()));
    new_item->setColor(Qt::magenta);
    new_item->setRenderingMode(FlatPlusEdges);
    scene->addItem(new_item);

    // default cursor
    QApplication::restoreOverrideCursor();
  }
}