R_API void r_cons_canvas_line_square (RConsCanvas *c, int x, int y, int x2, int y2, RCanvasLineStyle *style) { int min_x = R_MIN (x, x2); int diff_x = R_ABS (x - x2); int diff_y = R_ABS (y - y2); apply_line_style (c, x, y, x2, y2, style, 1); // -- // TODO: find if there's any collision in this line if (y2 - y > 1) { int hl = diff_y / 2 - 1; int hl2 = diff_y - hl; int w = diff_x == 0 ? 0 : diff_x + 1; int style = min_x == x ? APEX_DOT : DOT_APEX; draw_vertical_line (c, x, y + 1, hl); draw_vertical_line (c, x2, y + hl + 1, hl2); draw_horizontal_line (c, min_x, y + hl + 1, w, style); } else { if (y2 == y) { draw_horizontal_line (c, min_x, y, diff_x + 1, DOT_DOT); } else { if (x != x2) { draw_horizontal_line (c, min_x, y, diff_x + 1, REV_APEX_APEX); } draw_vertical_line (c, x2, y2, diff_y); } } c->attr = Color_RESET; }
R_API void r_cons_canvas_line_back_edge (RConsCanvas *c, int x, int y, int x2, int y2, RCanvasLineStyle *style, int ybendpoint1, int xbendpoint, int ybendpoint2, int isvert) { int min_x1 = R_MIN (x, xbendpoint); int min_x2 = R_MIN (x2, xbendpoint); int diff_x1 = R_ABS (x - xbendpoint); int diff_x2 = R_ABS (x2 - xbendpoint); int diff_y = R_ABS ((y + ybendpoint1 + 1) - (y2 - ybendpoint2- 1)); int w1 = diff_x1 == 0 ? 0 : diff_x1 + 1; int w2 = diff_x2 == 0 ? 0 : diff_x2 + 1; apply_line_style (c, x, y, x2, y2, style, isvert); if (isvert) { draw_vertical_line (c, x, y + 1, ybendpoint1 + 1); draw_horizontal_line (c, min_x1, y + ybendpoint1 + 2, w1, REV_APEX_APEX); draw_vertical_line (c, xbendpoint, y2 - ybendpoint2 + 1, diff_y - 1); draw_horizontal_line (c, min_x2, y2 - ybendpoint2, w2, DOT_DOT); draw_vertical_line (c, x2, y2 - ybendpoint2 + 1, ybendpoint2); } else { int miny1 = R_MIN (y, xbendpoint); int miny2 = R_MIN (y2, xbendpoint); int diff_y1 = R_ABS (y - xbendpoint); int diff_y2 = R_ABS (y2 - xbendpoint); draw_horizontal_line (c, x + 1, y, 1 + ybendpoint1 + 1, xbendpoint > y ? NRM_DOT : NRM_APEX); draw_vertical_line (c, x + 1 + ybendpoint1 + 1, miny1 + 1, diff_y1 - 1); draw_horizontal_line (c, x2 - ybendpoint2, xbendpoint, (x + 1 + ybendpoint1 + 1) - (x2 - ybendpoint2) + 1, xbendpoint > y ? REV_APEX_APEX : DOT_DOT); draw_vertical_line (c, x2 - ybendpoint2, miny2 + 1, diff_y2 - 1); draw_horizontal_line (c, x2 - ybendpoint2, y2, ybendpoint2 + 1, xbendpoint > y ? DOT_NRM : REV_APEX_NRM); } }
void Canvas::fill_roundrect(uint8_t x, uint8_t y, uint8_t width, uint8_t height, uint8_t radius) { int16_t dx = 0, dy = radius; int16_t p = 1 - radius; uint8_t diameter = 2 * radius; // Adjust the position and fill the inner rectangle x += radius; width -= diameter; fill_rect(x, y, width, height + 1); height -= diameter; y += radius; // Draw the outer rectangle and corners while (dx <= dy) { draw_vertical_line(x + dx + width, y - dy, dy + dy + height); draw_vertical_line(x - dx, y - dy, dy + dy + height); draw_vertical_line(x + dy + width, y - dx, dx + dx + height); draw_vertical_line(x - dy, y - dx, dx + dx + height); dx++; if (p < 0) p = p + (dx << 1) + 1; else { dy--; p = p + ((dx - dy) << 1) + 1; } } }
void Canvas::draw_rect(uint8_t x, uint8_t y, uint8_t width, uint8_t height) { draw_horizontal_line(x, y, width); draw_vertical_line(x + width, y, height); draw_vertical_line(x, y, height); draw_horizontal_line(x, y + height, width); }
R_API void r_cons_canvas_line_square_defined (RConsCanvas *c, int x, int y, int x2, int y2, RCanvasLineStyle *style, int bendpoint, int isvert) { int min_x = R_MIN (x, x2); int diff_x = R_ABS (x - x2); int diff_y = R_ABS (y - y2); int min_y = R_MIN (y, y2); apply_line_style (c, x, y, x2, y2, style, isvert); if (isvert) { if (x2 == x) { draw_vertical_line (c, x, y + 1, diff_y); } else if (y2 - y > 1) { int h1 = 1 + bendpoint; int h2 = diff_y - h1; int w = diff_x == 0 ? 0 : diff_x + 1; int style = min_x == x ? APEX_DOT : DOT_APEX; draw_vertical_line (c, x, y + 1, h1); draw_horizontal_line (c, min_x, y + bendpoint + 2, w, style); draw_vertical_line (c, x2, y + h1 + 1 + 1, h2); } else { //TODO: currently copy-pasted if (y2 == y) { draw_horizontal_line (c, min_x, y, diff_x + 1, DOT_DOT); } else { if (x != x2) { draw_horizontal_line (c, min_x, y, diff_x + 1, REV_APEX_APEX); } draw_vertical_line (c, x2, y2, diff_y-2); } } } else { if (y2 == y) { draw_horizontal_line (c, min_x + 1, y, diff_x, NRM_NRM); } else if (x2 - x > 1) { int w1 = 1 + bendpoint; int w2 = diff_x - w1; //int h = diff_x;// == 0 ? 0 : diff_x + 1; //int style = min_x == x ? APEX_DOT : DOT_APEX; //draw_vertical_line (c, x, y + 1, h1); draw_horizontal_line (c, x + 1, y, w1 + 1, y2 > y ? NRM_DOT : NRM_APEX); //draw_horizontal_line (c, min_x, y + bendpoint + 2, w, style); draw_vertical_line (c, x + 1 + w1, min_y + 1, diff_y - 1); //draw_vertical_line (c, x2, y + h1 + 1 + 1, h2); draw_horizontal_line (c, x + 1 + w1, y2, w2, y2 < y ? DOT_NRM : REV_APEX_NRM); } } c->attr = Color_RESET; }
void Canvas::draw_roundrect(uint8_t x, uint8_t y, uint8_t width, uint8_t height, uint8_t radius) { uint8_t diameter = 2 * radius; int16_t f = 1 - radius; int16_t dx = 1; int16_t dy = -diameter; int8_t rx = 0; int8_t ry = radius; // Adjust position, width and height x += radius; y += radius; width -= diameter; height -= diameter; // Draw the boundary rectangle draw_horizontal_line(x, y - radius, width + 1); draw_vertical_line(x + width + radius, y, height + 1); draw_vertical_line(x - radius, y, height + 1); draw_horizontal_line(x, y + height + radius, width + 1); // Draw the round corners while (rx < ry) { if (f >= 0) { ry--; dy += 2; f += dy; } rx++; dx += 2; f += dx; draw_pixel(x + rx + width, y - ry); draw_pixel(x + ry + width, y - rx); draw_pixel(x + rx + width, y + ry + height); draw_pixel(x + ry + width, y + rx + height); draw_pixel(x - rx, y + ry + height); draw_pixel(x - ry, y + rx + height); draw_pixel(x - rx, y - ry); draw_pixel(x - ry, y - rx); } }
void Canvas::fill_circle(uint8_t x, uint8_t y, uint8_t radius) { int16_t dx = 0, dy = radius; int16_t p = 1 - radius; while (dx <= dy) { draw_vertical_line(x + dx, y - dy, dy + dy); draw_vertical_line(x - dx, y - dy, dy + dy); draw_vertical_line(x + dy, y - dx, dx + dx); draw_vertical_line(x - dy, y - dx, dx + dx); dx++; if (p < 0) p = p + (dx << 1) + 1; else { dy--; p = p + ((dx - dy) << 1) + 1; } } }
void bmp_image::draw_rectangle(int x_min, int y_min, int x_max, int y_max, rgba_color_t color) { if ( x_min > x_max ) { std::swap( x_min, x_max ); } if ( y_min > y_max ) { std::swap( y_min, y_max ); } for ( int col = x_min; col <= x_max; ++col ) { draw_vertical_line(col, y_min, y_max, color); } }
int Leveler::draw() { Stroke (255, 128, 128, 0.5); StrokeWidth (2); draw_l_title ( ); draw_horizontal_tics( ); draw_vertical_line ( ); draw_x_label ( ); draw_y_label ( ); draw_marker( ); }
/* The following function divides the GLCD display panel into * equal number of rows based on the first value passed and * equal number of columns based on the second value passed * as arguments. */ draw_grid(int x, int y) { int horizontal_lines, vertical_lines; int i; horizontal_lines = GLCD_ROWS/x; for(i=0; i<(x+1); i++) { draw_horizontal_line(horizontal_lines*i); } vertical_lines = GLCD_COLUMNS/y; for(i=0; i<(x+1); i++) { draw_vertical_line(vertical_lines*i); } }
int Leveler::draw() { if (!Visible) return 0; Stroke (255, 128, 128, 0.5); StrokeWidth (2); draw_l_title ( ); draw_horizontal_tics( ); draw_vertical_line ( ); draw_x_label ( ); draw_y_label ( ); draw_marker ( ); return 1; }
void draw_grid(){ int hpos; //счётчик int ypos; //счётчик int grid_height=(cell_height+1)*row_num+1; int grid_width=(cell_width+1)*col_num+1; for (ypos=0;ypos<grid_width;ypos++){ if (ypos % (cell_width+1) == 0){ draw_vertical_line(pimg,ypos, grid_height); } } for (hpos=0;hpos<grid_height;hpos++){ if (hpos % (cell_height+1) == 0){ //+1 т.к. 1 пиксель между ячейками (граница) draw_horizontal_line(pimg,hpos, grid_width); } } }
void draw(t_env *e) { e->x = 0; while (e->x < SCREEN_W) { draw_init(e); calculate_step_and_initial_side_dist(e); perform_dda(e); calculate_dist_projected(e); calculate_wall(e); if (e->textured_wall) texturing_calculations(e); else wall_color(e); draw_vertical_line(e); e->x++; } if (e->textured_wall && e->map.max_x > 25 && e->map.y > 25) draw_sprite(e); }
void reset_terminal(void){ clear_terminal(); set_display_attribute(BAR_COLOUR); draw_horizontal_line(1,1,WIDTH); set_display_attribute(BAR_COLOUR); draw_vertical_line(40,1,HEIGHT); move_cursor(TITLE_X,TITLE_Y); printf_P(PSTR("FROGGER")); draw_lives(); draw_score(); draw_level(); draw_time(16); display_scores(); draw_status(0); draw_frog(); set_display_attribute(8); }
void bmp_image::draw_filled_circle(int x0, int y0, int radius, rgba_color_t color) { assert(radius >= 0); //Midpoint circle algorithm //std::cout << x0 << ", " << y0 << ", " << radius << ", " << std::hex << color << std::endl; int f = 1 - radius; int ddF_x = 1; int ddF_y = -2 * radius; int x = 0; int y = radius; draw_horizontal_line(y0, x0 - radius, x0 + radius, color); draw_vertical_line(x0, y0 - radius, y0 + radius, color); while(x < y) { if(f >= 0) { y--; ddF_y += 2; f += ddF_y; } x++; ddF_x += 2; f += ddF_x; draw_horizontal_line(y0 + y, x0 - x, x0 + x, color); draw_horizontal_line(y0 - y, x0 - x, x0 + x, color); draw_horizontal_line(y0 + x, x0 - y, x0 + y, color); draw_horizontal_line(y0 - x, x0 - y, x0 + y, color); } }
void Gradient::resize(float width, float height) { float w; if(direction == LEFT_RIGHT) w = width; else if(direction == TOP_BOTTOM) w = height; else assert(false); float dr = ((float) to.r - (float) from.r) / w; float dg = ((float) to.g - (float) from.g) / w; float db = ((float) to.b - (float) from.b) / w; float da = ((float) to.a - (float) from.a) / w; #if SDL_BYTEORDER == SDL_BIG_ENDIAN SDL_Surface* surface = SDL_CreateRGBSurface(SDL_SWSURFACE, (int) width, (int) height, 32, 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff); #else SDL_Surface* surface = SDL_CreateRGBSurface(SDL_SWSURFACE, (int) width, (int) height, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000); #endif if(surface == 0) throw std::runtime_error("Couldn't create SDL_Surface for gradient. " "(Out of memory?"); float r = from.r; float g = from.g; float b = from.b; float a = from.a; if(direction == LEFT_RIGHT) { for(int x = 0; x < (int) width; ++x) { draw_vertical_line(surface, x, 0, (int) height, lrintf(r), lrintf(g), lrintf(b), lrintf(a)); r += dr; g += dg; b += db; a += da; } } else { for(int y = 0; y < (int) height; ++y) { draw_horizontal_line(surface, 0, y, (int) width, lrintf(r), lrintf(g), lrintf(b), lrintf(a)); r += dr; g += dg; b += db; a += da; } } texture.reset(texture_manager->create(surface)); this->width = width; this->height = height; }
void clip_n_draw_vertical_line(PPM_Image &I, const PPM_Color &c, const int x, const int y1, const int y2) { const int h {I.height() - 1}; draw_vertical_line(I, c, x, std::min(std::max(0, y1), h), std::min(std::max(0, y2), h)); }
void Rectangle::doDraw(PPM_Image &I, const PPM_Color &c) const { const int x1 = p_.x(), x2 = x1 + w_, y1 = p_.y(), y2 = y1 + h_; const int w {I.width() - 1}, h {I.height() - 1}; const int xmin {std::min(std::max(0, x1), w)}; const int xmax {std::min(std::max(0, x2), w)}; const int ymin {std::min(std::max(0, y1), h)}; const int ymax {std::min(std::max(0, y2), h)}; const uint clr {c.color()}; /* drawing all sides: if the rectangle goes beyond the image size, then * drawing lines on the image border */ //for (auto x = xmin; x <= xmax; ++x) { // I[x][ymin] = clr; // I[x][ymax] = clr; //} //for (auto y = ymin; y <= ymax; ++y) { // I[xmin][y] = clr; // I[xmax][y] = clr; //} // avoid drawing lines on the border if (y1 >= 0) { if (y2 < h) for (auto x = xmin; x <= xmax; ++x) { I[x][y1] = clr; I[x][y2] = clr; } else if (y1 <= h) draw_horizontal_line(I, c, xmin, xmax, y1); //for (auto x = xmin; x <= xmax; ++x) // I[x][y1] = clr; } else if (y2 >= 0 && y2 < h) draw_horizontal_line(I, c, xmin, xmax, y2); //for (auto x = xmin; x <= xmax; ++x) // I[x][y2] = clr; if (x1 >= 0) { if (x2 < w) for (auto y = ymin; y <= ymax; ++y) { I[x1][y] = clr; I[x2][y] = clr; } else if (x1 <= w) draw_vertical_line(I, c, x1, ymin, ymax); //for (auto y = ymin; y <= ymax; ++y) // I[x1][y] = clr; } else if (x2 >= 0 && x2 < w) draw_vertical_line(I, c, x2, ymin, ymax); //for (auto y = ymin; y <= ymax; ++y) // I[x2][y] = clr; // the code below is shorter than above, but, perhaps, less efficient //if (y1 >= 0 && y1 < h) // draw_horizontal_line(I, c, xmin, xmax, y1); //if (y2 >= 0 && y2 < h) // draw_horizontal_line(I, c, xmin, xmax, y2); //if (x1 >= 0 && x1 < w) // draw_vertical_line(I, c, x1, ymin, ymax); //if (x2 >= 0 && x2 < w) // draw_vertical_line(I, c, x2, ymin, ymax); }
int main(int argv, char **argc) { robot_if_t ri; int major, minor, x_dist_diff, square_count, prev_square_area_1 = 0, prev_square_area_2 = 0; IplImage *image = NULL, *hsv = NULL, *threshold_1 = NULL, *threshold_2 = NULL, *final_threshold = NULL; squares_t *squares, *biggest_1, *biggest_2, , *pair_square_1, *pair_square_2, *sq_idx; bool same_square; bool hasPair = 0; square_count = 0; // Make sure we have a valid command line argument if(argv <= 1) { printf("Usage: robot_test <address of robot>\n"); exit(-1); } ri_api_version(&major, &minor); printf("Robot API Test: API Version v%i.%i\n", major, minor); // Setup the robot with the address passed in if(ri_setup(&ri, argc[1], 0)) { printf("Failed to setup the robot!\n"); exit(-1); } // Setup the camera if(ri_cfg_camera(&ri, RI_CAMERA_DEFAULT_BRIGHTNESS, RI_CAMERA_DEFAULT_CONTRAST, 5, RI_CAMERA_RES_640, RI_CAMERA_QUALITY_LOW)) { printf("Failed to configure the camera!\n"); exit(-1); } // Create a window to display the output //cvNamedWindow("Rovio Camera", CV_WINDOW_AUTOSIZE); cvNamedWindow("Biggest Square", CV_WINDOW_AUTOSIZE); cvNamedWindow("Thresholded", CV_WINDOW_AUTOSIZE); // Create an image to store the image from the camera image = cvCreateImage(cvSize(640, 480), IPL_DEPTH_8U, 3); // Create an image to store the HSV version in // We configured the camera for 640x480 above, so use that size here hsv = cvCreateImage(cvSize(640, 480), IPL_DEPTH_8U, 3); // And an image for each thresholded version threshold_1 = cvCreateImage(cvSize(640, 480), IPL_DEPTH_8U, 1); threshold_2 = cvCreateImage(cvSize(640, 480), IPL_DEPTH_8U, 1); final_threshold = cvCreateImage(cvSize(640, 480), IPL_DEPTH_8U, 1); // Move the head up to the middle position ri_move(&ri, RI_HEAD_MIDDLE, RI_FASTEST); // Action loop do { // Update the robot's sensor information if(ri_update(&ri) != RI_RESP_SUCCESS) { printf("Failed to update sensor information!\n"); continue; } // Get the current camera image and display it if(ri_get_image(&ri, image) != RI_RESP_SUCCESS) { printf("Unable to capture an image!\n"); continue; } //cvShowImage("Rovio Camera", image); // Convert the image from RGB to HSV cvCvtColor(image, hsv, CV_BGR2HSV); // Pick out the first range of pink color from the image cvInRangeS(hsv, RC_PINK_LOW_1, RC_PINK_HIGH_1, threshold_1); // Pick out the second range of pink color from the image cvInRangeS(hsv, RC_PINK_LOW_2, RC_PINK_HIGH_2, threshold_2); // compute the final threshold image by using cvOr cvOr(threshold_1, threshold_2, final_threshold, NULL); cvShowImage("Thresholded", final_threshold); // Find the squares in the image squares = ri_find_squares(final_threshold, RI_DEFAULT_SQUARE_SIZE); if( squares != NULL ) { printf("Sorting squares!\n"); sort_squares(squares); printf("Sort Complete!\n"); printAreas(squares); printf("Done printing"); //find biggest pair (if it exists) sq_idx = squares; while(sq_idx != NULL){ if(sq_idx->next == NULL) break; else if(isPair(sq_idx, sq_idx->next, 0.75)){ hasPair = 1; break; } sq_idx = sq_idx->next; } printf("Pair ID complete!\n"); if(hasPair){ printf("Pair found.\n"); //draw_green_X(sq_idx, image); //draw_green_X(sq_idx->next, image); biggest_1 = sq_idx; biggest_2 = sq_idx->next; } else { printf("Pair not found. Marking largest.\n"); draw_red_X(squares, image); //temporary: biggest_1 = squares; biggest_2 = squares; } hasPair = 0; } else { printf("No squares found.\n"); } hasPair = 0; if(biggest_1 != NULL){ draw_green_X(biggest_1, image); printf("Area 1 = %d", biggest_1->area); } //we only see the last pair of squares, go straight ahead until IR_Detect stops the robot if (square_count == 3){ ri_move(&ri, RI_MOVE_FORWARD, 1); if (ri_IR_Detected(&ri)) { square_count++; printf("Object detected, square_count = %d\n", square_count); } } //once the robot is at the intersection, rotate right until it detects a pair of squares else if(square_count == 4){ printf("Rotating\n"); if (biggest_1 != NULL && biggest_2 != NULL && (biggest_1->area - biggest_2->area) < 500){ square_count++; printf("New Path Found\n"); } ri_move(&ri, RI_TURN_RIGHT, 7); } else{ /* * If we only find a single usable largest square: * if square is on left of screen, turn right, strafe right * if square is on right of screen, turn left, strafe left */ if(biggest_1 != NULL && biggest_2 != NULL ) { draw_red_X(biggest_2, image); printf("\tArea 2 = %d\n", biggest_2->area); //get the difference in distance between the two biggest squares and the center vertical line x_dist_diff = get_square_diffence(biggest_1, biggest_2, image); get_diff_in_y(biggest_1, biggest_2); //when the camera can't detect a pair of squares, which means now the second biggest square //is much smaller than the first biggest square if ((biggest_1->area - biggest_2->area) > 500){ //if both squares are at the left side of the center line if (biggest_1->center.x < image->width/2 && biggest_2->center.x < image->width/2){ printf("rotate right at speed = 6\n"); ri_move(&ri, RI_TURN_RIGHT, 6); } //if both squares are at the right side of the center line else if (biggest_1->center.x > image->width/2 && biggest_2->center.x > image->width/2){ printf("rotate left at speed = 6\n"); ri_move(&ri, RI_TURN_LEFT, 6); } //if the center line is in the middle of the two biggest squares else if (biggest_1->center.x < image->width/2 && biggest_2->center.x > image->width/2 ){ printf("rotate right at speed = 2\n"); ri_move(&ri, RI_TURN_RIGHT, 2); } else{ printf("rotate left at speed = 2\n"); ri_move(&ri, RI_TURN_LEFT, 2); } } else{ //increment square_count whenever the robot pass by a pair of squares if (prev_square_area_1 != 0 && prev_square_area_2 != 0 && biggest_1->area < prev_square_area_1 && biggest_2->area < prev_square_area_2 ){ square_count++; printf("square count = %d\n", square_count); } //rotate to the left if (x_dist_diff < -40){ printf("rotate left at speed = 6\n"); ri_move(&ri, RI_TURN_LEFT, 6); } //rotate to the right else if (x_dist_diff > 40){ printf("rotate right at speed = 6\n"); ri_move(&ri, RI_TURN_RIGHT, 6); } prev_square_area_1 = biggest_1->area; prev_square_area_2 = biggest_2->area; } ri_move(&ri, RI_MOVE_FORWARD, 5); } //once the camera can't detect any squares, make the robot go backwards else if (biggest_1 == NULL && biggest_2 == NULL){ printf("Move Backwards\n"); ri_move(&ri, RI_MOVE_BACKWARD , 1); } } // display a straight vertical line draw_vertical_line(image); // Display the image with the drawing oon ito cvShowImage("Biggest Square", image); // Update the UI (10ms wait) cvWaitKey(10); // Release the square data while(squares != NULL) { sq_idx = squares->next; free(squares); squares = sq_idx; } biggest_1 = NULL; biggest_2 = NULL; // Move forward unless there's something in front of the robot /*if(!ri_IR_Detected(&ri)) ri_move(&ri, RI_MOVE_FORWARD, RI_SLOWEST);*/ //printf("Loop Complete\n"); //getc(stdin); } while(1); // Clean up (although we'll never get here...) //cvDestroyWindow("Rovio Camera"); cvDestroyWindow("Biggest Square"); cvDestroyWindow("Thresholded"); // Free the images cvReleaseImage(&threshold_1); cvReleaseImage(&threshold_2); cvReleaseImage(&final_threshold); cvReleaseImage(&hsv); cvReleaseImage(&image); return 0; }