int PathPlanner::runRRT(){
	this->RRT();
	calcPathLength();
	writePath();
	writeMetadata();
	cout<<"Estimated path length: "<<this->pathLength<<"\n";
	return 0;
}
int PathPlanner::runSquareSpiral(){
	Points spiralpath = this->getSpiralPath();	
	this->setPath(spiralpath);
	calcPathLength();
	writePath();
	writeMetadata();
	cout<<"Estimated path length: "<<this->pathLength<<"\n";
	return 0;
}
//In a perfect world these would have some kind of error checking. I like to live dangerously....
int PathPlanner::runTrace(){
	vector<Polygon_2> all = this->linearShrink();
	this->setPath(all);
	calcPathLength();
	writePath();
	writeMetadata();
	cout<<"Estimated path length: "<<this->pathLength<<"\n";
	return 0;
}
    /*
     * first_is_already_merged == false
     *
     *       o     o
     *      /     /
     *     /     /
     *    /  +  /      --->   -(t)-o-----o
     *   /     /
     *  /     /
     * o     o
     *
     * travel (t) to first location is done through first_path_start_changed and new_first_path_start.
     * this gets rid of the tiny "blips". Depending on the merged line distance a small gap may appear, but this is
     * accounted for in the volume.
     *
     * first_is_already_merged == true
     *
     *                   o
     *                  /
     *                 /
     *    o-----o  +  /     --->    o-----------o   or with slight   o-----o-----o
     *   /           /             /                   bend         /
     *  /           /             /                                /
     * o           o             o                                o
     *
     */
    bool MergeInfillLines::mergeLinesSideBySide(const bool first_is_already_merged, GCodePath& first_path, const Point first_path_start, GCodePath& second_path, const Point second_path_start, Point& new_first_path_start, coord_t& error_area) const
    {
        Point average_first_path;

        coord_t first_path_length = calcPathLength(first_path_start, first_path);
        coord_t first_path_length_flow = first_path_length * first_path.flow; //To get the volume we don't need to include the line width since it's the same for both lines.
        const coord_t line_width = first_path.config->getLineWidth();

        if (first_is_already_merged)
        {
            // take second point of path, first_path.points[0]
            average_first_path = first_path.points[0];
        }
        else
        {
            average_first_path += first_path_start;
            for (const Point point : first_path.points)
            {
                average_first_path += point;
            }
            average_first_path /= (first_path.points.size() + 1);
        }

        coord_t second_path_length = calcPathLength(second_path_start, second_path);
        Point average_second_path = second_path_start;
        for (const Point point : second_path.points)
        {
            average_second_path += point;
        }
        coord_t second_path_length_flow = second_path_length *= second_path.flow;
        average_second_path /= (coord_t) (second_path.points.size() + 1);

        // predict new length and flow and if the new flow is to big, don't merge. conditions in this part must exactly match the actual merging
        coord_t new_path_length = first_path_length;
        coord_t dist2_from_line = 0;
        coord_t new_error_area = 0;
        coord_t merged_part_length = 0;
        if (first_is_already_merged)
        {
            // check if the new point is a good extension of last part of existing polyline
            // because of potential accumulation of errors introduced each time a line is merged, we do not allow any error.
            if (first_path.points.size() > 1) {
                dist2_from_line = LinearAlg2D::getDist2FromLine(average_second_path, first_path.points[first_path.points.size() - 2], first_path.points[first_path.points.size() - 1]);
                merged_part_length = vSize(first_path.points[first_path.points.size() - 2] - average_second_path);
                new_error_area = sqrt(dist2_from_line) * merged_part_length / 2;
            }
            // The max error margin uses the meshfix_maximum_resolution setting
            if (first_path.points.size() > 1 && error_area + new_error_area < merged_part_length * maximum_resolution)
            {
                new_path_length -= vSize(first_path.points[first_path.points.size() - 2] - first_path.points[first_path.points.size() - 1]);
                new_path_length += vSize(first_path.points[first_path.points.size() - 2] - average_second_path);
            }
            else
            {
                new_path_length += vSize(first_path.points[first_path.points.size() - 1] - average_second_path);
            }
        }
        else
        {
            new_path_length -= vSize(first_path.points.back() - first_path_start);
            new_path_length += vSize(average_second_path - average_first_path);
        }
        double new_flow = ((first_path_length_flow + second_path_length_flow) / static_cast<double>(new_path_length));
        if (new_flow > 2 * nozzle_size / line_width)  // line width becomes too wide.
        {
            return false;
        }

        // do the actual merging
        if (first_is_already_merged)
        {
            // check if the new point is a good extension of last part of existing polyline
            // because of potential accumulation of errors introduced each time a line is merged, we do not allow any error.
            if (first_path.points.size() > 1 && error_area + new_error_area < line_width * line_width)
            {
                first_path.points[first_path.points.size() - 1] = average_second_path;
                error_area += new_error_area;
            } else {
                first_path.points.push_back(average_second_path);
                error_area = 0;
            }
        }
        else
        {
            new_first_path_start = average_first_path;
            first_path.points.clear();
            first_path.points.push_back(average_second_path);
            error_area = 0;
        }

        first_path.flow = static_cast<double>(first_path_length_flow + second_path_length_flow) / new_path_length;

        return true;
    }