Exemplo n.º 1
0
int bisect(int s, int e, int val)
{
  int m=(s+e)/2;
  if(primes[m] ==val) return m;
  if(s==e)
   return primes[m]>val?m:m+1;
  if(primes[m]>val) return bisect(s,m,val);
  else return bisect(m+1,e,val);
}
Exemplo n.º 2
0
static void 
exfill(void (*fill) (PLINT, PLFLT *, PLFLT *),
       PLINT (*defined) (PLFLT, PLFLT),
       int n, PLFLT *x, PLFLT *y)
{
    if (defined == NULL)

        (*fill) (n, x, y);

    else {
        PLFLT xx[16];  
	PLFLT yy[16];
	PLFLT xb, yb;  
	PLINT count = 0;
	PLINT is_inside = defined (x[n-1], y[n-1]);
	PLINT i;

        for (i = 0; i < n; i++) {

	    if (defined(x[i], y[i])) {
	        if (!is_inside) {
		    if (i > 0)
		        bisect (defined, 10,
				x[i], y[i], x[i-1], y[i-1], &xb, &yb);
		    else
		        bisect (defined, 10,
				x[i], y[i], x[n-1], y[n-1], &xb, &yb);
		    xx[count] = xb;
		    yy[count++] = yb;
		}
		xx[count] = x[i];
		yy[count++] = y[i];
		is_inside = 1;
	    }
	    else {
	        if (is_inside) {
		    if (i > 0)
		        bisect (defined, 10,
				x[i-1], y[i-1], x[i], y[i], &xb, &yb);
		    else
		        bisect (defined, 10,
				x[n-1], y[n-1], x[i], y[i], &xb, &yb);
		    xx[count] = xb;
		    yy[count++] = yb;
		    is_inside = 0;
		}
	    }
	}
	
	if (count)
  	    (*fill) (count, xx, yy);
    }
}
Exemplo n.º 3
0
int bisect(int s, int e, ull v)
{
    int m=s+(e-s)/2;
    if(squares[m]==v) return m;
    if(s==e)
    {
	if(squares[m]>v) return m;
	else return m+1;
    }
    if(squares[m]>v) return bisect(s,m,v);
    else return bisect(m+1,e,v);
}
Exemplo n.º 4
0
int solve(int n)
{
   int l=vals[n];
   int low=bisect(0,p-1,n-l+1);
   int high= bisect_left(low,p-1,n);
   return (high-low);
}
Exemplo n.º 5
0
// partitioning a box
vector<box> box_factory::partition(box b, double e)
{
    // setting up a precision map
    map<string, capd::interval> e_map;
    map<string, capd::interval> edges = b.get_map();
    for(auto it = edges.cbegin(); it != edges.cend(); it++)
    {
        e_map.insert(make_pair(it->first, capd::interval(e)));
    }
    // main algorithm
    vector<box> q = {b};
    vector<box> res;
    while(!q.empty())
    {
        box tmp_b = q.front();
        q.erase(q.cbegin());
        vector<box> tmp_v = bisect(tmp_b, e_map);
        if(tmp_v.empty())
        {
            res.push_back(tmp_b);
        }
        else
        {
            q.insert(q.cend(), tmp_v.cbegin(), tmp_v.cend());
        }
    }
    return res;
}
Exemplo n.º 6
0
SubPaving* Paver::pave(const IntervalVector& init_box) {

	SubPaving* paving=new SubPaving[ctc.size()];

	buffer.flush();

	Cell* root=new Cell(init_box);

	// add data required by the contractors
//	for (int i=0; i<ctc.size(); i++) {
//		ctc[i].init_root(*root);
//	}
	// add data required by the bisector
	bsc.add_backtrackable(*root);

	buffer.push(root);

	while (!buffer.empty()) {
		Cell* c=buffer.top();

		if (trace) cout << buffer << endl;

		contract(*c, paving);

		Timer::check(timeout);
		check_capacity(paving);

		if (c->box.is_empty()) delete buffer.pop();
		else bisect(*c);
	}

	return paving;
}
Exemplo n.º 7
0
vector<box> box_factory::partition(box b, map<string, capd::interval> e_map)
{
    // checking if precision map is empty
    if(e_map.empty())
    {
        return {b};
    }
    // checking whether partition map contains does not contain undefined variables
    if(!box_factory::get_keys_diff(box(e_map), b).empty())
    {
        ostringstream s;
        s << "partition map \"" << box(e_map) << "\" contains variables not defined in the box \"" << b << "\"";
        throw std::invalid_argument(s.str());
    }
    // main algorithm
    vector<box> q = {b};
    vector<box> res;
    while(!q.empty())
    {
        box tmp_b = q.front();
        q.erase(q.cbegin());
        vector<box> tmp_v = bisect(tmp_b, e_map);
        if(tmp_v.size() == 1)
        {
            res.push_back(tmp_b);
        }
        else
        {
            q.insert(q.cend(), tmp_v.cbegin(), tmp_v.cend());
        }
    }
    return res;
}
Exemplo n.º 8
0
void
findgraph (long double a, long double b, long double i, long double error,
	   long double p, long double (*f) (long double, long double),
	   char *name)
{

  long double previous = f (a, p);
  long double current = f (a, p);
  unsigned long count = 0;

  printf
    ("Starting scan of %s on interval %Lf to %Lf with increment of %Lf\n\n",
     name, a, b, i);
  for (; a < b; a += i)
    {

      current = f (a, p);
      if (matchSign (previous, current))
	{
	}
      else
	{
	  printf ("  Found sign change from %Lf to %Lf\n\n", a - i, a);
	  bisect (a - i, a, error, p, f, name);
	  secant (a - i, a, error, p, f, name);
	  falseposition (a - i, a, error, p, f, name);
	}
      previous = current;
      count++;
    }

  printf ("Done scanning %s after %lu iterations\n\n", name, count);
}
 void generate(unsigned begin, unsigned end, exec_list *list)
 {
     unsigned length = end - begin;
     if (length <= this->linear_sequence_max_length)
         return linear_sequence(begin, end, list);
     else
         return bisect(begin, end, list);
 }
Exemplo n.º 10
0
int Array::bsearch_custom(const Variant &p_value, Object *p_obj, const StringName &p_function, bool p_before) {

	ERR_FAIL_NULL_V(p_obj, 0);

	_ArrayVariantSortCustom less;
	less.obj = p_obj;
	less.func = p_function;

	return bisect(_p->array, p_value, p_before, less);
}
Exemplo n.º 11
0
/* mkCtrlPts:
 * Generate mult points associated with v.
 * The points will lie on the ray bisecting the angle prev--v--nxt.
 * The first point will aways be v.
 * The rest are positioned equally spaced with maximum spacing SEP.
 * In addition, they all lie within the polygon trip->poly.
 * Parameter s gives the index after which a vertex lies on the
 * opposite side. This is necessary to get the "curvature" of the
 * path correct.
 */
static pointf *mkCtrlPts(int s, int mult, pointf prev, pointf v,
			   pointf nxt, tripoly_t * trip)
{
    pointf *ps;
    int idx = ctrlPtIdx(v, &(trip->poly));
    int i;
    double d, sep, theta, sinTheta, cosTheta;
    pointf q, w;

    if (idx < 0)
	return NULL;

    ps = N_GNEW(mult, pointf);
    theta = bisect(prev, v, nxt);
    sinTheta = sin(theta);
    cosTheta = cos(theta);
    w.x = v.x + 100 * cosTheta;
    w.y = v.y + 100 * sinTheta;
    if (idx > s) {
	if (wind(prev, v, w) != 1) {
	    sinTheta *= -1;
	    cosTheta *= -1;
	    w.x = v.x + 100 * cosTheta;
	    w.y = v.y + 100 * sinTheta;
	}
    } else if (wind(prev, v, w) != -1) {
	sinTheta *= -1;
	cosTheta *= -1;
	w.x = v.x + 100 * cosTheta;
	w.y = v.y + 100 * sinTheta;
    }

    if (triPoint(trip, idx, v, w, &q)) {
	return 0;
    }

    d = DIST(q, v);
    if (d >= mult * SEP)
	sep = SEP;
    else
	sep = d / mult;
    if (idx < s) {
	for (i = 0; i < mult; i++) {
	    ps[i].x = v.x + i * sep * cosTheta;
	    ps[i].y = v.y + i * sep * sinTheta;
	}
    } else {
	for (i = 0; i < mult; i++) {
	    ps[mult - i - 1].x = v.x + i * sep * cosTheta;
	    ps[mult - i - 1].y = v.y + i * sep * sinTheta;
	}
    }
    return ps;
}
Exemplo n.º 12
0
static void 
bisect(PLINT (*defined) (PLFLT, PLFLT), PLINT niter,
       PLFLT x1, PLFLT y1, PLFLT x2, PLFLT y2, PLFLT* xb, PLFLT* yb)
{
    PLFLT xm;
    PLFLT ym;

    if (niter == 0) {
        *xb = x1;
        *yb = y1;
        return;
    }

    xm = (x1 + x2) / 2;
    ym = (y1 + y2) / 2;

    if (defined (xm, ym))
      bisect (defined, niter - 1, xm, ym, x2, y2, xb, yb);
    else
      bisect (defined, niter - 1, x1, y1, xm, ym, xb, yb);      
}
Exemplo n.º 13
0
int main() {

	// Temperature range
	std::vector<double> Temp_range{ 4.0e6 };

	// For clock
	std::clock_t t;
	t = std::clock();

	std::size_t p;

	// Set up main loop to iterate over main sequence, Temps from (4.0e6, 3.2e7 + 7e5)
	for (int p = 0; p < 40; p++) {
		Temp_range.push_back(Temp_range.back() + 7.0e5);
	}

	// Write comment line
	std::ofstream file;
	file.open("Stars_c++.txt");

	file << "# T_C, Rho_C, L_surface, M_surface, R_surface, T_surface" << std::endl;
	file.close();

	for (p = 0; p < Temp_range.size(); p++) {
		// Create initial stars
		std::shared_ptr<Star> star_a(new Star(Temp_range[p], 0.3e3));
		std::shared_ptr<Star> star_b(new Star(Temp_range[p], (500.0e3 + 0.3e3) / 2.0));
		std::shared_ptr<Star> star_c(new Star(Temp_range[p], 500.0e3));

		// While loop to get a proper convergence of star
		bisect(star_a, star_b, star_c, 9.0e-12);

		// Use final star to send data to a file
		file.open("Stars_c++.txt", std::ios::app);
		file << std::setprecision(8);

		file << star_b->luminosity_list[star_b->end] << "," << std::pow((star_b->luminosity_list[star_b->end])
			/ (4.0*pi*sigma*std::pow(star_b->radius_list[star_b->end], 2.0)), 1.0 / 4.0) << "," << star_b->mass_list[star_b->end] << "," 
			<< star_b->radius_list[star_b->end] << "," << star_b->temp_list[0] << "," << star_b->density_list[0] << std::endl;
		file.close();
		std::cout << "Star is finished" << std::endl;
	}

	// timing
	t = std::clock() - t;
	std::cout << "the main sequence took " << t/1000.0 << "seconds" ;
	std::cin.get();

	return 0;
}
Exemplo n.º 14
0
tuple<int, box, box> box::bisect() const {
    // TODO(soonhok): implement other bisect policy
    int index = 0;
    double max_diam = numeric_limits<double>::min();

    for (int i = 0; i < m_values.size(); i++) {
        double current_diam = m_values[i].diam();
        if (current_diam > max_diam && m_values[i].is_bisectable()) {
            index = i;
            max_diam = current_diam;
        }
    }
    return bisect(index);
}
Exemplo n.º 15
0
Arquivo: value.c Projeto: kebekus/srt
static inline m34sf value(i4sf l, struct ray ray, float a)
{
	v4su test = localize(&l, ray, a);
//	v4sf n = l.min;
//	v4sf n = bisect(l, ray, a);
//	v4sf n = newton(l.min, ray, a);
	v4sf n = newton(bisect(l, ray, a), ray, a);
//	v4sf n = newton_bisect(l, ray, a);
//	v4sf n = newton_forward(l.min, ray, a);
//	return color(n, sign_test(n, ray, a) & int_test(n, l), ray, a);
//	return color(n, zero_test(n, ray, a) & int_test(n, l), ray, a);
//	return color(n, (sign_test(n, ray, a) | zero_test(n, ray, a)) & int_test(n, l), ray, a);
//	return color(n, (sign_test(n, ray, a) | epsilon_test(n, ray, a)) & int_test(n, l), ray, a);
	return color(n, test, ray, a);
}
Exemplo n.º 16
0
int split(const Region R, Region* const out, const int count)
{
    out[0] = R;
    int num = 1, tail = 1;

    // Keep splitting elements in the list
    while (num < count) {
        for (int i=0; i < num && tail < count; ++i)
            if (bisect(out[i], &out[i], &out[tail++]))
                return tail - 1;
        num = tail;
    }

    return count;
}
Exemplo n.º 17
0
Arquivo: addseq.c Projeto: isuruf/arb
/* write p = 2a with a in P */
static int
write_as_2a(slong * i1, slong * i2, slong p, const slong * P, slong Plen)
{
    if (p % 2 == 0)
    {
        slong i = bisect(p / 2, P, Plen);

        if (i != -1)
        {
            *i1 = *i2 = i;
            return 1;
        }
    }

    return 0;
}
Exemplo n.º 18
0
void testRoot(){

 printf("\nRoot finding and minimisation\n");
 golden(functionTest3,0,2);
 golden(functionTest1,3,7);
 golden(functionTest2,5,7);
 golden(poly,-0.5,1.0); 

 brute (poly,-1.0,1.0, 0.0001); 
 brute (functionTest1,3,7, 0.0001); 
 secant(poly,0.0,1.0);
 newton(poly, dpoly, 0.0); 
 regulaFalsi(poly,-1.0,1.0); 
 bisect(poly,-1.0,1.0);
 fixedPointIteration(cosine,1.0); 
 squareRoot(20); 
 
} 
/*
 * Main procedure. Specifies usage and parses command line arguments for search
 * bounds.
 */
int main(int argc, char ** argv) {
    // Ensures that the necessary arguments are present
    if (argc!= 3) {
        fprintf(stderr, "Usage:\n\t./bisection.o lower upper\n");
        return EXIT_FAILURE;
    }

    // Parse command line arguments
    double lower = atof(argv[1]);
    double upper = atof(argv[2]);

    // Specify the function you want to bisect here.
    double (*func)(double) = f;

    double result = bisect(func, lower, upper);

    fprintf(stdout, "Root of g on interval [%0.4lf, %0.4lf]:\n", lower, upper);
    fprintf(stdout, "%0.10lf\n", result);
    exit(0);
}
Exemplo n.º 20
0
// draw an arc defined by its ends
static void drawAnyArc (const Quat &vFrom, const Quat &vTo)
{
	Quat pts[NUM_SEGS+1];

	pts[0] = vFrom;
	pts[1] = pts[NUM_SEGS] = vTo;

	int i;
	for(i=0; i<LOG_NUM_SEGS; ++i)
		pts[1] = bisect(pts[0], pts[1]);

	double dot = 2 * Dot(pts[0],pts[1]);
	for(i=2; i<NUM_SEGS; ++i)
		pts[i] = pts[i-1]*dot - pts[i-2];

	glBegin(GL_LINE_STRIP);
	for(i=0; i<=NUM_SEGS; ++i)
		glVertex3f(pts[i].x, pts[i].y, pts[i].z);
	glEnd();
}
Exemplo n.º 21
0
Arquivo: addseq.c Projeto: isuruf/arb
/* write p = a + b with a, b in P */
static int
write_as_a_b(slong * i1, slong * i2, slong p, const slong * P, slong Plen)
{
    slong i, j, pi;

    for (i = 0; i < Plen; i++)
    {
        pi = P[i];

        j = bisect(p - pi, P, Plen);

        if (j != -1)
        {
            *i1 = i;
            *i2 = j;
            return 1;
        }
    }

    return 0;
}
Exemplo n.º 22
0
SolveData* TimeIndependentSolver::solve(Task *task)
{
    Logger::info("Start time-independent solver");

    bool timeIndependent = task->isTimeIndependent();
    if (!timeIndependent) {
        Logger::error("Using time-independent solver for time-dependent task is not appropriate");
        throw 42;
    }

    double coordStep = task->getCoordStep();
    int gridColumns = (task->getMaxCoord() - task->getMinCoord()) / coordStep;
    int gridRows = 1;

    std::vector< std::vector< std::complex<double> > > grid = std::vector< std::vector< std::complex<double> > > (gridRows, std::vector< std::complex< double > >(gridColumns, std::complex<double>(0)));
    Logger::verbose("Grid allocated");

    double * eigenValues = new double[4];
    double * eigenVector = new double[gridColumns];
    double threshold = 1e-7 / gridColumns;
    double vectorThreshold = 1e-7;

    bisect(-1, 4, gridColumns, threshold, std::numeric_limits<double>::epsilon(), task, coordStep, eigenValues);

    double eigenValue = eigenValues[3];
    Logger::info("Obtained eigen value: " + std::to_string(eigenValue));
    Logger::info("qwe: " + std::to_string(eigenValue * gridColumns * gridColumns));

    inverseIteration(coordStep, gridColumns, eigenValue, task, vectorThreshold, eigenVector);

    #pragma omp parallel for
    for (int i = 0; i < gridColumns; ++i) {
        grid[0][i] = eigenVector[i];
    }

    delete eigenValues;
    return new SolveData(task, grid);
}
Exemplo n.º 23
0
int main(){
    freopen(INPUT, "r", stdin);
    freopen(OUTPUT, "w", stdout);
    int total, num, i;
    scanf("%d %d", &total, &num);
    struct farmer farmers[num] ;
    for(i=0;i<num;i++){
        struct farmer temp;
        scanf("%d %d", &(temp.price), &(temp.count));
        bisect(temp, farmers, i);
    }
    int paid = 0;
    for(i=0;i<num;i++){
        if(farmers[i].count >= total){
            paid +=  total * farmers[i].price;
            break;}
        else
            paid += farmers[i].count * farmers[i].price;
            total -= farmers[i].count;
    }
    printf("%d\n",paid);
    exit(0);
}
Exemplo n.º 24
0
void ArcballHelper::fill_arc(
    Arcball const & arcball,
    std::vector<glm::vec3> & positions,
    glm::vec3 from,
    glm::vec3 to)
{
    const auto arc_bisects = 5;
    const auto arc_segments = 32;

    std::array<glm::vec3, arc_segments + 1> points;
    points[0] = from;
    points[1] = to;
    points[arc_segments] = to;

    // we have our first and last point, we bisect the arc to find the second
    // point
    for (int i = 0; i < arc_bisects; i++) {
        points[1] = bisect(points[0], points[1]);
    }

    const auto radius = arcball.radius;
    auto push = [&positions, radius](glm::vec3 point) {
        positions.push_back(point * radius);
    };

    push(points[0]);
    push(points[1]);

    // using our first two points, we use dynamic programming to build up the
    // remaining points of the arc
    const float dot_two = glm::dot(points[0], points[1]) * 2.0f;
    for (int i = 2; i < arc_segments; i++) {
        points[i] = (points[i - 1] * dot_two) - points[i - 2];
        push(points[i]);
    }
    push(points[arc_segments]);
}
Exemplo n.º 25
0
int main(){
    char data[MAX_FARMER_NUM][MAX_LINE_LENGTH];
    int farmer_num,i;
    read_lines(data);
    farmer_num = atoi(data[0]);
    int data_points[farmer_num][2],temp[2];
    int (*comp)(int[],int[]) = compare;
    for(i=0;i<farmer_num;i++){
        read_points(temp,data[i+1]);
        bisect(temp, data_points, i, comp);
    }
    int section[2],j;
    int max_work_time, max_idle_time;
    max_idle_time = max_work_time = 0;
    for(i=0;i<farmer_num;i++){
        if(i!=0){
            if(data_points[i][0] > section[1]){ // open new section
                max_idle_time = record_max_idle(data_points[i][0], section[1], max_idle_time);
                copy(data_points[i],section,2);
                }
            else if(data_points[i][1] > section[1])  // extend section
                section[1] = data_points[i][1];
            max_work_time = record_max_work(section, max_work_time);
        }
        else{
            copy(data_points[i],section,2);
            max_work_time = record_max_work(section, max_work_time);
        }
    }
    FILE *fout;
    fout = fopen("milk2.out","w");
    char buffer[MAX_LINE_LENGTH];
    sprintf(buffer,"%d %d\n",max_work_time, max_idle_time);
    fputs(buffer,fout);
    exit(0);
}
Exemplo n.º 26
0
bool VoronoiDiagramGenerator::voronoi(int triangulate)
{
	struct Site *newsite, *bot, *top, *temp, *p;
	struct Site *v;
	struct Point newintstar;
	int pm;
	struct Halfedge *lbnd, *rbnd, *llbnd, *rrbnd, *bisector;
	struct Edge *e;
	
	PQinitialize();
	bottomsite = nextone();
	out_site(bottomsite);
	bool retval = ELinitialize();

	if(!retval)
		return false;
	
	newsite = nextone();
	while(1)
	{

		if(!PQempty()) 
			newintstar = PQ_min();
		
		//if the lowest site has a smaller y value than the lowest vector intersection, process the site
		//otherwise process the vector intersection		

		if (newsite != (struct Site *)NULL 	&& (PQempty() || newsite -> coord.y < newintstar.y
			|| (newsite->coord.y == newintstar.y && newsite->coord.x < newintstar.x)))
		{/* new site is smallest - this is a site event*/
			out_site(newsite);						//output the site
			lbnd = ELleftbnd(&(newsite->coord));				//get the first HalfEdge to the LEFT of the new site
			rbnd = ELright(lbnd);						//get the first HalfEdge to the RIGHT of the new site
			bot = rightreg(lbnd);						//if this halfedge has no edge, , bot = bottom site (whatever that is)
			e = bisect(bot, newsite);					//create a new edge that bisects 
			bisector = HEcreate(e, le);					//create a new HalfEdge, setting its ELpm field to 0			
			ELinsert(lbnd, bisector);					//insert this new bisector edge between the left and right vectors in a linked list	

			if ((p = intersect(lbnd, bisector)) != (struct Site *) NULL) 	//if the new bisector intersects with the left edge, remove the left edge's vertex, and put in the new one
			{	
				PQdelete(lbnd);
				PQinsert(lbnd, p, dist(p,newsite));
			};
			lbnd = bisector;						
			bisector = HEcreate(e, re);					//create a new HalfEdge, setting its ELpm field to 1
			ELinsert(lbnd, bisector);					//insert the new HE to the right of the original bisector earlier in the IF stmt

			if ((p = intersect(bisector, rbnd)) != (struct Site *) NULL)	//if this new bisector intersects with the
			{	
				PQinsert(bisector, p, dist(p,newsite));			//push the HE into the ordered linked list of vertices
			};
			newsite = nextone();	
		}
		else if (!PQempty()) /* intersection is smallest - this is a vector event */			
		{	
			lbnd = PQextractmin();						//pop the HalfEdge with the lowest vector off the ordered list of vectors				
			llbnd = ELleft(lbnd);						//get the HalfEdge to the left of the above HE
			rbnd = ELright(lbnd);						//get the HalfEdge to the right of the above HE
			rrbnd = ELright(rbnd);						//get the HalfEdge to the right of the HE to the right of the lowest HE 
			bot = leftreg(lbnd);						//get the Site to the left of the left HE which it bisects
			top = rightreg(rbnd);						//get the Site to the right of the right HE which it bisects

			out_triple(bot, top, rightreg(lbnd));		//output the triple of sites, stating that a circle goes through them

			v = lbnd->vertex;						//get the vertex that caused this event
			makevertex(v);							//set the vertex number - couldn't do this earlier since we didn't know when it would be processed
			endpoint(lbnd->ELedge,lbnd->ELpm,v);	//set the endpoint of the left HalfEdge to be this vector
			endpoint(rbnd->ELedge,rbnd->ELpm,v);	//set the endpoint of the right HalfEdge to be this vector
			ELdelete(lbnd);							//mark the lowest HE for deletion - can't delete yet because there might be pointers to it in Hash Map	
			PQdelete(rbnd);							//remove all vertex events to do with the  right HE
			ELdelete(rbnd);							//mark the right HE for deletion - can't delete yet because there might be pointers to it in Hash Map	
			pm = le;								//set the pm variable to zero
			
			if (bot->coord.y > top->coord.y)		//if the site to the left of the event is higher than the Site
			{										//to the right of it, then swap them and set the 'pm' variable to 1
				temp = bot; 
				bot = top; 
				top = temp; 
				pm = re;
			}
			e = bisect(bot, top);					//create an Edge (or line) that is between the two Sites. This creates
													//the formula of the line, and assigns a line number to it
			bisector = HEcreate(e, pm);				//create a HE from the Edge 'e', and make it point to that edge with its ELedge field
			ELinsert(llbnd, bisector);				//insert the new bisector to the right of the left HE
			endpoint(e, re-pm, v);					//set one endpoint to the new edge to be the vector point 'v'.
													//If the site to the left of this bisector is higher than the right
													//Site, then this endpoint is put in position 0; otherwise in pos 1
			deref(v);								//delete the vector 'v'

			//if left HE and the new bisector don't intersect, then delete the left HE, and reinsert it 
			if((p = intersect(llbnd, bisector)) != (struct Site *) NULL)
			{	
				PQdelete(llbnd);
				PQinsert(llbnd, p, dist(p,bot));
			};

			//if right HE and the new bisector don't intersect, then reinsert it 
			if ((p = intersect(bisector, rrbnd)) != (struct Site *) NULL)
			{	
				PQinsert(bisector, p, dist(p,bot));
			};
		}
		else break;
	};

	


	for(lbnd=ELright(ELleftend); lbnd != ELrightend; lbnd=ELright(lbnd))
	{	
		e = lbnd -> ELedge;

		clip_line(e);
	};

	cleanup();

	return true;
	
}
Exemplo n.º 27
0
bool
TerrainPatch::BuildDetailLevel(int level)
{
	int i, j;

	int detail_size = 1 << level;
	int ds1 = detail_size+1;

	if (detail_size > PATCH_SIZE)
	return false;

	Model* model   = new(__FILE__,__LINE__) Model;
	detail_levels[level] = model;

	model->SetLuminous(luminous);
	model->SetDynamic(true);

	const int   NUM_STRIPS        = 4;
	const int   NUM_INDICES_TRI   = 3;
	const int   NUM_INDICES_QUAD  = 6;

	int nverts     = ds1*ds1 + ds1*2*NUM_STRIPS;
	int npolys     = detail_size*detail_size*2;
	int strip_len  = detail_size;
	int total      = npolys + strip_len*NUM_STRIPS;

	if (water) {
		nverts      = ds1*ds1;
		strip_len   = 0;
		total       = npolys;
	}

	Surface*    s     = new(__FILE__,__LINE__) Surface;
	VertexSet*  vset  = 0;

	if (s) {
		s->SetName("default");
		s->CreateVerts(nverts);
		s->CreatePolys(total);
		s->AddIndices(npolys*NUM_INDICES_TRI + strip_len*NUM_STRIPS*NUM_INDICES_QUAD);

		vset = s->GetVertexSet();
		if (!water)
		vset->CreateAdditionalTexCoords();

		ZeroMemory(vset->loc,      nverts * sizeof(Vec3));
		ZeroMemory(vset->diffuse,  nverts * sizeof(DWORD));
		ZeroMemory(vset->specular, nverts * sizeof(DWORD));
		ZeroMemory(vset->tu,       nverts * sizeof(float));
		ZeroMemory(vset->tv,       nverts * sizeof(float));
		if (!water) {
			ZeroMemory(vset->tu1,      nverts * sizeof(float));
			ZeroMemory(vset->tv1,      nverts * sizeof(float));
		}
		ZeroMemory(vset->rw,       nverts * sizeof(float));

		// initialize vertices
		Vec3*  pVert   = vset->loc;
		float* pTu     = vset->tu;
		float* pTv     = vset->tv;
		float* pTu1    = vset->tu1;
		float* pTv1    = vset->tv1;
		DWORD* pSpec   = vset->specular;

		int    dscale  = (PATCH_SIZE-1)/detail_size;
		double dt      = 0.0625 / (ds1-1); // terrain texture scale
		double dtt     = 2.0000 / (ds1-1); // tile texture scale
		double tu0     = (double) rect.x / rect.w / 16.0 + 1.0/16.0;
		double tv0     = (double) rect.y / rect.h / 16.0;

		// surface verts
		for (i = 0; i < ds1; i++) {
			for (j = 0; j < ds1; j++) {
				*pVert   = Vec3((float) (j* scale * dscale - (HALF_PATCH_SIZE*scale)),
				(float) (heights[i*dscale*PATCH_SIZE + j*dscale]),
				(float) (i* scale * dscale - (HALF_PATCH_SIZE*scale)));

				if (level >= 2) {
					*pTu++   = (float) (-j*dtt);
					*pTv++   = (float) ( i*dtt);

					if (level >= 4 && !water) {
						*pTu1++  = (float) (-j*dtt*3);
						*pTv1++  = (float) ( i*dtt*3);
					}

					*pSpec++ = BlendValue(pVert->y);
				}

				else {
					*pTu++   = (float) (tu0 - j*dt);
					*pTv++   = (float) (tv0 + i*dt);
				}

				pVert++;
			}
		}

		if (!water) {
			// strip 1 & 2 verts
			for (i = 0; i < ds1; i += detail_size) {
				for (j = 0; j < ds1; j++) {
					Vec3 vl  = Vec3((float) (j* scale * dscale - (HALF_PATCH_SIZE*scale)),
					(float) (heights[i*dscale*PATCH_SIZE + j*dscale]),
					(float) (i* scale * dscale - (HALF_PATCH_SIZE*scale)));

					*pVert++ = vl;

					DWORD blend = 0;

					if (level >= 2) {
						blend = BlendValue(vl.y);

						*pSpec++ = blend;
						*pTu++   = (float) (-j*dtt);
						*pTv++   = (float) ( i*dtt);
					}

					else {
						*pTu++   = (float) (tu0 - j*dt);
						*pTv++   = (float) (tv0 + i*dt);
					}

					vl.y     = -5000.0f;

					*pVert++ = vl;

					if (level >= 2) {
						*pSpec++ = blend;
						*pTu++   = (float) (-j*dtt);
						*pTv++   = (float) ( i*dtt);
					}

					else {
						*pTu++   = (float) (tu0 - j*dt);
						*pTv++   = (float) (tv0 + i*dt);
					}
				}
			}

			// strip 3 & 4 verts
			for (j = 0; j < ds1; j += detail_size) {
				for (i = 0; i < ds1; i++) {
					Vec3 vl  = Vec3((float) (j* scale * dscale - (HALF_PATCH_SIZE*scale)),
					(float) (heights[i*dscale*PATCH_SIZE + j*dscale]),
					(float) (i* scale * dscale - (HALF_PATCH_SIZE*scale)));

					*pVert++ = vl;

					DWORD blend = 0;

					if (level >= 2) {
						blend = BlendValue(vl.y);

						*pSpec++ = blend;
						*pTu++   = (float) (-j*dtt);
						*pTv++   = (float) ( i*dtt);
					}

					else {
						*pTu++   = (float) (tu0 - j*dt);
						*pTv++   = (float) (tv0 + i*dt);
					}

					vl.y     = -5000.0f;

					*pVert++ = vl;

					if (level >= 2) {
						*pSpec++ = blend;
						*pTu++   = (float) (-j*dtt);
						*pTv++   = (float) ( i*dtt);
					}

					else {
						*pTu++   = (float) (tu0 - j*dt);
						*pTv++   = (float) (tv0 + i*dt);
					}
				}
			}
		}

		Material* m = materials.first();

		// initialize the polys
		for (i = 0; i < npolys; i++) {
			Poly* p        = s->GetPolys() + i;
			p->nverts      = 3;
			p->vertex_set  = vset;
			p->visible     = 1;
			p->sortval     = 0;
			p->material    = m;

			if (level >= 2 && !water) {
				p->material = materials.at(1);
				p->sortval  = 1;
			}
		}

		for (i = npolys; i < total; i++) {
			Poly* p        = s->GetPolys() + i;
			p->nverts      = 4;
			p->vertex_set  = vset;
			p->visible     = 1;
			p->sortval     = 0;
			p->material    = m;
		}

		int index = 0;

		// build main patch polys:
		for (i = 0; i < detail_size; i++) {
			for (j = 0; j < detail_size; j++) {
				int v[4] = {
					(ds1 * (i  ) + (j  )),
					(ds1 * (i  ) + (j+1)),
					(ds1 * (i+1) + (j  )),
					(ds1 * (i+1) + (j+1)) };

				bisect(vset, v);

				// first triangle
				Poly* p = s->GetPolys() + index++;
				p->verts[0]   = v[0];
				p->verts[1]   = v[1];
				p->verts[2]   = v[3];

				if (level >= 2 && !water) {
					int layer = CalcLayer(p) + 1;
					p->material = materials.at(layer);
					p->sortval  = layer;
				}

				// second triangle
				p = s->GetPolys() + index++;
				p->verts[0]   = v[0];
				p->verts[1]   = v[3];
				p->verts[2]   = v[2];

				if (level >= 2 && !water) {
					int layer = CalcLayer(p) + 1;
					p->material = materials.at(layer);
					p->sortval  = layer;
				}
			}
		}

		// build vertical edge strip polys:

		if (!water) {
			for (i = 0; i < NUM_STRIPS; i++) {
				Poly* p = s->GetPolys() + npolys + i*strip_len;
				int   base_index = ds1*ds1 + ds1*2*i;

				for (j = 0; j < strip_len; j++) {
					int v       = base_index + j * 2;
					p->nverts   = 4;

					if (i == 1 || i == 2) {
						p->verts[0] = v;
						p->verts[1] = v+2;
						p->verts[2] = v+3;
						p->verts[3] = v+1;
					}

					else {
						p->verts[0] = v;
						p->verts[1] = v+1;
						p->verts[2] = v+3;
						p->verts[3] = v+2;
					}

					if (level >= 2) {
						int layer = CalcLayer(p) + 1;
						p->material = materials.at(layer);
						p->sortval  = layer;
					}

					p++;
				}
			}
		}

		// update the poly planes:
		for (i = 0; i < total; i++) {
			Poly*   p      = s->GetPolys() + i;
			Plane&  plane  = p->plane;
			WORD*   v      = p->verts;

			plane = Plane(vset->loc[v[0]] + loc,
			vset->loc[v[1]] + loc,
			vset->loc[v[2]] + loc);
		}

		s->Normalize();

		// create continguous segments for each material:
		// sort the polys by material index:
		qsort((void*) s->GetPolys(), s->NumPolys(), sizeof(Poly), mcomp);

		// then assign them to cohesive segments:
		Segment* segment = 0;
		Poly*    spolys  = s->GetPolys();

		for (int n = 0; n < s->NumPolys(); n++) {
			if (segment && segment->material == spolys[n].material) {
				segment->npolys++;
			}
			else {
				segment = 0;
			}

			if (!segment) {
				segment = new(__FILE__,__LINE__) Segment;

				segment->npolys   = 1;
				segment->polys    = &spolys[n];
				segment->material = segment->polys->material;
				segment->model    = model;

				s->GetSegments().append(segment);
			}
		}

		Solid::EnableCollision(false);
		model->AddSurface(s);
		Solid::EnableCollision(true);

		// copy vertex normals:
		const Vec3B* tnorms = terrain->Normals();

		for (i = 0; i < ds1; i++) {
			for (j = 0; j < ds1; j++) {

				if (water) {
					vset->nrm[i*ds1+j] = Point(0,1,0);
				}

				// blend adjacent normals:
				else if (dscale > 1) {
					Point normal;

					// but don't blend more than 16 normals per vertex:
					int step = 1;
					if (dscale > 4)
					step = dscale / 4;

					for (int dy = -dscale/2; dy < dscale/2; dy += step) {
						for (int dx = -dscale/2; dx < dscale/2; dx += step) {
							int ix = rect.x + (ds1-1-j)*dscale + dx;
							int iy = rect.y + i*dscale + dy;

							if (ix < 0)                ix = 0;
							if (ix > terrain_width-1)  ix = terrain_width-1;
							if (iy < 0)                iy = 0;
							if (iy > terrain_width-1)  iy = terrain_width-1;

							Vec3B vbn = tnorms[iy*terrain_width + ix];
							normal += Point((128-vbn.x)/127.0, (vbn.z-128)/127.0, (vbn.y-128)/127.0);
						}
					}

					normal.Normalize();
					vset->nrm[i*ds1+j] = normal;
				}

				// just copy the one normal:
				else {
					Vec3B vbn    = tnorms[(rect.y + i*dscale)*terrain_width + (rect.x + (ds1-1-j) * dscale)];
					Point normal = Point((128-vbn.x)/127.0, (vbn.z-128)/127.0, (vbn.y-128)/127.0);
					vset->nrm[i*ds1+j] = normal;
				}
			}
		}

		if (!water) {
			pVert = &vset->nrm[ds1*ds1];

			// strip 1 & 2 verts
			for (i = 0; i < ds1; i += detail_size) {
				for (j = 0; j < ds1; j++) {
					Vec3 vn  = vset->nrm[i*ds1 + j];

					*pVert++ = vn;
					*pVert++ = vn;
				}
			}

			// strip 3 & 4 verts
			for (j = 0; j < ds1; j += detail_size) {
				for (i = 0; i < ds1; i++) {
					Vec3 vn  = vset->nrm[i*ds1 + j];

					*pVert++ = vn;
					*pVert++ = vn;
				}
			}
		}
	}

	if (level > max_detail)
	max_detail = level;

	return true;
}
Exemplo n.º 28
0
long bisect_right(X const &x, A const &a, long lo, long hi)
{
    return bisect(x, a, lo, hi);
}
Exemplo n.º 29
0
long bisect_right(X const &x, A const &a, long lo)
{
    return bisect(x, a, lo);
}
Exemplo n.º 30
0
void _project_segment(GEOSContextHandle_t handle,
                      const GEOSCoordSequence *src_coords,
                      unsigned int src_idx_from, unsigned int src_idx_to,
                      Interpolator *interpolator,
                      const GEOSPreparedGeometry *gp_domain,
                      double threshold,
                      LineAccumulator &lines)
{
    Point p_current, p_min, p_max, p_end;
    double t_current, t_min, t_max;
    State state;

    GEOSCoordSeq_getX_r(handle, src_coords, src_idx_from, &p_current.x);
    GEOSCoordSeq_getY_r(handle, src_coords, src_idx_from, &p_current.y);
    GEOSCoordSeq_getX_r(handle, src_coords, src_idx_to, &p_end.x);
    GEOSCoordSeq_getY_r(handle, src_coords, src_idx_to, &p_end.y);
#ifdef DEBUG
    std::cerr << "Setting line:" << std::endl;
    std::cerr << "   " << p_current.x << ", " << p_current.y << std::endl;
    std::cerr << "   " << p_end.x << ", " << p_end.y << std::endl;
#endif
    interpolator->set_line(p_current, p_end);
    p_current = interpolator->project(p_current);
    p_end = interpolator->project(p_end);
#ifdef DEBUG
    std::cerr << "Projected as:" << std::endl;
    std::cerr << "   " << p_current.x << ", " << p_current.y << std::endl;
    std::cerr << "   " << p_end.x << ", " << p_end.y << std::endl;
#endif

    t_current = 0.0;
    state = get_state(p_current, gp_domain, handle);

    while(t_current < 1.0 && lines.size() < 500)
    {
        //std::cerr << "Bisecting" << std::endl;
#ifdef DEBUG
        std::cerr << "Working from: " << t_current << " (";
        if (state == POINT_IN)
            std::cerr << "IN";
        else if (state == POINT_OUT)
            std::cerr << "OUT";
        else
            std::cerr << "NAN";
        std::cerr << ")" << std::endl;
        std::cerr << "   " << p_current.x << ", " << p_current.y << std::endl;
        std::cerr << "   " << p_end.x << ", " << p_end.y << std::endl;
#endif
        bisect(t_current, p_current, p_end, handle, gp_domain, state,
               interpolator, threshold,
               t_min, p_min, t_max, p_max);
#ifdef DEBUG
        std::cerr << "   => " << t_min << " to " << t_max << std::endl;
        std::cerr << "   => (" << p_min.x << ", " << p_min.y << ") to (" << p_max.x << ", " << p_max.y << ")" << std::endl;
#endif
        if (state == POINT_IN)
        {
            lines.add_point_if_empty(p_current);
            if (t_min != t_current)
            {
                lines.add_point(p_min);
                t_current = t_min;
                p_current = p_min;
            }
            else
            {
                t_current = t_max;
                p_current = p_max;
                state = get_state(p_current, gp_domain, handle);
                if(state == POINT_IN)
                    lines.new_line();
            }
        }
        else if(state == POINT_OUT)
        {
            if (t_min != t_current)
            {
                t_current = t_min;
                p_current = p_min;
            }
            else
            {
                t_current = t_max;
                p_current = p_max;
                state = get_state(p_current, gp_domain, handle);
                if(state == POINT_IN)
                    lines.new_line();
            }
        }
        else
        {
            t_current = t_max;
            p_current = p_max;
            state = get_state(p_current, gp_domain, handle);
            if(state == POINT_IN)
                lines.new_line();
        }
    }
}