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); }
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); } }
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); }
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); }
// 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; }
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; }
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; }
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); }
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); }
/* 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; }
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); }
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; }
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); }
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); }
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; }
/* 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; }
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); }
// 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(); }
/* 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; }
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); }
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); }
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]); }
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); }
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; }
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; }
long bisect_right(X const &x, A const &a, long lo, long hi) { return bisect(x, a, lo, hi); }
long bisect_right(X const &x, A const &a, long lo) { return bisect(x, a, lo); }
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(); } } }