コード例 #1
0
// Adjust if the point lies in the triangle abc
REAL InTriangle(MESH * pMesh, VERTEX2D * pVer, TRIANGLE * pTri)
{
	int vertex_index;
	VERTEX2D * pV1, *pV2, *pV3;

	vertex_index =pTri->i1;
	pV1 = (VERTEX2D *)(pMesh->pVerArr+vertex_index);
	vertex_index =pTri->i2;
	pV2 = (VERTEX2D *)(pMesh->pVerArr+vertex_index);
	vertex_index =pTri->i3;
	pV3 = (VERTEX2D *)(pMesh->pVerArr+vertex_index);

	REAL ccw1 = CounterClockWise(pV1, pV2, pVer);
	REAL ccw2 = CounterClockWise(pV2, pV3, pVer);
	REAL ccw3 = CounterClockWise(pV3, pV1, pVer);

	REAL r = -1;
	if (ccw1>0 && ccw2>0 && ccw3>0)
	{
		r = 1;
	}
	else if(ccw1*ccw2*ccw3 == 0 && (ccw1*ccw2 > 0 || ccw1*ccw3 > 0 || ccw2*ccw3 > 0) )
	{
		r = 0;
	}

	return r;
}
コード例 #2
0
bool IncrementalBlueNoise::InTriangle(Edge* edge, Node2d * target_node, int &mode)
{

//	Node2d* new_node = target_node;
	Node2d* n1 = edge->getSourceNode();
	Edge* e1 = edge;

	Edge* e2 = edge->getNextEdgeInFace();
	Node2d* n2 = e2->getSourceNode();

	Edge* e3 = e2->getNextEdgeInFace();
	Node2d* n3 = e3->getSourceNode();

	real ccw1 = CounterClockWise(n1, n2, target_node); // 如果target_node 在 1 2 的 右侧  则 顺时针, 负值
	real ccw2 = CounterClockWise(n2, n3, target_node); // 如果target_node 在 2 3 的 左侧  则 逆时针, 正值
	real ccw3 = CounterClockWise(n3, n1, target_node); 

	if (ccw1 > 0 && ccw2 > 0 && ccw3 > 0) 
	{
		mode = 0;
		return true;
	}
	else if (ccw1*ccw2*ccw3 == 0)
	{
		if (ccw2*ccw3 > 0)
			mode = 1;
		else if (ccw1*ccw3 > 0)
			mode = 2;
		else if (ccw1*ccw2 > 0)
			mode = 3;
		return true;
	}
	mode = -1;
	return false;
}
コード例 #3
0
// Create a new node and add it into triangle list
TRIANGLE * AddTriangleNode(MESH * pMesh, TRIANGLE * pPrevTri, int i1, int i2, int i3)
{
	// test if 3 vertices are co-linear
	if(CounterClockWise((VERTEX2D *)(pMesh->pVerArr+i1), (VERTEX2D *)(pMesh->pVerArr+i2), (VERTEX2D *)(pMesh->pVerArr+i3)) == 0)
	{
		return NULL;
	}

	// allocate memory
	TRIANGLE * pNewTestTri = (TRIANGLE *)malloc(sizeof(TRIANGLE));

	pNewTestTri->i1 = i1;
	pNewTestTri->i2 = i2;
	pNewTestTri->i3 = i3;

	// insert after prev triangle
	if (pPrevTri == NULL) // add root
	{
		pMesh->pTriArr = pNewTestTri;
		pNewTestTri->pNext = NULL;
		pNewTestTri->pPrev = NULL;
	}
	else
	{
		pNewTestTri->pNext = pPrevTri->pNext;
		pNewTestTri->pPrev = pPrevTri;

		if(pPrevTri->pNext != NULL)
		{
			pPrevTri->pNext->pPrev = pNewTestTri;
		}

		pPrevTri->pNext = pNewTestTri;
	}
	
	return pNewTestTri;
}
コード例 #4
0
	/*
	Reconstruct triangulation from indexed set of triangles.
	*/
	Triangulator::Triangulator(const vector<CParticleF>& pnts, const vector<_Internal::_indexed_triangle>& faces)
	{
		for(int i=0; i<pnts.size(); ++i)
		{
			points.push_back(new _Internal::_vertex(pnts[i]));
		}
		for(int i=0; i<faces.size(); ++i)
		{
			_Internal::_vertex* p[3];
			for(int j=0; j<3; ++j)
			{
				p[j] = points[faces[i].index[j]];
			}
			float ccw = CounterClockWise(p[0]->p, p[1]->p, p[2]->p);
			if(ccw > 0)
			{
				//arrange them in clockwise orientation
				swap(p[0], p[2]);
			}
			_Internal::_edge* e[3];
			for(int j=0; j<3; ++j)
			{
				_Internal::_vertex* u = p[j];
				_Internal::_vertex* v = p[(j+1)%3];
				e[j] = new _Internal::_edge(u, v);
				vector<_Internal::_edge*>::iterator it = find_if(edges.begin(), edges.end(), _Internal::_edge_equal(e[j]));
				if(it==edges.end())
				{
					edges.push_back(e[j]);
				}
				else
				{
					delete e[j];
					e[j] = *it;
				}
				u->AddEdge(e[j]);
				v->AddEdge(e[j]);
			}
			_Internal::_triangle* tr = new _Internal::_triangle(e[0], e[1], e[2], p[0], p[1], p[2]);
			this->faces.push_back(tr);
			for(int j=0; j<3; ++j)
			{
				e[j]->AddFace(tr);
			}
		}
		for(int i=0; i<edges.size(); ++i)
		{
			if(edges[i]->faces[0]==NULL && edges[i]->faces[1]==NULL)
			{
				edges[i]->type = _Internal::Isolated;
			}
			else if(edges[i]->faces[0]!=NULL && edges[i]->faces[1]!=NULL)
			{
				edges[i]->type = _Internal::Inside;
			}
			else 
			{
				edges[i]->type = _Internal::Boundary;
				//we do not consider Hole for now...
			}
		}
	}
コード例 #5
0
int trichro_back_buffer(int xchroma, int ychroma, int rayon, int largeurchroma)//calcul et couleurs dans les 10eme de sec.
{
clear_bitmap(bmp_buffer_trichro);
int coord[4];
for (hcl=0.0; hcl<360.0; hcl+=0.4)
{
     xcl = cos(hcl*PI/180.0)*(rayon+16);
	 ycl = sin(hcl*PI/180.0)*(rayon+16);

	 hsv_to_rgb(hcl, 1.0, 1.0, &rcl, &gcl, &bcl);

	 coord[0]=xchroma;
     coord[1]=ychroma;
     coord[2]=(int)(xchroma+xcl);
     coord[3]=(int)(ychroma+ycl);
//	 Line(Vec2D(xchroma,ychroma),Vec2D(xchroma+xcl,ychroma+ycl)).Draw(Rgba(rcl,gcl,bcl));
 polygon(bmp_buffer_trichro, 2, coord, makecol(rcl,gcl,bcl));
}

//Circle MasqueNoir(Vec2D(xchroma,ychroma),rayon-16);
//MasqueNoir.Draw(CouleurFond);
circlefill(bmp_buffer_trichro,  xchroma,ychroma, rayon-16, makecol(0,0,0));

for(angle = 0 ; angle <(PI*360) / 180  ; angle+=0.1)//radians
{
   vx = cos(angle)*rayon;
   vy = sin(angle)*rayon;
   if(mouse_x>xtrichro_window+vx-16  && mouse_x< xtrichro_window+vx+16 && mouse_y>ytrichro_window+vy-16 && mouse_y<ytrichro_window+vy+16
      && mouse_button==1 && window_focus_id==902)

   {

   angle_snap=angle;//angle rotation roue couleur
   position_curseur_hue_x= xtrichro_window+vx;//affichage
   position_curseur_hue_y=ytrichro_window+vy ;//affichage
   cref=getpixel(bmp_buffer_trichro,(int)(xchroma+vx),(int)(ychroma+vy));
    r_pick=getr(cref);
    v_pick=getg(cref);
    b_pick=getb(cref);

   stock_etat_picker_dans_dockcolor(dock_color_selected);
   do_colors();//ventilation des niveaux pickés ainsi que distrib dans faders et docks
    midi_levels[497]=(int)(angle_snap/((PI*360) / (180*127)));
    if(midi_send_out[497]==1){index_send_midi_out[497]=1;}
    index_snap_color_wheel_levels=1;
    mouse_released=1;
   }

}


//attaque midi
if (miditable[0][497]==istyp && miditable[1][497]==ischan && miditable[2][497]==ispitch)
{
  angle_snap=((PI*360) / (180*127))*midi_levels[497];
  vx = cos(angle_snap)*125;
  vy = sin(angle_snap)*125;
  position_curseur_hue_x= xtrichro_window+vx;
  position_curseur_hue_y=ytrichro_window+vy ;
  cref=getpixel(bmp_buffer_trichro,(int)(xchroma+vx),(int)(ychroma+vy));
  r_pick=getr(cref);
  v_pick=getg(cref);
  b_pick=getb(cref);
  stock_etat_picker_dans_dockcolor(dock_color_selected);
  do_colors();//ventilation des niveaux pickés ainsi que distrib dans faders et docks
  if (midi_levels[497]!=previous_trichro_wheel)
  {
      index_snap_color_wheel_levels=1;
      previous_trichro_wheel=midi_levels[497];
  }
}
//triangle
	V3D_f v1 =
	{
		xchroma+vxd, ychroma+vyd, 0,
		0., 0.,
		makecol(0, 0, 0) // black vertex
	};
	V3D_f v2 =
	{
		xchroma+vxw, ychroma+vyw, 0,
		0., 0.,
		makecol(255, 255, 255) // white vertex
	};
	V3D_f v3 =
	{
		xchroma+vxh, ychroma+vyh, 0,
		0., 0.,
		makecol(r_pick, v_pick, b_pick) // color vertex
	};


	triangle3d_f(bmp_buffer_trichro, POLYTYPE_GCOL, NULL, &v1, &v2, &v3);


//definir si on est dans l aire du triangle
//(angle (Pa-1 Pa-2) * angle (Pa-2 Pa-3) * angle (Pa-3 Pa-1)) resultat pos ou neg
float angle1, angle2,angle3;
angle1=CounterClockWise(mouse_x,mouse_y,xtrichro_window+vxd, ytrichro_window+vyd,xtrichro_window+vxh, ytrichro_window+vyh) ; //Pa1-Pa2
angle2=CounterClockWise(mouse_x,mouse_y,xtrichro_window+vxh, ytrichro_window+vyh,xtrichro_window+vxw, ytrichro_window+vyw);//Pa2 - Pa3
angle3=CounterClockWise(mouse_x,mouse_y,xtrichro_window+vxw, ytrichro_window+vyw, xtrichro_window+vxd, ytrichro_window+vyd);//Pa3-Pa1

if((angle1*angle2*angle3) <=0 ) //dans le triangle formé par la souris et les 3 points du triangle
{


if(mouse_b&1 && mouse_x>xtrichro_window+vxd && mouse_x<xtrichro_window+vxw && mouse_y>ytrichro_window+vyd && mouse_y<ytrichro_window+vyh && window_focus_id==902)
{
picker_x=mouse_x-xtrichro_window;
picker_y=mouse_y-ytrichro_window;
stock_etat_picker_dans_dockcolor(dock_color_selected);
do_colors();//ventilation des niveaux pickés ainsi que distrib dans faders et docks
index_snap_color_wheel_levels=1;
}

}


if(   index_snap_color_wheel_levels==1)//take measurement on mouse or midi
{
if(getpixel(bmp_buffer_trichro,(int)(xchroma+picker_x),(int)(ychroma+picker_y))!=0)
{colorpicker=getpixel(bmp_buffer_trichro,(int)(xchroma+picker_x),(int)(ychroma+picker_y));}

my_red=getr(colorpicker);
my_green=getg(colorpicker);
my_blue=getb(colorpicker);

if (index_quadri==1)
{
   float hue, saturation, value;
   rgb_to_hsv(my_red, my_green, my_blue, &hue, &saturation, &value);
   //saturation: plus il y en a , moins de jaune il y a
   my_yellow=(int)(255-(255*saturation));
}
do_colors();//ventilation des niveaux pickés ainsi que distrib dans faders et docks
index_snap_color_wheel_levels=0;
}
return(0);
}
コード例 #6
0
bool FlipTest(MESH * pMesh, TRIANGLE * pTestTri)
{
	bool flipped = false;

	int index_a = pTestTri->i1;
	int index_b = pTestTri->i2;
	int index_p = pTestTri->i3;

	int statify[3]={0,0,0};
	int vertex_index;
	int* pi;
	int k = 1;

	// find the triangle which has edge consists of start and end
	TRIANGLE * pTri = pMesh->pTriArr;

	int index_d = -1;
	while (pTri != NULL)
	{
		statify[0] = 0;
		statify[1] = 0;
		statify[2] = 0;

		pi = &(pTri->i1);
		for (int j=0, k = 1; j<3; j++, k*= 2)
		{
			vertex_index = *pi++;
			if(vertex_index == index_a || vertex_index == index_b)
			{
				statify[j] = k;
			}
		}

		switch(statify[0] | statify[1] | statify[2] )
		{
			case 3:
				if(CounterClockWise((VERTEX2D *)(pMesh->pVerArr+index_a), (VERTEX2D *)(pMesh->pVerArr+index_b), (VERTEX2D *)(pMesh->pVerArr+pTri->i3)) < 0)
				{
					index_d = pTri->i3;
				}
				
				break;
			case 5:
				if(CounterClockWise((VERTEX2D *)(pMesh->pVerArr+index_a), (VERTEX2D *)(pMesh->pVerArr+index_b), (VERTEX2D *)(pMesh->pVerArr+pTri->i2)) < 0)
				{
					index_d = pTri->i2;
				}
				
				break;
			case 6: 
				if(CounterClockWise((VERTEX2D *)(pMesh->pVerArr+index_a), (VERTEX2D *)(pMesh->pVerArr+index_b), (VERTEX2D *)(pMesh->pVerArr+pTri->i1)) < 0)
				{
					index_d = pTri->i1;
				}

				break;

			default:
				break;
		}

		if (index_d != -1)
		{
			VERTEX2D * pa = (VERTEX2D *)(pMesh->pVerArr+index_a);
			VERTEX2D * pb = (VERTEX2D *)(pMesh->pVerArr+index_b);
			VERTEX2D * pd = (VERTEX2D *)(pMesh->pVerArr+index_d);
			VERTEX2D * pp = (VERTEX2D *)(pMesh->pVerArr+index_p);
			
			if(InCircle( pa, pb, pp, pd) < 0) // not local Delaunay
			{
				flipped = true;

				// add new triangle adp,  dbp, remove abp, abd.
				// allocate memory for adp
				TRIANGLE * pT1 = AddTriangleNode(pMesh, pTestTri, pTestTri->i1, index_d, pTestTri->i3);				
				// allocate memory for dbp
				TRIANGLE * pT2 = AddTriangleNode(pMesh, pT1, index_d, pTestTri->i2, index_p);				
				// remove abp
				RemoveTriangleNode(pMesh, pTestTri);
				// remove abd
				RemoveTriangleNode(pMesh, pTri);

				FlipTest(pMesh, pT1); // pNewTestTri satisfies CCW order
				FlipTest(pMesh, pT2); // pNewTestTri2  satisfies CCW order

				break;
			}			
		}

		// go to next item	
		pTri = pTri->pNext;
	}

	return flipped;
}
	Triangulator::Triangulator(const vector<CParticleF>& pnts)
	{
		for(int i=0; i<pnts.size(); ++i)
		{
			points.push_back(new _Internal::_vertex(pnts[i]));
		}

		vector<TriangulateBourke::Triplet> delaunayTriangles = TriangulateBourke::DelaunayTriangulation(pnts);
		/*if(tripletSanityCheck(delaunayTriangles, pnts.size()) > 0)
		{
			int i=0;
		}*/
		for(int i=0; i<delaunayTriangles.size(); i++)
		{
			int xk = delaunayTriangles[i].index[0];
			int yk = delaunayTriangles[i].index[1];
			int zk = delaunayTriangles[i].index[2];
			assert(xk>=0 && xk<pnts.size() && yk>=0 && yk<pnts.size() && zk>=0 && zk<pnts.size());
			CParticleF x = pnts[xk];
			CParticleF y = pnts[yk];
			CParticleF z = pnts[zk];

			float ccw = CounterClockWise(x, y, z);
			if(ccw > 0)
			{
				//arrange them in clockwise orientation
				swap(xk, zk);
				swap(x, z);
			}

			_Internal::_edge* tedges[3];
			tedges[0] = (new _Internal::_edge(points[xk], points[yk]));
			tedges[1] = (new _Internal::_edge(points[yk], points[zk]));
			tedges[2] = (new _Internal::_edge(points[zk], points[xk]));
			_Internal::_triangle* tr = new _Internal::_triangle(0, 0, 0, points[xk], points[yk], points[zk]);
			faces.push_back(tr);
			//add new edges to the edge vector. Make association with a new face and edges.
			for(int j=0; j<3; ++j)
			{
				vector<_Internal::_edge*>::iterator it = find_if(edges.begin(), edges.end(), _Internal::_edge_equal(tedges[j]));
				if(it == edges.end())
				{
					edges.push_back(tedges[j]);
				}
				else
				{
					delete tedges[j];
					tedges[j] = *it;
				}
				tr->edges[j] = tedges[j];
				tedges[j]->AddFace(tr);
			}
			points[xk]->AddEdge(tedges[0]);
			points[xk]->AddEdge(tedges[2]);
			points[yk]->AddEdge(tedges[0]);
			points[yk]->AddEdge(tedges[1]);
			points[zk]->AddEdge(tedges[1]);
			points[zk]->AddEdge(tedges[2]);
		}
		sort(edges.begin(), edges.end(), _Internal::_edge_less);
		//classify each edge. Initially, they are either Inside or Boundary.
		//After edge-removal, we can have Hole edges when an Inside edge is removed.
		for(int i=0; i<edges.size(); ++i)
		{
			if(isBoundary(edges[i]))
			{
				edges[i]->type = _Internal::Boundary;
			}
			else
			{
				edges[i]->type = _Internal::Inside;
			}
			Node<_Internal::_edge*>* node = makeset(edges[i]);
			vnodes.push_back(node);
			edges[i]->node = node;

		}
		//make a cluster of boundary edges. Initially, there is only one cluster
		Node<_Internal::_edge*>* root = NULL;
		for(int i=0; i<edges.size(); ++i)
		{
			if(edges[i]->type == _Internal::Boundary)
			{	
				if(root == NULL)
				{
					root = edges[i]->node;
				}
				else
				{
					merge(edges[i]->node, root);
				}
			}
		}
	}