예제 #1
0
Curve *EllipticalArc::transformed(Affine const& m) const
{
    Ellipse e(center(X), center(Y), ray(X), ray(Y), _rot_angle);
    Ellipse et = e.transformed(m);
    Point inner_point = pointAt(0.5);
    return et.arc( initialPoint() * m,
                                  inner_point * m,
                                  finalPoint() * m,
                                  isSVGCompliant() );
}
예제 #2
0
파일: path.cpp 프로젝트: Spin0za/inkscape
void Path::do_append(Curve *c) {
  boost::shared_ptr<Curve> curve(c);
  if ( get_curves().front().get() == final_ ) {
    final_->setPoint(1, curve->initialPoint());
  } else {
    if (curve->initialPoint() != finalPoint()) {
      THROW_CONTINUITYERROR();
    }
  }
  get_curves().insert(get_curves().end()-1, curve);
  final_->setPoint(0, curve->finalPoint());
}
예제 #3
0
파일: path.cpp 프로젝트: Spin0za/inkscape
Path &Path::operator*=(Affine const &m) {
  unshare();
  Sequence::iterator last = get_curves().end() - 1;
  Sequence::iterator it;
  Point prev;
  for (it = get_curves().begin() ; it != last ; ++it) {
    *it = boost::shared_ptr<Curve>((*it)->transformed(m));
    if ( it != get_curves().begin() && (*it)->initialPoint() != prev ) {
      THROW_CONTINUITYERROR();
    }
    prev = (*it)->finalPoint();
  }
  for ( int i = 0 ; i < 2 ; ++i ) {
    final_->setPoint(i, (*final_)[i] * m);
  }
  if (get_curves().size() > 1) {
    if ( front().initialPoint() != initialPoint() || back().finalPoint() != finalPoint() ) {
      THROW_CONTINUITYERROR();
    }
  }
  return *this;
}
예제 #4
0
D2<SBasis> EllipticalArc::toSBasis() const
{
    D2<SBasis> arc;
    // the interval of parametrization has to be [0,1]
    Coord et = initialAngle().radians() + ( _sweep ? sweepAngle() : -sweepAngle() );
    Linear param(initialAngle(), et);
    Coord cos_rot_angle, sin_rot_angle;
    sincos(_rot_angle, sin_rot_angle, cos_rot_angle);

    // order = 4 seems to be enough to get a perfect looking elliptical arc
    SBasis arc_x = ray(X) * cos(param,4);
    SBasis arc_y = ray(Y) * sin(param,4);
    arc[0] = arc_x * cos_rot_angle - arc_y * sin_rot_angle + Linear(center(X),center(X));
    arc[1] = arc_x * sin_rot_angle + arc_y * cos_rot_angle + Linear(center(Y),center(Y));

    // ensure that endpoints remain exact
    for ( int d = 0 ; d < 2 ; d++ ) {
        arc[d][0][0] = initialPoint()[d];
        arc[d][0][1] = finalPoint()[d];
    }

    return arc;
}
예제 #5
0
/*
 * NOTE: this implementation follows Standard SVG 1.1 implementation guidelines
 * for elliptical arc curves. See Appendix F.6.
 */
void EllipticalArc::_updateCenterAndAngles(bool svg)
{
    Point d = initialPoint() - finalPoint();

    // TODO move this to SVGElipticalArc?
    if (svg)
    {
        if ( initialPoint() == finalPoint() )
        {
            _rot_angle = _start_angle = _end_angle = 0;
            _center = initialPoint();
            _rays = Geom::Point(0,0);
            _large_arc = _sweep = false;
            return;
        }

        _rays[X] = std::fabs(_rays[X]);
        _rays[Y] = std::fabs(_rays[Y]);

        if ( are_near(ray(X), 0) || are_near(ray(Y), 0) )
        {
            _rays[X] = L2(d) / 2;
            _rays[Y] = 0;
            _rot_angle = std::atan2(d[Y], d[X]);
            _start_angle = 0;
            _end_angle = M_PI;
            _center = middle_point(initialPoint(), finalPoint());
            _large_arc = false;
            _sweep = false;
            return;
        }
    }
    else
    {
        if ( are_near(initialPoint(), finalPoint()) )
        {
            if ( are_near(ray(X), 0) && are_near(ray(Y), 0) )
            {
                _start_angle = _end_angle = 0;
                _center = initialPoint();
                return;
            }
            else
            {
                THROW_RANGEERROR("initial and final point are the same");
            }
        }
        if ( are_near(ray(X), 0) && are_near(ray(Y), 0) )
        { // but initialPoint != finalPoint
            THROW_RANGEERROR(
                "there is no ellipse that satisfies the given constraints: "
                "ray(X) == 0 && ray(Y) == 0 but initialPoint != finalPoint"
            );
        }
        if ( are_near(ray(Y), 0) )
        {
            Point v = initialPoint() - finalPoint();
            if ( are_near(L2sq(v), 4*ray(X)*ray(X)) )
            {
                Angle angle(v);
                if ( are_near( angle, _rot_angle ) )
                {
                    _start_angle = 0;
                    _end_angle = M_PI;
                    _center = v/2 + finalPoint();
                    return;
                }
                angle -= M_PI;
                if ( are_near( angle, _rot_angle ) )
                {
                    _start_angle = M_PI;
                    _end_angle = 0;
                    _center = v/2 + finalPoint();
                    return;
                }
                THROW_RANGEERROR(
                    "there is no ellipse that satisfies the given constraints: "
                    "ray(Y) == 0 "
                    "and slope(initialPoint - finalPoint) != rotation_angle "
                    "and != rotation_angle + PI"
                );
            }
            if ( L2sq(v) > 4*ray(X)*ray(X) )
            {
                THROW_RANGEERROR(
                    "there is no ellipse that satisfies the given constraints: "
                    "ray(Y) == 0 and distance(initialPoint, finalPoint) > 2*ray(X)"
                );
            }
            else
            {
                THROW_RANGEERROR(
                    "there is infinite ellipses that satisfy the given constraints: "
                    "ray(Y) == 0  and distance(initialPoint, finalPoint) < 2*ray(X)"
                );
            }

        }

        if ( are_near(ray(X), 0) )
        {
            Point v = initialPoint() - finalPoint();
            if ( are_near(L2sq(v), 4*ray(Y)*ray(Y)) )
            {
                double angle = std::atan2(v[Y], v[X]);
                if (angle < 0) angle += 2*M_PI;
                double rot_angle = _rot_angle.radians() + M_PI/2;
                if ( !(rot_angle < 2*M_PI) ) rot_angle -= 2*M_PI;
                if ( are_near( angle, rot_angle ) )
                {
                    _start_angle = M_PI/2;
                    _end_angle = 3*M_PI/2;
                    _center = v/2 + finalPoint();
                    return;
                }
                angle -= M_PI;
                if ( angle < 0 ) angle += 2*M_PI;
                if ( are_near( angle, rot_angle ) )
                {
                    _start_angle = 3*M_PI/2;
                    _end_angle = M_PI/2;
                    _center = v/2 + finalPoint();
                    return;
                }
                THROW_RANGEERROR(
                    "there is no ellipse that satisfies the given constraints: "
                    "ray(X) == 0 "
                    "and slope(initialPoint - finalPoint) != rotation_angle + PI/2 "
                    "and != rotation_angle + (3/2)*PI"
                );
            }
            if ( L2sq(v) > 4*ray(Y)*ray(Y) )
            {
                THROW_RANGEERROR(
                    "there is no ellipse that satisfies the given constraints: "
                    "ray(X) == 0 and distance(initialPoint, finalPoint) > 2*ray(Y)"
                );
            }
            else
            {
                THROW_RANGEERROR(
                    "there is infinite ellipses that satisfy the given constraints: "
                    "ray(X) == 0  and distance(initialPoint, finalPoint) < 2*ray(Y)"
                );
            }

        }

    }

    Rotate rm(_rot_angle);
    Affine m(rm);
    m[1] = -m[1];
    m[2] = -m[2];

    Point p = (d / 2) * m;
    double rx2 = _rays[X] * _rays[X];
    double ry2 = _rays[Y] * _rays[Y];
    double rxpy = _rays[X] * p[Y];
    double rypx = _rays[Y] * p[X];
    double rx2py2 = rxpy * rxpy;
    double ry2px2 = rypx * rypx;
    double num = rx2 * ry2;
    double den = rx2py2 + ry2px2;
    assert(den != 0);
    double rad = num / den;
    Point c(0,0);
    if (rad > 1)
    {
        rad -= 1;
        rad = std::sqrt(rad);

        if (_large_arc == _sweep) rad = -rad;
        c = rad * Point(rxpy / ray(Y), -rypx / ray(X));

        _center = c * rm + middle_point(initialPoint(), finalPoint());
    }
    else if (rad == 1 || svg)
    {
        double lamda = std::sqrt(1 / rad);
        _rays[X] *= lamda;
        _rays[Y] *= lamda;
        _center = middle_point(initialPoint(), finalPoint());
    }
    else
    {
        THROW_RANGEERROR(
            "there is no ellipse that satisfies the given constraints"
        );
    }

    Point sp((p[X] - c[X]) / ray(X), (p[Y] - c[Y]) / ray(Y));
    Point ep((-p[X] - c[X]) / ray(X), (-p[Y] - c[Y]) / ray(Y));
    Point v(1, 0);
    _start_angle = angle_between(v, sp);
    double sweep_angle = angle_between(sp, ep);
    if (!_sweep && sweep_angle > 0) sweep_angle -= 2*M_PI;
    if (_sweep && sweep_angle < 0) sweep_angle += 2*M_PI;

    _end_angle = _start_angle;
    _end_angle += sweep_angle;
}
예제 #6
0
std::vector<Coord> EllipticalArc::roots(Coord v, Dim2 d) const
{
    std::vector<Coord> sol;

    if ( are_near(ray(X), 0) && are_near(ray(Y), 0) ) {
        if ( center(d) == v )
            sol.push_back(0);
        return sol;
    }

    static const char* msg[2][2] =
    {
        { "d == X; ray(X) == 0; "
          "s = (v - center(X)) / ( -ray(Y) * std::sin(_rot_angle) ); "
          "s should be contained in [-1,1]",
          "d == X; ray(Y) == 0; "
          "s = (v - center(X)) / ( ray(X) * std::cos(_rot_angle) ); "
          "s should be contained in [-1,1]"
        },
        { "d == Y; ray(X) == 0; "
          "s = (v - center(X)) / ( ray(Y) * std::cos(_rot_angle) ); "
          "s should be contained in [-1,1]",
          "d == Y; ray(Y) == 0; "
          "s = (v - center(X)) / ( ray(X) * std::sin(_rot_angle) ); "
          "s should be contained in [-1,1]"
        },
    };

    for ( unsigned int dim = 0; dim < 2; ++dim )
    {
        if ( are_near(ray((Dim2) dim), 0) )
        {
            if ( initialPoint()[d] == v && finalPoint()[d] == v )
            {
                THROW_INFINITESOLUTIONS(0);
            }
            if ( (initialPoint()[d] < finalPoint()[d])
                 && (initialPoint()[d] > v || finalPoint()[d] < v) )
            {
                return sol;
            }
            if ( (initialPoint()[d] > finalPoint()[d])
                 && (finalPoint()[d] > v || initialPoint()[d] < v) )
            {
                return sol;
            }
            double ray_prj = 0.0;
            switch(d)
            {
                case X:
                    switch(dim)
                    {
                        case X: ray_prj = -ray(Y) * std::sin(_rot_angle);
                                break;
                        case Y: ray_prj = ray(X) * std::cos(_rot_angle);
                                break;
                    }
                    break;
                case Y:
                    switch(dim)
                    {
                        case X: ray_prj = ray(Y) * std::cos(_rot_angle);
                                break;
                        case Y: ray_prj = ray(X) * std::sin(_rot_angle);
                                break;
                    }
                    break;
            }

            double s = (v - center(d)) / ray_prj;
            if ( s < -1 || s > 1 )
            {
                THROW_LOGICALERROR(msg[d][dim]);
            }
            switch(dim)
            {
                case X:
                    s = std::asin(s); // return a value in [-PI/2,PI/2]
                    if ( logical_xor( _sweep, are_near(initialAngle(), M_PI/2) )  )
                    {
                        if ( s < 0 ) s += 2*M_PI;
                    }
                    else
                    {
                        s = M_PI - s;
                        if (!(s < 2*M_PI) ) s -= 2*M_PI;
                    }
                    break;
                case Y:
                    s = std::acos(s); // return a value in [0,PI]
                    if ( logical_xor( _sweep, are_near(initialAngle(), 0) ) )
                    {
                        s = 2*M_PI - s;
                        if ( !(s < 2*M_PI) ) s -= 2*M_PI;
                    }
                    break;
            }

            //std::cerr << "s = " << rad_to_deg(s);
            s = map_to_01(s);
            //std::cerr << " -> t: " << s << std::endl;
            if ( !(s < 0 || s > 1) )
                sol.push_back(s);
            return sol;
        }
    }

    double rotx, roty;
    sincos(_rot_angle, roty, rotx);
    if (d == X) roty = -roty;

    double rxrotx = ray(X) * rotx;
    double c_v = center(d) - v;

    double a = -rxrotx + c_v;
    double b = ray(Y) * roty;
    double c = rxrotx + c_v;
    //std::cerr << "a = " << a << std::endl;
    //std::cerr << "b = " << b << std::endl;
    //std::cerr << "c = " << c << std::endl;

    if ( are_near(a,0) )
    {
        sol.push_back(M_PI);
        if ( !are_near(b,0) )
        {
            double s = 2 * std::atan(-c/(2*b));
            if ( s < 0 ) s += 2*M_PI;
            sol.push_back(s);
        }
    }
    else
    {
        double delta = b * b - a * c;
        //std::cerr << "delta = " << delta << std::endl;
        if ( are_near(delta, 0) )
        {
            double s = 2 * std::atan(-b/a);
            if ( s < 0 ) s += 2*M_PI;
            sol.push_back(s);
        }
        else if ( delta > 0 )
        {
            double sq = std::sqrt(delta);
            double s = 2 * std::atan( (-b - sq) / a );
            if ( s < 0 ) s += 2*M_PI;
            sol.push_back(s);
            s = 2 * std::atan( (-b + sq) / a );
            if ( s < 0 ) s += 2*M_PI;
            sol.push_back(s);
        }
    }

    std::vector<double> arc_sol;
    for (unsigned int i = 0; i < sol.size(); ++i )
    {
        //std::cerr << "s = " << rad_to_deg(sol[i]);
        sol[i] = map_to_01(sol[i]);
        //std::cerr << " -> t: " << sol[i] << std::endl;
        if ( !(sol[i] < 0 || sol[i] > 1) )
            arc_sol.push_back(sol[i]);
    }
    return arc_sol;
}
예제 #7
0
int main(int argc, char ** argv)
{
	const std::string patchParamsFilename = argv[1];
	const std::string testDataFilename = argv[2];
	const std::string valveDataFilename = "/home/om0000/ValveTracking/TrainingData/MV-Planes.hdf5";
	PatchParams params(patchParamsFilename);

	TestData::Pointer testData = TestData::Initialise(testDataFilename);
	LengthData::Pointer lengthData = LengthData::Load("/home/om0000/ValveTracking/TrainingData/Lengths");
	lengthData->Prepare(testData->GetId());

	std::cout << "Loading Plane Data" << std::endl;
	ValveTrainingData::Pointer valveData = ValveTrainingData::Load(valveDataFilename);


	std::cout << "Loading PatchData" << std::endl;
	//PatchTrainingData::Pointer patchData = PatchTrainingData::Load(patchParamsFilename);
	PatchTrainingData::Pointer patchData = PatchTrainingData::New();

	VectorType startPoint, startNormal;


	for(unsigned int runs = 0; runs < 1; runs++)
	{
		
		for(params.timeStep = 0; params.timeStep < params.numberOfTimeSteps; params.timeStep++)
		{


			std::cout << "Working on: " << params.timeStep << std::endl;


			// load the input points and create the bounding box
			MatrixType pointsData;
			valveData->GetTrainingPoints(testData->GetId(), params.timeStep, pointsData);
			
			std::vector<MatrixType> pointsData2;
			valveData->GetTrainingPoints(testData->GetId(), params.timeStep, pointsData2);


			vtkBoundingBox boundingBox;


			computeBoundingBox(pointsData, boundingBox);


			std::cout << "Loading / Training Classifiers" << std::endl;
			ClassifierMap classifiers;
			loadOrTrainClassifiers(params, 1000, patchData, classifiers);



			testData->Prepare(params.timeStep, boundingBox);
			testData->SaveImageGroup("2C", "MV-2C");


			// compute the distribution for the plane and get the mean for initialisation
			MatrixType planeData;
			valveData->GetTrainingData(testData->GetId(), params.timeStep, planeData);
			PlaneCovarianceFilterType::Pointer planeDistribution = PlaneCovarianceFilterType::New();
			computePlaneCovariance(planeData, planeDistribution);


			TestData::VectorType point, normal;

			if(params.timeStep == 0 && runs == 0)
			{
				for(unsigned int i = 0; i < 3; i++)
				{
					point(i) = planeDistribution->GetMean()[i];
					normal(i) = planeDistribution->GetMean()[i+3];
				}
				//startingPlane(pointsData2, point, normal);
			}
			else
			{
				point = startPoint;
				normal = startNormal;
			}

			OptData * optData = new OptData;
			optData->testData = testData;
			optData->classifiers = classifiers;
			optData->params = params;
			optData->lengths = lengthData;
			optData->planeMember = planeDistribution;




			nlopt::opt opt(nlopt::LN_BOBYQA, 5);
			opt.set_min_objective(f, (void*) optData);
			opt.set_xtol_rel(1e-4);
			opt.set_maxeval(100);


			std::vector<double> initStep(5);
			double pointStep = atof(argv[3]);
			double normalStep = atof(argv[4]);
			for(unsigned int i = 0; i < 3; i++)
			{
				initStep[i] = pointStep;
			}

			initStep[3] = normalStep;
			initStep[4] = normalStep;

			opt.set_default_initial_step(initStep);

			std::vector<double> xStart;
			convert_plane(point, normal, xStart);

			double minf;
			nlopt::result result = opt.optimize(xStart,minf);
			std::cout << "Final: " << result << std::endl;

			MatrixType initialPlane(1,6), finalPlane(1,6);
			VectorType finalPoint, finalNormal;
			convert_x(xStart, finalPoint, finalNormal);


			imageCost(params, testData, finalPoint, finalNormal, classifiers, lengthData, true);


			for(unsigned int i = 0; i < 3; i++)
			{
				finalPlane(0,i) = finalPoint(i);
				finalPlane(0,i+3) = finalNormal(i);
			}


			std::cout << finalPlane << std::endl;
			for(unsigned int i = 0; i < 6; i++)
			{
				initialPlane(0,i) = planeDistribution->GetMean()[i];
			}

			startPoint = finalPoint;
			startNormal = finalNormal;


			MatrixType gt;
			valveData->GetTestData(testData->GetId(), params.timeStep, gt);
			VectorType gtPoint, gtNormal;
			for(unsigned int i = 0; i < 3; i++)
			{
				gtPoint(i) = gt(0,i);
				gtNormal(i) = gt(0,i+3);
			}



			std::vector<ImageType::Pointer> vimages;
			testData->GetImages(vimages);
			ResultViewer::Pointer viewer = ResultViewer::New();
			viewer->SetImages(vimages);
			viewer->SetBoundingBox(boundingBox);
			viewer->SetPlane(finalPoint, finalNormal);
			viewer->SetStartPlane(gtPoint, gtNormal);
			viewer->SetUp();

			std::stringstream ss; 
			ss << params.name << "/" << testData->GetId() << "-" << params.timeStep << "-image.png";

			viewer->Save(ss.str());
			//viewer->View();

			//testData->SaveImageGroup("2C", "2C");
			//testData->SaveImageGroup("3C", "3C");
			//testData->SaveImageGroup("4C", "4C");
			//savePlane(initialPlane, "initialPlane.vtk");
			//savePlane(finalPlane, "finalPlane.vtk");
			

		}

	}






	return 0;
}