void testInCirclePredicate()
{
	double pa[2] = {-2,0};
	double pb[2] = {2,0};
	double pc[2] = {0,3};
	double pd[2] = {0,1.5};
	double pdp[2] = {0,-1.5};
	double pbc[2] = {3,2};
	double pca[2] = {-3,-3};

	double rtn = incircle(pa,pb,pc,pd);
	double rtn1 = incircle(pa,pb,pc,pdp);
	double rtnbc = incircle(pa,pb,pc,pca);

	// The following test case is the incircle test!
	double p25_4_41_v0[2] = {0.657466,2.696793};
	double p25_4_41_v1[2] = {2.000000,2.000000};
	double p25_4_41_v2[2] = {1.354103,1.967425};

	double p25_4_25_v[2] = {0.657466,2.696793};
	double p25_4_25_incircle = incircle(p25_4_41_v0,p25_4_41_v1,p25_4_41_v2,p25_4_25_v);

	double p641_1996_1069_v0[2] = {1.784130,2.094302};
	double p641_1996_1069_v1[2] = {1.285546,2.383407};
	double p641_1996_1069_v2[2] = {1.400998,2.373647};

	double p641_1996_2333_v[2] = {1.400165,2.265218};
	double p641_1996_1069_incircle = incircle(p641_1996_1069_v0,p641_1996_1069_v1,p641_1996_1069_v2,p641_1996_2333_v);
}
Exemplo n.º 2
0
/*!
 *  \param globalverts global vertices vector
 *  \param v1 first vertex
 *  \param v2 second vertex
 *  \param v3 third vertex
 *  \param p the point
 *  \return 0 if not inside <BR>
 *          1 if inside <BR>
 */
int SimplePolygon::isInsideCircumCircle( DCTPVec2dvector &globalverts, int v1, int v2, int v3, int p ) const
{
  double pa[2], pb[2], pc[2], pd[2];

  pa [ 0 ] = globalverts[ vertices[ v1 ] ][0];
  pa [ 1 ] = globalverts[ vertices[ v1 ] ][1];
  pb [ 0 ] = globalverts[ vertices[ v2 ] ][0];
  pb [ 1 ] = globalverts[ vertices[ v2 ] ][1];
  pc [ 0 ] = globalverts[ vertices[ v3 ] ][0];
  pc [ 1 ] = globalverts[ vertices[ v3 ] ][1];
  pd [ 0 ] = globalverts[ vertices[ p ] ][0];
  pd [ 1 ] = globalverts[ vertices[ p ] ][1];
  // check for order of (pa, pb, pc) they must be in counterclockwise order
  double order = orient2d( pa, pb, pc );
  double dres;
  if ( order < 0.0 ) // clockwise order -> change order
    dres = incircle( pa, pc, pb, pd );
  else
    dres = incircle( pa, pb, pc, pd );

  //std::cerr << pa[ 0 ] << "," << pa[ 1 ] << " ";
  //std::cerr << pb[ 0 ] << "," << pb[ 1 ] << " ";
  //std::cerr << pc[ 0 ] << "," << pc[ 1 ] << " ";
  //std::cerr << pd[ 0 ] << "," << pd[ 1 ] << std::endl;
  //std::cerr << "Inside Circumcircle: " << dres << std::endl;   // >0 if inside

  if ( dres <= 0 ) return 0;
  else return 1;
}
Exemplo n.º 3
0
// InsertVertex in the paper
static void insert_cavity_vertex_helper(MutableTriangleTopology& mesh, RawField<const Perturbed2,VertexId> X,
                                        RawField<bool,VertexId> marked, const HalfedgeId vw) {
  // If wv is a boundary edge, or we're already Delaunay and properly oriented, we're done
  const auto wv = mesh.reverse(vw);
  if (mesh.is_boundary(wv))
    return;
  const auto u = mesh.opposite(vw),
             v = mesh.src(vw),
             w = mesh.dst(vw),
             x = mesh.opposite(wv);
  const auto Xu = X[u],
             Xv = X[v],
             Xw = X[w],
             Xx = X[x];
  const bool in = incircle(Xu,Xv,Xw,Xx);
  if (!in && triangle_oriented(Xu,Xv,Xw))
    return;

  // Flip edge and recurse
  const auto xu = mesh.flip_edge(wv);
  assert(mesh.vertices(xu)==vec(x,u));
  const auto vx = mesh.prev(xu),
             xw = mesh.next(mesh.reverse(xu)); // Grab this now before the recursive call changes uvx
  insert_cavity_vertex_helper(mesh,X,marked,vx),
  insert_cavity_vertex_helper(mesh,X,marked,xw);
  if (!in)
    marked[u] = marked[v] = marked[w] = marked[x] = true;
}
Exemplo n.º 4
0
Exact_adaptive_kernel::Oriented_side Exact_adaptive_kernel::oriented_circle (Point2 const& pa, Point2 const& pb, Point2 const& pc, Point2 const& test)
{
    double r = incircle(pa.coord(), pb.coord(), pc.coord(), test.coord());
    if (r > 0.0)
        return ON_POSITIVE_SIDE;
    else if (r < 0.0)
        return ON_NEGATIVE_SIDE;
    else
        return ON_ORIENTED_BOUNDARY;    
}
Exemplo n.º 5
0
int main(int argc, char *argv[])
{
    FILE *fp;
    float cx, cy, r, px, py;

    fp = fopen(*++argv, "r");
    while (fscanf(fp, "Center: (%f, %f); Radius: %f; Point: (%f, %f)\n", &cx, &cy, &r, &px, &py) != EOF) {
        if (incircle(cx - px, cy - py, r)) {
            puts("true");
        } else {
            puts("false");
        }
    }
    return 0;
}
Exemplo n.º 6
0
static void predicate_tests() {
  IntervalScope scope;
  typedef Vector<double,2> TV2;
  typedef Vector<Quantized,2> QV2;

  // Compare triangle_oriented and incircle against approximate floating point versions
  struct F {
    static inline double triangle_oriented(const TV2 p0, const TV2 p1, const TV2 p2) {
      return edet(p1-p0,p2-p0);
    };
    static inline double incircle(const TV2 p0, const TV2 p1, const TV2 p2, const TV2 p3) {
      const auto d0 = p0-p3, d1 = p1-p3, d2 = p2-p3;
      return edet(ROW(d0),ROW(d1),ROW(d2));
    }
  };
  const auto random = new_<Random>(9817241);
  for (int step=0;step<100;step++) {
    #define MAKE(i) \
      const auto p##i = tuple(i,QV2(random->uniform<Vector<ExactInt,2>>(-exact::bound,exact::bound))); \
      const TV2 x##i(p##i.y);
    MAKE(0) MAKE(1) MAKE(2) MAKE(3)
    GEODE_ASSERT(triangle_oriented(p0,p1,p2)==(F::triangle_oriented(x0,x1,x2)>0));
    GEODE_ASSERT(incircle(p0,p1,p2,p3)==(F::incircle(x0,x1,x2,x3)>0));
  }

  // Test behavior for large numbers, using the scale invariance and antisymmetry of incircle.
  for (const int i : range(exact::log_bound)) {
    const auto bound = ExactInt(1)<<i;
    const auto p0 = tuple(0,QV2(-bound,-bound)), // Four points on a circle of radius sqrt(2)*bound
               p1 = tuple(1,QV2( bound,-bound)),
               p2 = tuple(2,QV2( bound, bound)),
               p3 = tuple(3,QV2(-bound, bound));
    GEODE_ASSERT(!incircle(p0,p1,p2,p3));
    GEODE_ASSERT( incircle(p0,p1,p3,p2));
  }
}
Exemplo n.º 7
0
// Test whether an edge is Delaunay
GEODE_ALWAYS_INLINE static inline bool is_delaunay(const TriangleTopology& mesh, RawField<const Perturbed2,VertexId> X, const HalfedgeId edge) {
  // Boundary edges belong to the sentinel quad and are always Delaunay.
  const auto rev = mesh.reverse(edge);
  if (mesh.is_boundary(rev))
    return true;
  // Grab vertices in counterclockwise order
  const auto v0 = mesh.src(edge),
             v1 = mesh.src(mesh.prev(rev)),
             v2 = mesh.dst(edge),
             v3 = mesh.src(mesh.prev(edge));
  const auto x0 = X[v0],
             x1 = X[v1],
             x2 = X[v2],
             x3 = X[v3];
  // If we have a nonsentinel interior edge, perform a normal incircle test
  if (maxabs(x0.value().x,x1.value().x,x2.value().x,x3.value().x)!=bound)
    return !incircle(x0,x1,x2,x3);
  // Fall back to sentinel case analysis
  return is_delaunay_sentinels(x0,x1,x2,x3);
}
Exemplo n.º 8
0
// Delaunay retriangulate a triangle fan
static void chew_fan(MutableTriangleTopology& parent_mesh, RawField<const Perturbed2,VertexId> X,
                     const VertexId u, RawArray<HalfedgeId> fan, Random& random) {
  chew_fan_count_ += 1;
#ifndef NDEBUG
  for (const auto e : fan)
    assert(parent_mesh.opposite(e)==u);
  for (int i=0;i<fan.size()-1;i++)
    GEODE_ASSERT(parent_mesh.src(fan[i])==parent_mesh.dst(fan[i+1]));
#endif
  const int n = fan.size();
  if (n < 2)
    return;
  chew_fan_count_ += 1024*n;

  // Collect vertices
  const Field<VertexId,VertexId> vertices(n+2,uninit);
  vertices.flat[0] = u;
  vertices.flat[1] = parent_mesh.src(fan[n-1]);
  for (int i=0;i<n;i++)
    vertices.flat[i+2] = parent_mesh.dst(fan[n-1-i]);

  // Delete original vertices
  for (const auto e : fan)
    parent_mesh.erase(parent_mesh.face(e));

  // Make the vertices into a doubly linked list
  const Field<VertexId,VertexId> prev(n+2,uninit),
                                 next(n+2,uninit);
  prev.flat[0].id = n+1;
  next.flat[n+1].id = 0;
  for (int i=0;i<n+1;i++) {
    prev.flat[i+1].id = i;
    next.flat[i].id = i+1;
  }

  // Randomly shuffle the vertices, then pulling elements off the linked list in reverse order of our final shuffle.
  const Array<VertexId> pi(n+2,uninit);
  for (int i=0;i<n+2;i++)
    pi[i].id = i;
  random.shuffle(pi);
  for (int i=n+1;i>=0;i--) {
    const auto j = pi[i];
    prev[next[j]] = prev[j];
    next[prev[j]] = next[j];
  }

  // Make a new singleton mesh
  const auto mesh = new_<MutableTriangleTopology>();
  mesh->add_vertices(n+2);
  small_sort(pi[0],pi[1],pi[2]);
  mesh->add_face(vec(pi[0],pi[1],pi[2]));

  // Insert remaining vertices
  Array<HalfedgeId> work;
  for (int i=3;i<n+2;i++) {
    const auto j = pi[i];
    const auto f = mesh->add_face(vec(j,next[j],prev[j]));
    work.append(mesh->reverse(mesh->opposite(f,j)));
    while (work.size()) {
      auto e = work.pop();
      if (   !mesh->is_boundary(e)
          && incircle(X[vertices[mesh->src(e)]],
                      X[vertices[mesh->dst(e)]],
                      X[vertices[mesh->opposite(e)]],
                      X[vertices[mesh->opposite(mesh->reverse(e))]])) {
        work.append(mesh->reverse(mesh->next(e)));
        work.append(mesh->reverse(mesh->prev(e)));
        e = mesh->unsafe_flip_edge(e);
      }
    }
  }

  // Copy triangles back to parent
  for (const auto f : mesh->faces()) {
    const auto vs = mesh->vertices(f);
    parent_mesh.add_face(vec(vertices[vs.x],vertices[vs.y],vertices[vs.z]));
  }
}
Exemplo n.º 9
0
/*!
 *  Note that the resulting triangulation will not necessarily be complex,
 *  since it's constrained by the polygon's edges.
 *
 *  Besides triangulating the polygon this method also does:
 *  - insertion of the new polygons (triangles) at the end of
 *    the polygon list.
 *  - setting up marking information for the new polygons.
 *
 *  \param polylist the global list of polygons
 *  \param selfindex the index of this polygon in the global list
 *  \return zero on success, and a negative integer if some error occured.
 */
int SimplePolygon::triangulate( DCTPVec2dvector &globalverts, simplepolygonvector &polylist)
{
#ifdef OSG_TRIANGULATE_CONVEX
	if( ( !is_marked ) && ( m_bConvex ) )
	{
//		std::cerr <<"triangulating convex: " <<vertices.size() << std::endl;
		switch( vertices.size( ) )
		{
			case 0:
			case 1:
			case 2:
				return 0;
			case 3:
				{
					polylist.push_back( *this );
				}
				return 0;
		}

		unsigned int		ui_prev;
		unsigned int		ui_mid;
		unsigned int		ui_next;
		const unsigned int	cui_vertex_cnt = vertices.size( );
		SimplePolygon		cl_poly;

		ui_mid = 0;
		for( ui_prev = 1; ui_prev < cui_vertex_cnt; ++ui_prev )
		{
			if( globalverts[ vertices[ ui_prev ] ][1] < globalverts[ vertices[ ui_mid ] ][1] )
			{
				ui_mid = ui_prev;
			}
			else if( ( globalverts[ vertices[ ui_prev ] ][1] == globalverts[ vertices[ ui_mid ] ][1] ) &&
					 ( globalverts[ vertices[ ui_prev ] ][0] < globalverts[ vertices[ ui_mid ] ][0] ) )
			{
				ui_mid = ui_prev;
			}
		}

		ui_prev = ( ui_mid + cui_vertex_cnt - 1 ) % cui_vertex_cnt;
		ui_next = ( ui_mid + 1 ) % cui_vertex_cnt;

		cl_poly.vertices.resize( 3 );
		cl_poly.is_marked = is_marked;
		cl_poly.vertices[ 0 ] = vertices[ ui_mid ];
		cl_poly.vertices[ 1 ] = vertices[ ui_next ];
		cl_poly.vertices[ 2 ] = vertices[ ui_prev ];

		ui_prev = ( ui_prev + cui_vertex_cnt - 1 ) % cui_vertex_cnt;
		ui_next = ( ui_next + 1 ) % cui_vertex_cnt;

		while( cl_poly.vertices[ 1 ] != cl_poly.vertices[ 2 ] )
		{
			polylist.push_back( cl_poly );
			if( globalverts[ vertices[ ui_prev ] ][1] < globalverts[ vertices[ ui_next ] ][1] )
			{
				cl_poly.vertices[ 0 ] = cl_poly.vertices[ 2 ];
				cl_poly.vertices[ 2 ] = vertices[ ui_prev ];
				ui_prev = ( ui_prev + cui_vertex_cnt - 1 ) % cui_vertex_cnt;
			}
			else if( ( globalverts[ vertices[ ui_prev ] ][1] == globalverts[ vertices[ ui_next ] ][1] ) &&
					 ( globalverts[ vertices[ ui_prev ] ][0] < globalverts[ vertices[ ui_next ] ][0] ) )
			{
				cl_poly.vertices[ 0 ] = cl_poly.vertices[ 2 ];
				cl_poly.vertices[ 2 ] = vertices[ ui_prev ];
				ui_prev = ( ui_prev + cui_vertex_cnt - 1 ) % cui_vertex_cnt;
			}
			else
			{
				cl_poly.vertices[ 0 ] = cl_poly.vertices[ 1 ];
				cl_poly.vertices[ 1 ] = vertices[ ui_next ];
				ui_next = ( ui_next + 1 ) % cui_vertex_cnt;
			}
		}
		return 0;
	}
#endif

//  std::cerr << " triangulate in, size: " << vertices.size() << std::endl;
	switch( vertices.size( ) )
	{
		case 0:
		case 1:
		case 2:
			return 0;
		case 3:
			{
				polylist.push_back( *this );
//				SimplePolygon p;
//				p.vertices = vertices;
//				p.is_marked = is_marked;
//				std::cerr << "adding polygon of 3 vertices into the list..." << std::endl;
//				polylist.push_back( p ); // FIXME, this is not too elegant
//				std::cerr << "triangulate out!!!" << std::endl;
			}
			return 0;
		case 4:
			{
				const int		ci_v1 = vertices[ 0 ];
				const int		ci_v2 = vertices[ 1 ];
				const int		ci_v3 = vertices[ 2 ];
				const int		ci_v4 = vertices[ 3 ];
				const double	cd_sdist1 = ( globalverts[ ci_v1 ] - globalverts[ ci_v3 ] ).squareLength( );
				const double	cd_sdist2 = ( globalverts[ ci_v2 ] - globalverts[ ci_v4 ] ).squareLength( );
				double			ad_pa[ 2 ];
				double			ad_pb[ 2 ];
				double			ad_pc[ 2 ];
				double			ad_pd[ 2 ];
				SimplePolygon	p;

				p.vertices.resize( 3 );
				p.is_marked = is_marked;

				ad_pa[ 0 ] = globalverts[ ci_v1 ][0];
				ad_pa[ 1 ] = globalverts[ ci_v1 ][1];
				ad_pb[ 0 ] = globalverts[ ci_v2 ][0];
				ad_pb[ 1 ] = globalverts[ ci_v2 ][1];
				ad_pc[ 0 ] = globalverts[ ci_v3 ][0];
				ad_pc[ 1 ] = globalverts[ ci_v3 ][1];
				ad_pd[ 0 ] = globalverts[ ci_v4 ][0];
				ad_pd[ 1 ] = globalverts[ ci_v4 ][1];

				if( cd_sdist1 - cd_sdist2 < DCTP_EPS )
				{
/*					const double cd_r1 = orient2d( ad_pa, ad_pb, ad_pc );
					const double cd_r2 = orient2d( ad_pa, ad_pb, ad_pd );
					if( ( ( cd_r1 <= 0.0 ) && ( cd_r2 <= 0.0 ) ) ||
						( ( cd_r1 >= 0.0 ) && ( cd_r2 >= 0.0 ) ) )*/
					if( ( orient2d( ad_pa, ad_pb, ad_pc ) <= 0.0 ) ||
						( orient2d( ad_pa, ad_pd, ad_pc ) >= 0.0 ) ||
						( incircle( ad_pa, ad_pb, ad_pc, ad_pd ) > 0.0 ) )
					{
						p.vertices[ 0 ] = ci_v1;
						p.vertices[ 1 ] = ci_v2;
						p.vertices[ 2 ] = ci_v4;
						polylist.push_back( p );
						p.vertices[ 0 ] = ci_v2;
						p.vertices[ 1 ] = ci_v3;
						p.vertices[ 2 ] = ci_v4;
						polylist.push_back( p );
//						std::cerr << globalverts[ ci_v1 ] << globalverts[ ci_v2 ] << globalverts[ ci_v3 ] << globalverts[ ci_v4 ] << std::endl;
					}
					else
					{
						p.vertices[ 0 ] = ci_v1;
						p.vertices[ 1 ] = ci_v2;
						p.vertices[ 2 ] = ci_v3;
						polylist.push_back( p );
						p.vertices[ 0 ] = ci_v1;
						p.vertices[ 1 ] = ci_v3;
						p.vertices[ 2 ] = ci_v4;
						polylist.push_back( p );
					}
				}
				else
				{
//					const double cd_r1 = orient2d( ad_pc, ad_pd, ad_pa );
//					const double cd_r2 = orient2d( ad_pc, ad_pd, ad_pb );
//					if( ( ( cd_r1 <= 0.0 ) && ( cd_r2 <= 0.0 ) ) ||
//						( ( cd_r1 >= 0.0 ) && ( cd_r2 >= 0.0 ) ) )
					if( ( orient2d( ad_pb, ad_pc, ad_pd ) <= 0.0 ) ||
						( orient2d( ad_pb, ad_pa, ad_pd ) >= 0.0 ) ||
						( incircle( ad_pa, ad_pb, ad_pd, ad_pc ) > 0.0 ) )
					{
						p.vertices[ 0 ] = ci_v1;
						p.vertices[ 1 ] = ci_v2;
						p.vertices[ 2 ] = ci_v3;
						polylist.push_back( p );
						p.vertices[ 0 ] = ci_v1;
						p.vertices[ 1 ] = ci_v3;
						p.vertices[ 2 ] = ci_v4;
						polylist.push_back( p );
//						std::cerr << globalverts[ ci_v1 ] << globalverts[ ci_v2 ] << globalverts[ ci_v3 ] << globalverts[ ci_v4 ] << std::endl;
					}
					else
					{
						p.vertices[ 0 ] = ci_v1;
						p.vertices[ 1 ] = ci_v2;
						p.vertices[ 2 ] = ci_v4;
						polylist.push_back( p );
						p.vertices[ 0 ] = ci_v2;
						p.vertices[ 1 ] = ci_v3;
						p.vertices[ 2 ] = ci_v4;
						polylist.push_back( p );
					}
				}
			}
			return 0;
	}

  // recalc valid third points!
  v1tp = -1;
  validThirdPoints.resize( vertices.size( ) );

  SimplePolygon poly;
  int i2, i3; // this is an index into the vertices[] vector
  int err;
  DCTPivector verts; //p1verts, p2verts, p3verts;
  int i;
  int j;
  // pseudo random (reproduces same triangulation)
  int offs = ( int( globalverts[ vertices[ 0 ] ][0] * vertices.size( ) ) ) % vertices.size( );

/*  for( i = 0; i < vertices.size( ); ++i )
  {
    std::cerr << globalverts[ vertices[ i ] ][0] << ",";
    std::cerr << globalverts[ vertices[ i ] ][1] << std::endl;
  }*/

  for( j = 0; j < int(vertices.size()); j++ ) {
	i = ( j + offs ) % vertices.size( );
//    v1 = vertices[ i ];
    if ( i == int(vertices.size()) - 1 )
      i2 = 0; //v2 = vertices [ 0 ];
    else
      i2 = i + 1; //v2 = vertices[ i + 1 ];
    err = findThirdPoint( globalverts, i, i2, i3 );
    if ( err ) return err;
    if ( i3 >= 0 ) {
      // build p1
      int k = i2; // !!!
      verts.resize( 0 );
      while ( k != i3 ) {
//        std::cerr << " k: " << k;
        verts.push_back( vertices[ k ] );
        k++; if ( k == int(vertices.size()) ) k = 0;
      } // while k
      verts.push_back( vertices[ k ] ); // record the last one aswell
//      std::cerr << " k: " << k << std::endl;
      poly.vertices = verts;
      poly.is_marked = is_marked;
//      std::cerr << "calling p1... " << std::endl;
      err = poly.triangulate( globalverts, polylist);
      if ( err ) return err;
      // build p2
      verts.resize( 3 );
      verts[ 0 ] = vertices[ i ];
      verts[ 1 ] = vertices[ i2 ];
      verts[ 2 ] = vertices[ i3 ];
      poly.vertices = verts;
      poly.is_marked = is_marked;
//      std::cerr << "adding p2 to the list..." << std::endl;
      polylist.push_back( poly );
      // build p3
      k = i3;
      verts.resize( 0 );
      while ( k != i ) {
        verts.push_back( vertices[ k ] );
        k++; if ( k == int(vertices.size()) ) k = 0;
      } // while k
      verts.push_back( vertices[ k ] ); // record the last one aswell
      poly.vertices = verts;
      poly.is_marked = is_marked;
//      std::cerr << "calling p3... " << std::endl;
      err = poly.triangulate( globalverts, polylist );
      if ( err ) return err;
//      std::cerr << "triangulate out!!!" << std::endl;
      return 0;
    } // if
  } // for i
/*  SWARNING << "triangulate out WITH ERROR!!!" << endLog;

  for( i = 0; i < vertices.size( ); ++i )
  {
    std::cerr << globalverts[ vertices[ i ] ][0] << ",";
    std::cerr << globalverts[ vertices[ i ] ][1] << std::endl;
  }*/

//  char x[ 256 ];
//  gets( x );

  return -1;
}
Exemplo n.º 10
0
int main(){
    double f = 3;
    printf("rand: %f\n",incircle(&f,&f,&f,&f));
}
Exemplo n.º 11
0
/*Type of Cut Strategy is defined as:
 * (useAltCut, useVertical) = (true, true)  => Alternating Cuts
 * (useAltCut, useVertical) = (true, false) => Horizontal Cuts*
 * (useAltCut, useVertical) = (false, true)  => Vertical Cuts
 * */
void delaunay(Vertex **ppVertices, long numVertices, Edge **ppLe, Edge **ppRe,
		bool useAltCuts, bool useVertical) {
    NOT_NULL(ppVertices);
    
    if(numVertices == 2) {
        Edge *pA = Edge::makeEdge();
        if(*ppVertices[0] > *ppVertices[1]) {
            ELEM_SWAP(ppVertices[0], ppVertices[1]);
        }
        pA->setOrg(ppVertices[0]);
        pA->setDest(ppVertices[1]);
        *ppLe = pA;
        *ppRe = pA->Sym();
    }
    else if(numVertices == 3) {
        Edge *pA = Edge::makeEdge(),
             *pB = Edge::makeEdge(),
             *pC = 0;

        if(*ppVertices[0] > *ppVertices[1]) {
            ELEM_SWAP(ppVertices[0], ppVertices[1]);
        }
        if(*ppVertices[1] > *ppVertices[2]) {
            ELEM_SWAP(ppVertices[1], ppVertices[2]);
        }

        Edge::splice(pA->Sym(), pB);
        pA->setOrg(ppVertices[0]);
        pA->setDest(ppVertices[1]);
        pB->setOrg(ppVertices[1]);
        pB->setDest(ppVertices[2]);
        
        REAL ccw = orient2d(ppVertices[0]->Pos(), ppVertices[1]->Pos(), ppVertices[2]->Pos());
        if(ccw > 0) {
            pC = Edge::connect(pB, pA);
            *ppLe = pA;
            *ppRe = pB->Sym();
        }
        else if(ccw < 0) {
            pC = Edge::connect(pB, pA);
            *ppLe = pC->Sym();
            *ppRe = pC;
        }
        else {
            *ppLe = pA;
            *ppRe = pB->Sym();
        }
    }
    else {
        long middle = std::floor(numVertices/2);
        Edge *pLdo = 0, 
             *pLdi = 0, 
             *pRdi = 0, 
             *pRdo = 0;

        //These vertices are used for merging a horizontal cut
        Vertex *pBotMax = 0, //highest vertex of bottom half
               *pTopMin = 0, //lowest vertex of top half
               *pMin    = 0, //Lexicographically max vertex
               *pMax    = 0; //Lexicographically min vertex
        
        //Find median partition by X or Y, depending on whether we're using a vertical cut
        std::nth_element(ppVertices, ppVertices+middle, ppVertices+numVertices, useVertical ? Vertex::lessX : Vertex::lessY);

        //Recursive calls
        delaunay(ppVertices, middle, &pLdo, &pLdi, useAltCuts, useAltCuts ? !useVertical : useVertical);
        delaunay(ppVertices+middle, numVertices - middle, &pRdi, &pRdo, useAltCuts, useAltCuts ? !useVertical : useVertical);
        
        //Modify ldi be highest in bottom half and rdi to be lowest in top half
        if(!useVertical) {
            pBotMax = ppVertices[0];
            pTopMin = ppVertices[middle];
            pMin    = (*ppVertices[0] < *ppVertices[middle]) ? ppVertices[0] : ppVertices[middle];
            pMax    = (*ppVertices[0] > *ppVertices[middle]) ? ppVertices[0] : ppVertices[middle];;
            for(long i=1; i < middle; i++) {
                if(*ppVertices[i] < *pMin) {
                    pMin = ppVertices[i];
                }
                else if(*ppVertices[i] > *pMax) {
                    pMax = ppVertices[i];
                }
                
                if(ppVertices[i]->gtY(*pBotMax)) {
                    pBotMax = ppVertices[i];
                }
            }
            for(long i=middle+1; i < numVertices; i++) {
                if(*ppVertices[i] < *pMin) {
                    pMin = ppVertices[i];
                }
                else if(*ppVertices[i] > *pMax) {
                    pMax = ppVertices[i];
                }
                
                if(ppVertices[i]->ltY(*pTopMin)) {
                    pTopMin = ppVertices[i];
                }
            }
            
            pLdi = pBotMax->getCWHullEdge();
            pRdi = pTopMin->getCCWHullEdge();
        }
        
        
        //Compute the lower common tangent of two sets of vertices
        while (1) {
            if(pLdi->leftOf(pRdi->Org())) {
                pLdi = pLdi->Lnext();
            }
            else if(pRdi->rightOf(pLdi->Org())) {
                pRdi = pRdi->Rprev();
            }
            else {
                break;
            }
        }

        // Create a first cross edge pBasel from pRdi.origin to pLdi.origin
        Edge *pBasel = Edge::connect(pRdi->Sym(), pLdi);

        if(pLdi->Org() == pLdo->Org()) {
            pLdo = pBasel->Sym();
        }
        if(pRdi->Org() == pRdo->Org()) {
            pRdo = pBasel;
        }

        //Merging two halves
        while(1) {
            //Locate the first Left point pLcand to be encou
        	Edge *pLcand = pBasel->Sym()->Onext();
            bool leftFinished  = !pLcand->valid(pBasel);
            if(!leftFinished) {
                while(incircle(pBasel->Dest()->Pos(), 
                               pBasel->Org()->Pos(), 
                               pLcand->Dest()->Pos(),  
                               pLcand->Onext()->Dest()->Pos()) > 0) {
                
                    Edge *pT = pLcand->Onext();
                    Edge::deleteEdge(pLcand);
                    pLcand = pT;
                }
            }
            
            //Symmetrically locate the first R point to be hit
            Edge *pRcand = pBasel->Oprev();
            bool rightFinished = !pRcand->valid(pBasel);
            if(!rightFinished) {
                while(incircle(pBasel->Dest()->Pos(), 
                               pBasel->Org()->Pos(), 
                               pRcand->Dest()->Pos(),  
                               pRcand->Oprev()->Dest()->Pos()) > 0) {
                
                    Edge *pT = pRcand->Oprev();
                    Edge::deleteEdge(pRcand);
                    pRcand = pT;
                }
            }

            //both are invalid, pBasel is upper common tangent
            if(leftFinished && rightFinished) {
                break;
            }
            //the next cross edge is to be connected to either pLcand.dest or pRcand.dest
            if(leftFinished || 
               (!rightFinished && incircle(pLcand->Dest()->Pos(), 
                                                  pLcand->Org()->Pos(), 
                                                  pRcand->Org()->Pos(), 
                                                  pRcand->Dest()->Pos()) > 0)) {
                pBasel = Edge::connect(pRcand, pBasel->Sym());
            }
            else {
                pBasel = Edge::connect(pBasel->Sym(), pLcand->Sym());
            }
        }

        //Modify pLdo and pRdo if we merging a horizontal cut
        if(!useVertical) {
            pLdo = pMin->getCCWHullEdge();
            pRdo = pMax->getCWHullEdge();
        }

        *ppLe = pLdo;
        *ppRe = pRdo;
    }
    return;
}
Exemplo n.º 12
0
int main(int argc, char *argv[]) {
	SDL_Event ev,az;
	SDL_Surface *screen;
	SDL_Surface *kep;
	SDL_TimerID id;
	FILE *fp;
	int x, y,click=0,clicktwo=0,aut=0,quit=0,gomb=0,egerx,egery,nothinghappened=1;
	cell cells[MAX][MAX]={0};

	kep=IMG_Load("sejt.png");
	if(!kep)
		fprintf(stderr, "Nem sikerult betolteni a kepfajlt!\n");

	/* SDL inicializálása és ablak megnyitása */
	SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER);
	screen=SDL_SetVideoMode(MAX*MERET+KERET*2+100, MAX*MERET+KERET*2-100, 0, SDL_FULLSCREEN);
	if (!screen) {
		fprintf(stderr, "Nem sikerult megnyitni az ablakot!\n");
		exit(1);
	} 
	SDL_WM_SetCaption("Game Of Life", "Game Of Life");
	
	SDL_FillRect(screen, NULL, 0x433e3f);
	boxColor(screen,KERET/3,KERET/3,MAX*MERET+KERET*2-KERET/3,MAX*MERET+KERET*2-KERET/3,KERETSZIN);

	drawcell(cells,screen,kep);



	while(!quit)
	{
		boxColor(screen, MAX*MERET+KERET*2+10,KERET+5,MAX*MERET+KERET*2+90,KERET+40,0xFFDFD2FF);
		boxColor(screen, MAX*MERET+KERET*2+14,KERET+9,MAX*MERET+KERET*2+86,KERET+36,0xE5C8BDFF);
		stringRGBA(screen, MAX*MERET+KERET*2+20, KERET+19, "Leptetes", 255, 255, 255, 255);

		boxColor(screen, MAX*MERET+KERET*2+10,KERET+5+HEZAG,MAX*MERET+KERET*2+90,KERET+40+HEZAG,0xFFDFD2FF);
		boxColor(screen, MAX*MERET+KERET*2+14,KERET+9+HEZAG,MAX*MERET+KERET*2+86,KERET+36+HEZAG,0xE5C8BDFF);
		if(aut==0)
			stringRGBA(screen, MAX*MERET+KERET*2+15, KERET+69, "Szimul.be", 255, 255, 255, 255);
		else
			stringRGBA(screen, MAX*MERET+KERET*2+15, KERET+69, "Szimul.ki", 255, 255, 255, 255);

		boxColor(screen, MAX*MERET+KERET*2+10,KERET+5+HEZAG*2,MAX*MERET+KERET*2+90,KERET+40+HEZAG*2,0xFFDFD2FF);
		boxColor(screen, MAX*MERET+KERET*2+14,KERET+9+HEZAG*2,MAX*MERET+KERET*2+86,KERET+36+HEZAG*2,0xE5C8BDFF);
		stringRGBA(screen, MAX*MERET+KERET*2+26, KERET+19+HEZAG*2, "Torles", 255, 255, 255, 255);

		boxColor(screen, MAX*MERET+KERET*2+10,KERET+5+HEZAG*3,MAX*MERET+KERET*2+90,KERET+40+HEZAG*3,0xFFDFD2FF);
		boxColor(screen, MAX*MERET+KERET*2+14,KERET+9+HEZAG*3,MAX*MERET+KERET*2+86,KERET+36+HEZAG*3,0xE5C8BDFF);
		stringRGBA(screen, MAX*MERET+KERET*2+27, KERET+19+HEZAG*3, "Kilovo", 255, 255, 255, 255);

		filledCircleColor(screen,MAX*MERET+2*KERET+80,9,8,0xFFDFD2FF);
		filledCircleColor(screen,MAX*MERET+2*KERET+80,9,6,0xE5C8BDFF);
		stringRGBA(screen,MAX*MERET+KERET*2+77,6,"X",255,255,255,255);
		
		SDL_Flip(screen);

		
		while(SDL_PollEvent(&ev)){
			switch(ev.type)
			{
				/*case SDL_KEYDOWN:
				switch(ev.key.keysym.sym)
				{
				case SDLK_s:
				mentes(cells);		   
				break;
				case SDLK_l:
				fp=fopen("save.txt","r");

				for(y=0;y<MAX;y++)
				for(x=0;x<MAX;x++)
				fscanf(fp,"%d ",&cells[y][x].alive);

				fclose (fp);

				drawcell(cells,screen,kep);
				SDL_Flip(screen);
				break;
				}
				break;*/

			case SDL_MOUSEBUTTONDOWN:
				if(ev.button.button==SDL_BUTTON_LEFT)
				{
					if(ev.button.x<=MAX*MERET+KERET){
						egerx=holazeger(ev.button.x);
						egery=holazeger(ev.button.y);

						if(cells[egery][egerx].alive==1)
							cells[egery][egerx].alive=0;
						else
							cells[egery][egerx].alive=1;
					}

					else if(incircle(ev.button.x,ev.button.y,MAX*MERET+2*KERET+80,9,8))
						quit=1;

					else if((ev.button.x<=MAX*MERET+KERET*2+90 && ev.button.x>=MAX*MERET+KERET*2+10) && (ev.button.y<=KERET+40 && ev.button.y>=KERET+5))//egyes lépés
					{
						round(cells);

					}
					else if((ev.button.x<=MAX*MERET+KERET*2+90 && ev.button.x>=MAX*MERET+KERET*2+10) && (ev.button.y<=KERET+90 && ev.button.y>=KERET+55))//szimulálás
					{
						if(aut==0)
							aut=1;
						else aut=0;	
					}
					else if((ev.button.x<=MAX*MERET+KERET*2+90 && ev.button.x>=MAX*MERET+KERET*2+10) && (ev.button.y<=KERET+40+HEZAG*2 && ev.button.y>=KERET+5+HEZAG*2))//egyes lépés
					{
						for(y=0;y<MAX;y++)
							for(x=0;x<MAX;x++)
								cells[y][x].alive=0;
					}
					else if((ev.button.x<=MAX*MERET+KERET*2+90 && ev.button.x>=MAX*MERET+KERET*2+10) && (ev.button.y<=KERET+40+HEZAG*3 && ev.button.y>=KERET+5+HEZAG*3))//egyes lépés
					{
						fp=fopen("save.txt","r");

						for(y=0;y<MAX;y++)
							for(x=0;x<MAX;x++)
								fscanf(fp,"%d ",&cells[y][x].alive);

						fclose (fp);

						drawcell(cells,screen,kep);
						SDL_Flip(screen);
					}
					drawcell(cells,screen,kep);
					SDL_Flip(screen);
				}
				break;

			case SDL_MOUSEBUTTONUP:
				if(ev.button.button==SDL_BUTTON_LEFT)
				{
					click=0;
					clicktwo=0;
				}
				break;

			case SDL_QUIT:
				quit=1;
				break;
			}
		}

		if(aut)
		{
			SDL_Delay(100);
			round(cells);
			drawcell(cells,screen,kep);
			SDL_Flip(screen);
		}


	}


	SDL_FreeSurface(kep);
	SDL_Quit();
	exit(0);
	return 0;
}
Exemplo n.º 13
0
static void
rec_delaunay(site_struct * sites[],
             int sl, int sh, edge_ref * le, edge_ref * re)
{
    if (sh == sl + 2) {
        edge_ref a = make_edge();
        ODATA(a) = sites[sl];
        DDATA(a) = sites[sl + 1];
        *le = a;
        *re = SYM(a);
    } else if (sh == sl + 3) {
        edge_ref a = make_edge();
        edge_ref b = make_edge();
        double ct = ccw(sites[sl], sites[sl + 1], sites[sl + 2]);
        splice(SYM(a), b);
        ODATA(a) = sites[sl];
        DDATA(a) = sites[sl + 1];
        ODATA(b) = sites[sl + 1];
        DDATA(b) = sites[sl + 2];
        if (ct == 0.0) {
            *le = a;
            *re = SYM(b);
        } else {
            edge_ref c = connect(b, a);
            if (ct > 0.0) {
                *le = a;
                *re = SYM(b);
            } else {
                *le = SYM(c);
                *re = c;
            }
        }
    } else {
        edge_ref ldo, ldi, rdi, rdo;
        edge_ref basel, lcand, rcand;

        int sm = (sl + sh) / 2;

        rec_delaunay(sites, sl, sm, &ldo, &ldi);
        rec_delaunay(sites, sm, sh, &rdi, &rdo);

        while (1) {
            if (leftof(ORG(rdi), ldi))
                ldi = LNEXT(ldi);
            else if (rightof(ORG(ldi), rdi))
                rdi = ONEXT(SYM(rdi));
            else
                break;
        }

        basel = connect(SYM(rdi), ldi);
        if (ORG(ldi) == ORG(ldo))
            ldo = SYM(basel);
        if (ORG(rdi) == ORG(rdo))
            rdo = basel;

        while (1) {
            lcand = ONEXT(SYM(basel));
            if (rightof(DEST(lcand), basel))
                while (incircle
                       (DEST(basel), ORG(basel), DEST(lcand),
                        DEST(ONEXT(lcand)))) {
                    edge_ref t = ONEXT(lcand);
                    destroy_edge(lcand);
                    lcand = t;
                }

            rcand = OPREV(basel);
            if (rightof(DEST(rcand), basel))
                while (incircle
                       (DEST(basel), ORG(basel), DEST(rcand),
                        DEST(OPREV(rcand)))) {
                    edge_ref t = OPREV(rcand);
                    destroy_edge(rcand);
                    rcand = t;
                }

            if (!rightof(DEST(lcand), basel)
                && !rightof(DEST(rcand), basel))
                break;

            if (!rightof(DEST(lcand), basel) ||
                (rightof(DEST(rcand), basel) &&
                 incircle(DEST(lcand), ORG(lcand), ORG(rcand),
                          DEST(rcand))))
                basel = connect(rcand, SYM(basel));
            else
                basel = connect(SYM(basel), SYM(lcand));
        }
        *le = ldo;
        *re = rdo;
    }
}