int main(int argc, char* argv[]) { if (argc != 5) { std::cerr << "Usage: " << argv[0] << " input.ppm output.ppm distance_field_method visualization_style" << std::endl; exit(1); } // open the input image Image<Color> input; if (!input.Load(argv[1])) { std::cerr << "ERROR: Cannot open input file: " << argv[1] << std::endl; exit(1); } // a place to write the distance values Image<DistancePixel> distance_image; distance_image.Allocate(input.Width(),input.Height()); // calculate the distance field (each function returns the maximum distance value) double max_distance = 0; if (std::string(argv[3]) == std::string("naive_method")) { max_distance = NaiveDistanceFieldMethod(input,distance_image); } else if (std::string(argv[3]) == std::string("improved_method")) { max_distance = ImprovedDistanceFieldMethod(input,distance_image); } else if (std::string(argv[3]) == std::string("pq_with_map")) { max_distance = FastMarchingMethod(input,distance_image); } else if (std::string(argv[3]) == std::string("pq_with_hash_table")) { // EXTRA CREDIT: implement FastMarchingMethod with a hash table } else { std::cerr << "ERROR: Unknown distance field method: " << argv[3] << std::endl; exit(1); } // convert distance values to a visualization Image<Color> output; output.Allocate(input.Width(),input.Height()); for (int i = 0; i < input.Width(); i++) { for (int j = 0; j < input.Height(); j++) { double v = distance_image.GetPixel(i,j).getValue(); if (std::string(argv[4]) == std::string("greyscale")) { output.SetPixel(i,j,GreyBands(v,max_distance*1.01,1)); } else if (std::string(argv[4]) == std::string("grey_bands")) { output.SetPixel(i,j,GreyBands(v,max_distance,4)); } else if (std::string(argv[4]) == std::string("rainbow")) { output.SetPixel(i,j,Rainbow(v,max_distance)); } else { // EXTRA CREDIT: create other visualizations std::cerr << "ERROR: Unknown visualization style" << std::endl; exit(0); } } } // save output if (!output.Save(argv[2])) { std::cerr << "ERROR: Cannot save to output file: " << argv[2] << std::endl; exit(1); } return 0; }
//--------------------------------------------------------------------------- void WtShapeGroupWidget::paintEvent(Wt::WPaintDevice *paintDevice) { Wt::WPainter painter(paintDevice); const int width = this->width().toPixels(); const int height = this->height().toPixels(); //Draw a background rectangle { Wt::WPen pen = painter.pen(); pen.setColor(Wt::WColor(1,1,1)); painter.setPen(pen); painter.setBrush(Wt::WBrush(Wt::WColor(254,254,254))); painter.drawRect(0.0,0.0,width,height); } if (m_v.empty()) return; const double mid_x = 0.5 * boost::numeric_cast<double>(width); const double mid_y = 0.5 * boost::numeric_cast<double>(height); const double ray_center = std::min(mid_x,mid_y); const double ray_group = 0.33 * ray_center; const double ray_member = 0.33 * ray_group; const int n_groups = boost::numeric_cast<double>(m_v.size()); for (int group=0; group!=n_groups; ++group) { //Draw the larger (group) circles first //Set the pen to black { Wt::WPen pen = painter.pen(); pen.setColor(Wt::WColor(1,1,1)); painter.setPen(pen); } const double f_group = (n_groups != 0 ? static_cast<double>(group) / static_cast<double>(n_groups) : 1.0); //Set the brush to the group's index { double r,g,b; Rainbow(f_group,r,g,b); painter.setBrush(Wt::WBrush(Wt::WColor(r*255.0,g*255.0,b*255.0))); } const double angle = 2.0 * M_PI * f_group; const double group_mid_x = mid_x + (std::sin(angle) * 0.66 * ray_center); const double group_mid_y = mid_y - (std::cos(angle) * 0.66 * ray_center); //Draw the group ellipse painter.drawEllipse( group_mid_x - ray_group, group_mid_y - ray_group, 2.0 * ray_group, 2.0 * ray_group); const std::vector<const Shape*>& members = m_v[group]; const int n_members = boost::numeric_cast<int>(members.size()); for (int member=0; member!=n_members;++member) { const double f_member = (n_members != 0 ? static_cast<double>(member) / static_cast<double>(n_members) : 1.0); const double angle = 2.0 * M_PI * f_member; const double member_mid_x = group_mid_x + (std::sin(angle) * 0.66 * ray_group); const double member_mid_y = group_mid_y - (std::cos(angle) * 0.66 * ray_group); //Draw the member his/her Shape ellipse WtShapeWidget::DrawShape(painter, member_mid_x - ray_member, member_mid_y - ray_member, 2.0 * ray_member, 2.0 * ray_member, members[member]); } } }
//--------------------------------------------------------------------------- void TFormSimBrainiacMain::DrawBrainiac( const Brainiac& brainiac) const { assert(brainiac.pCorrectAnswer >= 0.0 && brainiac.pCorrectAnswer < 1.0); assert(brainiac.pHasQuestion >= 0.0 && brainiac.pHasQuestion < 1.0); //Assumes that 'image' already contains a globe! const int width = ImageBrainiac->Picture->Bitmap->Width; const int height = ImageBrainiac->Picture->Bitmap->Height; const int midX = width / 2; const int midY = height / 2; const int midX2 = midX / 2; const int midY2 = midY / 2; const unsigned char greyCorrectAnswer = static_cast<unsigned char>( 1.0 + (brainiac.pCorrectAnswer * 254.0) ); const unsigned char greyHasQuestion = static_cast<unsigned char>( 1.0 + (brainiac.pHasQuestion * 254.0) ); const int x1 = midX-midX2; const int y1 = midY-midY2; const int x2 = midX+midX2; const int y2 = midY+midY2; assert(x1 >= 0); assert(x1 < width); assert(y1 >= 0); assert(y1 < height); assert(x2 >= 0); assert(x2 < width); assert(y2 >= 0); assert(y2 < height); if (mUseGrey==true) { //Grey SetPixel(ImageBrainiac, x1, y1, midX, midY, greyCorrectAnswer,greyCorrectAnswer,greyCorrectAnswer); //Rainbow(brainiac.pHasQuestion,r,g,b); SetPixel(ImageBrainiac, midX, midY, x2, y2, greyHasQuestion,greyHasQuestion,greyHasQuestion); } else { //Rainbow unsigned char r,g,b; Rainbow(brainiac.pCorrectAnswer,r,g,b); SetPixel(ImageBrainiac, x1, y1, midX, midY, r,g,b); Rainbow(brainiac.pHasQuestion,r,g,b); SetPixel(ImageBrainiac, midX, midY, x2, y2, r,g,b); } }