static void interpolate_start (const Matrix& z, int x, int y, int direction) // // compute and store starting point // { Vector3D p; // store starting coordinates xstart = x; ystart = y; // start at boundary if (y == 0 || y == ydim) { opencontour = true; current = new_point(Outside); // start inside } else { opencontour = false; interpolate(z,x,y,direction,p); current = new_point(p); } // mark starting point start = current; }
static int interpolate_next (const Matrix& z, int x, int y, int direction) // // linear interpolation for the point found // { Vector3D p; // check if returned to starting point - close circular list if ( (x == xstart) && (y == ystart) && (direction == final_direction) ) { current->next = start; return true; // finished // check if no boundary point } else if (x > 0 && y > 0 && x < xdim && y < ydim) { // add this point to list interpolate(z,x,y,direction,p); current->next = new_point(p); current = current->next; // point on boundary - add marker to list } else if ( current->p != Outside) { opencontour = true; current->next = new_point(Outside); current = current->next; } return false; // not finished }
t_color get_ambiant_light(t_scene scene, t_vector ray, t_obj object, t_point inter) { t_llst *tmp; t_point light_inter; double norm; tmp = scene.lst_light; scene.color = new_color(0, 0, 0); while (tmp) { light_inter = new_point(inter.x - tmp->light->body.center.x, inter.y - tmp->light->body.center.y, inter.z - tmp->light->body.center.z); norm = sqrt(pow(light_inter.x, 2) + pow(light_inter.y, 2) + pow(light_inter.z, 2)); scene.normal = object.normal(object, inter, ray); light_inter = new_point((double)light_inter.x / norm, light_inter.y / norm, light_inter.z / norm); scene.scal = scalar_prod(light_inter, scene.normal); scene.ray = ray.dir; if (norm_is_shit(scene, *(tmp->light), inter, norm) && scene.scal >= 0.000000000000000000001) scene.color = calc_color(get_spec(scene, *(tmp->light), light_inter, object), object.texturing(object, inter, ray), *(tmp->light), scene.scal); tmp = tmp->next; } return (scene.color); }
t_color texture_plan(t_obj object, t_point inter) { float x; float y; int colo; t_point rot; t_plan *tmp; normal = normal_sphere(*(t_sphere *)(obj.obj), inter, ray); if (!object.texture) return (object.color); tmp = ((t_plan *)object.obj); rot = vec_dir(new_point(0, 0, 0), new_point(tmp->a, tmp->b, tmp->c)); x = rot.x + rot.y + rot.z; inter = rot_point(new_point(inter.x - rot.x * (tmp->d / (tmp->a + tmp->b + tmp->c)), inter.y - rot.y * (tmp->d / (tmp->a + tmp->b + tmp->c)), inter.z - rot.z * (tmp->d / (tmp->a + tmp->b + tmp->c))), get_rot_mat(M_PI / 2 * rot.z / x, 0, -M_PI / 2 * rot.x / x)); colo = 0; x = (inter.x - floor(inter.x / 30) * 30) / 30 * object.texture->width; y = (10 - (inter.z - floor(inter.z / 10) * 10)) / 10 * object.texture->height; ft_memcpy(&colo, object.texture->data + ((int)x * (object.texture->bpp / 8)) + ((int)y * object.texture->sl), 3); return (normalize(new_point((def.red * 2 - 255) / 255 + normal.x, -(def.green * 2 - 255) / 255 + normal.y, (def.blue * 2 - 255) / 255 + normal.z))); }
LINEVECTOR *read_linevector (char *filename, short print) { /*! * \author Emanuele Cordano * \date May 2009 * *\param filename (char *) - name of the file where to read line_information *\param print (short) * * *\brief It creates and reads a linevector from the following options: *\brief index{1} * FILE CONTAINIG NECESSARY INFORMATION FOR LINES x y line_index lenght2d x_P1 y_P1 x_P2 y_P2 1: double matrix lines information {55550,8} */ FILE *fd; DOUBLEMATRIX *ldata; LINEVECTOR *lines; POINT *P1,*P2; long index,j,ja; int ix=1; /*! x coordinate of the middle point */ int iy=ix+1; /*! y coordinate of the midddele point */ int iline_index=iy+1; /*! iline_index of the line */ int ilength2d=iline_index+1; /*! lenght of the line */ int iP1_x=ilength2d+1; /*! P1 x coordinate */ int iP1_y=iP1_x+1; /*! P1 y coordinate */ int iP2_x=iP1_y+1; /*! P2 x coordinate */ int iP2_y=iP2_x+1; /*! P2 y coordinate */ int indata=iP2_y; /* number of data */ fd=t_fopen(filename,"r"); index=(long)read_index(fd,no_PRINT); ldata=read_doublematrix(fd,"a",no_PRINT); if (ldata->nch!=indata) printf("Warning in read_linevector: inconstancy on number of columns (data) : %ld %d \n",ldata->nch,indata); //if (ldata->nrh!=index) printf("Error in read_linevector: inconstancy on number of lines : %ld %ld",ldata->nrh,index); lines=new_linevector(ldata->nrh); for (j=lines->nl;j<=lines->nh;j++) { ja=(long)ldata->element[j][iline_index]; if (j!=ja) printf("Error in read_linevector (line %ld of %ld): inconstancy on line index : %ld %ld \n",j,lines->nh,j,ja); P1=new_point(j-1,ldata->element[j][iP1_x],ldata->element[j][iP1_y],NULL_ELEVATION); P2=new_point(j,ldata->element[j][iP2_x],ldata->element[j][iP2_y],NULL_ELEVATION); lines->element[j]=new_line_from_points(j,P1,P2); free_point(P1); free_point(P2); } free_doublematrix(ldata); if (print==1) printf("Function read_linevector (number of lines %ld) was successfully executed!! \n",lines->nh); return lines; }
static t_point get_symetric(t_point a, t_vector normal) { t_point ret; float k_mini; k_mini = (normal.dir.x * (a.x - normal.origin.x) + normal.dir.y * (a.y - normal.origin.y) + normal.dir.z * (a.z - normal.origin.z)) / (pow(normal.dir.x, 2) + pow(normal.dir.y, 2) + pow(normal.dir.z, 2)); ret = new_point(k_mini * normal.dir.x + normal.origin.x, k_mini * normal.dir.y + normal.origin.y, k_mini * normal.dir.z + normal.origin.z); ret = new_point(2 * ret.x - a.x, 2 * ret.y - a.y, 2 * ret.z - a.z); return (ret); }
LINE *get_line(DOUBLEVECTOR *vertex_x_coord, DOUBLEVECTOR *vertex_y_coord, long line_index, char *number_strings, short print){ /*! * \param vertex_x_coord - (DOUBLEVECTOR *) vector of x coordinates * \param vertex_y_coord - (DOUBLEVECTOR *) vector of y coordinates * * \param line_index - (long int) index of the line * \param number_string - (char *) string containing the number of two vertex points * \param print - (short) if activated it prints error or warning messages * \author Emanuele Cordano * \date November 2008 * */ POINT *P1, *P2; //long index1,index2, long j; LONGVECTOR *lvertices; LINE *li; lvertices=read_longarray_from_string(number_strings,DELIMITERS,MAX_POINTS,0); if (lvertices->nh<2) printf("Error:: line %s (%ld) cannot be created, there no vertices!!\n",number_strings,line_index); for (j=lvertices->nl;j<=2;j++){ if ((lvertices->element[j]>vertex_x_coord->nh) || (lvertices->element[j]>vertex_y_coord->nh)) { printf ("Error:: line %s (%ld) cannot be created, point %ld has no coordinates or no atributes!!\n",number_strings,line_index,j); } } j=1; P1=new_point(lvertices->element[j],vertex_x_coord->element[lvertices->element[j]],vertex_y_coord->element[lvertices->element[j]],NO_ELEVATION); j=2; P2=new_point(lvertices->element[j],vertex_x_coord->element[lvertices->element[j]],vertex_y_coord->element[lvertices->element[j]],NO_ELEVATION); if (print==1) printf ("The two vertices %ld (x=%lf,y=%lf) and %ld (x=%lf,y=%lf) of line %s (%ld) were succesfully created!!\n",P1->index,P1->x,P1->y,P2->index,P2->x,P2->y,number_strings,line_index); li=new_line_from_points(line_index, P1,P2); free_point(P1); free_point(P2); free_longvector(lvertices); return li; }
void AbstractForm::add_point_to_form(float x, float y) { Point new_point(x,y); points.push_back(new_point); update_bounding_box(x,y); update_values(); }
point_t *random_point(point_t *min, point_t *max) { int i; point_t *point = new_point(); for (i=0; i<dim; i++) point->weights[i] = min->weights[i] + (float)random()/RAND_MAX * (max->weights[i]-min->weights[i]); return point; }
void TestSetNodeLocationForCylindricalMesh() throw (Exception) { // Create mesh CylindricalHoneycombVertexMeshGenerator generator(4, 4); Cylindrical2dVertexMesh* p_mesh = generator.GetCylindricalMesh(); // Move one of the nodes to near the periodic boundary c_vector<double, 2> new_point_location; new_point_location[0] = -0.01; new_point_location[1] = 3.0*0.5/sqrt(3.0); ChastePoint<2> new_point(new_point_location); // This node was on left and is now near the right p_mesh->SetNode(12, new_point); TS_ASSERT_DELTA(p_mesh->GetNode(12)->rGetLocation()[0], 3.99, 1e-4); TS_ASSERT_DELTA(p_mesh->GetNode(12)->rGetLocation()[1], 3.0*0.5/sqrt(3.0), 1e-4); // This node has stayed close to where it was new_point.SetCoordinate(0, 0.2); p_mesh->SetNode(0, new_point); TS_ASSERT_DELTA(p_mesh->GetNode(0)->rGetLocation()[0], 0.2, 1e-4); // This node was on right and is now near the left new_point.SetCoordinate(0, 4.1); p_mesh->SetNode(8, new_point); TS_ASSERT_DELTA(p_mesh->GetNode(8)->rGetLocation()[0], 0.1, 1e-4); TS_ASSERT_DELTA(p_mesh->GetNode(8)->rGetLocation()[1], 3.0*0.5/sqrt(3.0), 1e-4); }
void NodeBasedCellPopulationWithParticles<DIM>::UpdateParticlePositions(double dt) { // Initialise vector of forces on particles std::vector<c_vector<double, DIM> > drdt(this->GetNumNodes()); for (unsigned i=0; i<drdt.size(); i++) { drdt[i] = zero_vector<double>(DIM); } // Calculate forces on particles double damping_constant = this->GetDampingConstantNormal(); for (unsigned i=0; i<drdt.size(); i++) { drdt[i] = this->GetNode(i)->rGetAppliedForce()/damping_constant; } for (typename AbstractMesh<DIM,DIM>::NodeIterator node_iter = this->mrMesh.GetNodeIteratorBegin(); node_iter != this->mrMesh.GetNodeIteratorEnd(); ++node_iter) { if (node_iter->IsParticle()) { ChastePoint<DIM> new_point(node_iter->rGetLocation() + dt*drdt[node_iter->GetIndex()]); node_iter->SetPoint(new_point); } } }
t_color get_reflect(t_scene scene, t_vector ray, t_obj object, t_point inter) { t_color color; t_color new_col; double dist; color = new_color(0, 0, 0); scene.refl *= object.brightness; if (scene.depth-- == 0 || scene.refl < 0.01) return (color); dist = -1; ray.dir = vec_dir(inter, get_symetric(ray.origin, new_vector(inter, object.normal(object, inter, ray)))); ray.origin = inter; if (find_closest_inter(scene.lst_obj, &object, &dist, ray) < 0) return (color); inter = new_point(ray.origin.x + dist * ray.dir.x, ray.origin.y + dist * ray.dir.y, ray.origin.z + dist * ray.dir.z); new_col = get_first_ray(scene, ray, object, inter); color = get_ambiant_light(scene, ray, object, inter); color = new_color(scene.refl * new_col.red + color.red, scene.refl * new_col.blue + color.blue, scene.refl * new_col.green + color.green); return (new_color(new_col.red + color.red, new_col.blue + color.blue, new_col.green + color.green)); }
void Triangle::transform(std::vector<TexturedPoint> &new_points){ double tr_mat[3][2]; double radians = currAngle * RAD_IN_GRAD; double sinval = sin(radians); double cosval = cos(radians); // матрица преобразования( сжатие по осям и поворот ) tr_mat[0][0] = currScaleX * cosval; tr_mat[0][1] = currScaleX * sinval; tr_mat[1][0] = -currScaleY * sinval; tr_mat[1][1] = currScaleY * cosval; tr_mat[2][0] = rotCenterX*(1-currScaleX*cosval) + currScaleY * rotCenterY*sinval; tr_mat[2][1] = rotCenterY*(1-currScaleY*cosval) - currScaleX * rotCenterX*sinval; // обрабатываем точки треугольника преобразованием for (int i = 0; i < (int) points.size(); ++i) { double x0 = points[i].x(); double y0 = points[i].y(); double x = tr_mat[0][0]*x0+ tr_mat[1][0]*y0+tr_mat[2][0]; double y = tr_mat[0][1]*x0+ tr_mat[1][1]*y0+tr_mat[2][1]; // текстурные координаты остаются преждними TexturedPoint new_point(x,y, points[i].getTexX(), points[i].getTexY()); new_points.push_back(new_point); } }
int main() { struct point p1, p2, middle_point, end_point; p1 = new_point(); p2 = new_point(); middle_point = new_point(); end_point = new_point(); print_point(p1); print_point(p2); print_point(middle_point); print_point(end_point); return 0; }
point_t *read_point(FILE *fp) { static char buf[1000]; char *tok, *s; int field; point_t *point; vector_t *v; float *xp; if (dim < 0) { v = read_float_vector(fp); if (v == NULL) return NULL; dim = v->n; point = new_point(); for (field = 0; field<dim; field++) { xp = vector_get(v, field); point->weights[field] = *xp; free(xp); } vector_delete(v); return point; } point = new_point(); if (fgets(buf, sizeof(buf), fp) == NULL) return NULL; s = buf; field = 0; while ((tok = strsep(&s, " \t\n")) != NULL) { if (!*tok) // empty token continue; if (field >= dim) { fprintf(stderr, "read_point(): too many fields in line\n"); return NULL; } else point->weights[field] = strtod(tok, NULL); field++; } if (field == 0) return NULL; if (field < dim) { fprintf(stderr, "read_point(): wrong number of fields in line\n"); return NULL; } return point; }
void start_accept( ba::ip::tcp::acceptor &accept ) { stream_sptr new_point(my_async_reader::create(accept.get_io_service( ))); accept.async_accept( new_point->get_stream( ), boost::bind( accept_handle, ba::placeholders::error, new_point, boost::ref( accept ) ) ); }
point_t *point_copy(point_t *point) { point_t *newpoint; int i; newpoint = new_point(); newpoint->score = point->score; newpoint->has_score = point->has_score; for (i=0; i<dim; i++) newpoint->weights[i] = point->weights[i]; return newpoint; }
void update_ship(game *g, asteroid *a) { if(g->Ship->time > 0) g->Ship->time -= 0.1; point *n1 = new_point(), *n2 = new_point(); n1->x = g->Ship->position->x - 8 * sin(g->Ship->angle); n1->y = g->Ship->position->y + 20 * cos(g->Ship->angle); n2->x = g->Ship->position->x + 8 * sin(g->Ship->angle); n2->y = g->Ship->position->y + 20 * cos(g->Ship->angle); if((collision(a, g->Ship->position) || collision(a, n1) || collision(a,n2) ) && g->Ship->time <= 0) { if(--g->Ship->life <= 0) g->status = Lose; g->Ship->position = p_times(g->Size, 0.5); g->Ship->time = 5; } free(n1); free(n2); }
int main() { point_t *p1, *p2, *mid_p; double dist; p1 = new_point(1,2); p2 = new_point(3,4); print_point(p1); print_point(p2); dist = distance_between(p1, p2); printf("Distance between p1 and p2: %f\n", dist); mid_p = midpoint(p1, p2); print_point(mid_p); free_point(&p1); free_point(&p2); return 0; }
std::vector<double> getPointBetween(const std::vector<double> &p1, const std::vector<double> &p2, double dist) { std::vector<double> new_point(p1.size()); double fraction = dist / getLineDistance(p2, p1); for (unsigned int i = 0; i < p1.size(); i++) { new_point[i] = p1[i] + fraction * getDirectionMultiplier(p1[i], p2[i]) * getAngleBetween(p1[i], p2[i]); } return new_point; }
void get_line(t_point **pts, char **s, int l, t_eve *e) { int i; i = 0; while (s[i]) { add_point(pts, new_point(i, l, ft_atoi(s[i]), e)); i++; } if (e->width == -1 || i > e->width) e->width = i; }
void point_cloud_at_hypercube_vertices(int points_per_cloud, double cloud_radius, std::vector< tracktable::PointCartesian<dim> >& out_points, std::vector<int>& out_labels) { // To generate all the edges of a hypercube we use the following // procedure: // // Take a d-dimensional integer and count from 0 to 2^d - 1 (all // ones). Each of these numbers specifies one vertex of the // hypercube: if a given bit is 0, the coordinate for that dimension // is -1. If a given bit is 1, the coordinate is 1. // // We can visit each edge once by watching for the bits that are // zero. Whenever we see one, sample from -1 to 1 along that axis. typedef tracktable::PointCartesian<dim> point_t; std::cout << "TEST: Iterating over " << (1 << dim) << " hypercube vertices.\n"; for (int vertex_id = 0; vertex_id < (1 << dim); ++vertex_id) { point_t corner_vertex; for (int d = 0; d < dim; ++d) { if ((vertex_id & (1 << d)) == 0) { corner_vertex[d] = -1; } else { corner_vertex[d] = 1; } } out_points.push_back(corner_vertex); out_labels.push_back(vertex_id); for (int i = 0; i < points_per_cloud; ++i) { point_t offset(random_point_in_sphere<dim>(cloud_radius)); // std::cout << "random point in sphere: " << offset << "\n"; point_t new_point(corner_vertex); boost::geometry::add_point(new_point, offset); out_points.push_back(new_point); out_labels.push_back(vertex_id); } } }
void create_point_set(void) { int i, n; double t; draw_count = 0; for (i = 0; i <= N; i++) { t = tmin + ((double) i / (double) N) * (tmax - tmin); new_point(t); } n = draw_count; for (i = 0; i < n - 1; i++) fill(i, i + 1, 0); }
static t_color get_spec(t_scene scene, t_light light, t_point light_inter, t_obj object) { t_point r; float dot; float reflet; reflet = 2.0f * scene.scal; r = new_point(light_inter.x - reflet * scene.normal.x, light_inter.y - reflet * scene.normal.y, light_inter.z - reflet * scene.normal.z); dot = scalar_prod(scene.ray, r); if (dot < 0.0f) { reflet = powf(dot, 20) * object.spec * light.intensity; scene.color = new_color(scene.color.red + reflet * light.color.red, scene.color.blue + reflet * light.color.blue, scene.color.green + reflet * light.color.green); } return (scene.color); }
int main(int argc, char const *argv[]) { //TODO 1. checar se a entrada tem o número correto de argumentos. (FEITO) // 2. checar se a entrada é alfanumérica // 3. checar se a entrada contém números inteiros if (argc != 3) { printf("ERRO: número de argumentos inválidos. Chamar como ./test_point x y, onde x e y são inteiros."); exit(EXIT_FAILURE); } int x = atoi(argv[1]); int y = atoi(argv[2]); point_t point = new_point(x,y); printf("Valor X: %d ", point.x); printf("Valor Y: %d\n", point.y); printf("\n"); return 0; }
POLYGON *read_polygon(FILE *fd,short print) { /*! * \autor Emanuele Cordano * \date May 2009 * * \param (FILE *) - file pointer * \param (short) - print * */ int ix=1; /* x coordinate of the centroid */ int iy=ix+1; /* y coordinate of the centroid */ int ipolygon_index=iy+1; /* index of the polygon */ int iarea2d=ipolygon_index+1; /* area of the polygon */ int n_data=iarea2d; long i; DOUBLEVECTOR *v_data; POLYGON *po; v_data=read_doublearray(fd,print); if (v_data->nh<=n_data) printf ("Error in read_polygon there no sufficient data !!\n"); po=(POLYGON *)malloc(sizeof(POLYGON)); if (!po) t_error("Polygon in read_polygon struct was not allocated"); po->area2D=v_data->element[iarea2d]; po->index=v_data->element[ipolygon_index]; po->centroid=new_point(po->index,v_data->element[ix],v_data->element[iy],NULL_ELEVATION); po->edge_indices=new_longvector(v_data->nh-n_data); for(i=po->edge_indices->nl;i<=po->edge_indices->nh;i++) { po->edge_indices->element[i]=v_data->element[i+n_data]; } free_doublevector(v_data); return po; }
void TestSetNodeLocationForCylindricalMesh() throw (Exception) { EXIT_IF_PARALLEL; // HoneycombMeshGenerator doesn't work in parallel // Create generating mesh HoneycombMeshGenerator generator(4, 4); TetrahedralMesh<2,2>* p_generating_mesh = generator.GetMesh(); // Convert this to a Cylindrical2dNodesOnlyMesh double periodic_width = 4.0; Cylindrical2dNodesOnlyMesh* p_mesh = new Cylindrical2dNodesOnlyMesh(periodic_width); p_mesh->ConstructNodesWithoutMesh(*p_generating_mesh, periodic_width); // Move one of the nodes to past the periodic boundary c_vector<double, 2> new_point_location; new_point_location[0] = -0.01; new_point_location[1] = 0.5*sqrt(3.0); ChastePoint<2> new_point(new_point_location); // This node was on left and is now near the right p_mesh->SetNode(4, new_point); TS_ASSERT_DELTA(p_mesh->GetNode(4u)->rGetLocation()[0], 3.99, 1e-4); TS_ASSERT_DELTA(p_mesh->GetNode(4u)->rGetLocation()[1], 3.0*0.5/sqrt(3.0), 1e-4); // This node has stayed close to where it was TS_ASSERT_DELTA(p_mesh->GetNode(5u)->rGetLocation()[0], 1.5, 1e-4); new_point.SetCoordinate(0, 1.4); p_mesh->SetNode(5, new_point); TS_ASSERT_DELTA(p_mesh->GetNode(5u)->rGetLocation()[0], 1.4, 1e-4); // This node was on right and is now near the left new_point.SetCoordinate(0, 4.1); p_mesh->SetNode(7, new_point); TS_ASSERT_DELTA(p_mesh->GetNode(7u)->rGetLocation()[0], 0.1, 1e-4); TS_ASSERT_DELTA(p_mesh->GetNode(7u)->rGetLocation()[1], 3.0*0.5/sqrt(3.0), 1e-4); // Avoid memory leak delete p_mesh; }
void Triangle::transform(std::vector<TexturedPoint> &new_points){ double tr_mat[3][2]; double radians = currAngle * RAD_IN_GRAD;// TODO : radians теряет точность double sinval = sin(radians); double cosval = cos(radians); tr_mat[0][0] = currScaleX * cosval; tr_mat[0][1] = currScaleX * sinval; tr_mat[1][0] = -currScaleY * sinval; tr_mat[1][1] = currScaleY * cosval; tr_mat[2][0] = rotCenterX*(1-currScaleX*cosval) + currScaleY * rotCenterY*sinval; tr_mat[2][1] = rotCenterY*(1-currScaleY*cosval) - currScaleX * rotCenterX*sinval; for (int i = 0; i < (int) points.size(); ++i) { double x0 = points[i].x(); double y0 = points[i].y(); double x = tr_mat[0][0]*x0+ tr_mat[1][0]*y0+tr_mat[2][0]; double y = tr_mat[0][1]*x0+ tr_mat[1][1]*y0+tr_mat[2][1]; TexturedPoint new_point(x,y, points[i].getTexX(), points[i].getTexY()); new_points.push_back(new_point); } }
POLYGON *get_polygon(long index,double x, double y, double z, char *edge_index_string,LINEVECTOR *all_lines, short print) { /*! * \author Emanuele Cordano * \date November 2008 * * \param index - (long) index of the centroid and the polygons * \param x - (double) x of the centroid * \param y - (double) y of the centroid * \param z - (double) z of the centroid * * \param edge_line_index - (char *) string containing the edge indices * * \param all_lines - (LINEVECTOR *) vector of all lines * \param print - (short) * * \return a polygon (Attributes are not allocated!!) * */ LINEVECTOR *edges; POLYGON *PO; LONGVECTOR *ledges; POINT *centroid; centroid=new_point(index,x,y,z); ledges=read_longarray_from_string(edge_index_string,DELIMITERS,MAX_POINTS,0); edges=extract_linvector_from_linevector(ledges,all_lines); PO=new_polygon_from_a_linevector(edges,centroid); free_point(centroid); free_longvector(ledges); free_linevector(edges); return PO; }
void fill(int i, int k, int level) { int dx, dy, j; double t; if (level >= MAX_DEPTH || draw_count >= YMAX) return; dx = abs(draw_buf[i].x - draw_buf[k].x); dy = abs(draw_buf[i].y - draw_buf[k].y); if (dx < 1 && dy < 1) return; t = (draw_buf[i].t + draw_buf[k].t) / 2.0; j = draw_count; new_point(t); fill(i, j, level + 1); fill(j, k, level + 1); }