Example #1
0
void calculateContour(const cv::Mat& image, std::vector<std::vector<geo::Vec2i> >& contours)
{
    cv::Mat contour_map(image.rows, image.cols, CV_8UC1, cv::Scalar(0));

    for(int y = 0; y < image.rows; ++y)
    {
        for(int x = 0; x < image.cols; ++x)
        {
            unsigned char v = image.at<unsigned char>(y, x);

            if (v == 0)
                continue;

            contours.push_back(std::vector<geo::Vec2i>());
            std::vector<geo::Vec2i>& points = contours.back();

            std::vector<geo::Vec2i> line_starts;
            findContours(image, geo::Vec2i(x, y), 0, points, line_starts, contour_map, true);

            unsigned int num_points = points.size();

            if (num_points <= 2)
            {
                contours.pop_back();
                continue;
            }

            // Check for holes within the contour
            for(unsigned int i = 0; i < line_starts.size(); ++i)
            {
                int x2 = line_starts[i].x;
                int y2 = line_starts[i].y;

                while(image.at<unsigned char>(y2, x2) == v)
                    ++x2;

                if (contour_map.at<unsigned char>(y2, x2 - 1) != 0)
                    continue;

                // found a hole, so find the contours of this hole

                contours.push_back(std::vector<geo::Vec2i>());
                std::vector<geo::Vec2i>& hole_points = contours.back();

                findContours(image, geo::Vec2i(x2 - 1, y2 + 1), 1, hole_points, line_starts, contour_map, false);

                if (hole_points.size() <= 2)
                {
                    contours.pop_back();
                    continue;
                }
            }

            // Remove the shape
            cv::floodFill(image, cv::Point(x, y), 0);
        }
    }
}
//TODO:
//TODO:  Use libnoise http://libnoise.sourceforge.net/tutorials/index.html !!!
//TODO:
void generate()
{

	//set crop height and width
	if (crop_height < 1)
		crop_height = tmap_size;
	if (crop_width < 1)
		crop_width = tmap_size;

	//if a crop value is set
	//set tmap_size to fit the cropped values
	int max_size = std::max(crop_height, crop_width);
	int max_size_tmp = max_size - 1;

	if ((max_size_tmp & (max_size_tmp - 1)) == 0)
	{
		//leave set size as highest crop value
		tmap_size = max_size;
	}
	else
	{
		//find smallest value such that (value is power of 2) + 1 and value > max_size
		int t = ceil(log2(max_size)) + 1;
		tmap_size = (1 << t) + 1;
	}

	double finish = 0;
	//display info
	if (verbose)
	{
		std::cout << "Using " << config_file << std::endl;
		std::cout << "Staring square diamond" << std::endl;
		std::cout << "Size: " << crop_width << " x " << crop_height
				<< " original size " << tmap_size << std::endl;
		std::cout << "Starting seed value " << seed << std::endl;
		std::cout << "Starting random offset " << random_offset << std::endl;
		std::cout << "Random offset decrease ratio " << offset_dr << std::endl;

	}

	//init map array
	tmap = new int*[tmap_size];
	for (int i = 0; i < tmap_size; ++i)
	{
		tmap[i] = new int[tmap_size];
		for (int j = 0; j < tmap_size; j++)
			tmap[i][j] = 0;
	}

//	initialize random seed:
//	use for generating a random map every time
//  srand ( time(NULL) );
	//harcoded for now as produces a nice map for testing
	srand(12);

	//fill the array with values
	square_diamond();

	//interpolate voronoi diagram
	//TODO: add noise to voronoi
	if (verbose)
	{
		std::cout << "Voronoi points " << voronoi_size << std::endl;
		/*
		 for (int i = 0; i < voronoi_size; ++i) {
		 std::cout << "\t" << voronoi_points[i][0] << "," << voronoi_points[i][1] << std::endl;
		 }
		 */
	}
	voronoi();

	erosion();

	if (!neg)
		clear_neg();

//		finish = clock() - start;
	if (verbose)
		std::cout << "Finished square diamond " << (finish / 1000000)
				<< std::endl;
	double sqadia = (finish / 1000000);

	if (normalise)
	{
		if (verbose)
			std::cout << "Normalising with value range " << normalise_min << "-"
					<< normalise_max << std::endl;
		normalise_map();
	}

	if (output_format == STANDRARD_HEIGHTS)
	{
		print_map(fopen(output_file.c_str(), "w"));
	}
	else if (output_format == STANDARD_XML)
	{
		print_map_xml(fopen(output_file.c_str(), "w"));
	}

	if (scale > 0 && crop_height > 256 && crop_width > 256)
	{

//			start = clock();
		if (verbose)
			std::cout << "Generating rivers" << std::endl;
		rivers();
//			finish = clock() - start;
		if (verbose)
			std::cout << "Done " << (finish / 1000000) << std::endl;
		double rivers_time = (finish / 1000000);
		print_rivers(0);

//			start = clock();
		if (verbose)
			std::cout << "Generating vegetation" << std::endl;
		vegetation(verbose);
//			finish = clock() - start;
		if (verbose)
			std::cout << "Done " << (finish / 1000000) << std::endl;
		double veg_time = (finish / 1000000);
		print_vegetation(0);

		if (verbose)
			std::cout << "Generating settlements" << std::endl;
		settlements();
//			finish = clock() - start;
		if (verbose)
			std::cout << "Done " << (finish / 1000000) << std::endl;
		double settlement_time = (finish / 1000000);
		print_settlements(0);

		std::cout << crop_height << "\t"
				<< (sqadia + rivers_time + veg_time + settlement_time) << "\t"
				<< sqadia << "\t " << rivers_time << "\t" << veg_time << "\t"
				<< settlement_time << std::endl;
	}

	std::cout << "Drawing contours" << std::endl;
	contour_map(32, 32, verbose);
	print_contour(0);
	print_kf(0);

}