示例#1
0
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);
  }
}