Software engineering twinning project work

4. Calculate the design and implementation of the interface module

My unique in that segment for the rays are basically a call to the original linear correlation function of the realization of new features , straight line segments when calculating the first ray intersection or into which they are located, and then determine the intersection of the straight line is calculated whether the point is on the line segment or radiation, greatly simplifies the code logic.

Considering that the geometric objects encapsulate only data is stored, the method does not involve therefore the package geometry with struct

struct Point {//点
	double x;
	double y;
	double length;

	bool operator ==(const Point& b) const noexcept
	{
		if (compareDouble(x - b.x) == 0 && compareDouble(y - b.y) == 0) return true;
		return false;
	}
	bool operator <(const Point& b) const noexcept
	{
		if (compareDouble(x - b.x) == 0 && compareDouble(y - b.y) < 0) return true;
		if (compareDouble(x - b.x) < 0) return true;
		return false;
	}

};

typedef Point Vector; //向量

struct Line { //直线
	Point p1, p2;
};

struct Segment { //线段
	Point p1, p2;
};

struct Ray { //射线
	Point start, direction;
};

struct Circle { //圆
	Point center;
	double r;
};

Command line handler, get the name of the input and output file. Get all the geometric objects from the input file, the same kind of geometric objects into the same vector. The intersection of all Pointthe set into a set.

vector<Line> lineSet;
vector<Segment> segmentSet;
vector<Ray> raySet;
vector<Circle> circleSet;
set<Point> pointSet;

Intersection point calculation calPointfunction or between two different classes in the same vector at the internal vector. Intersection point calculation getPointfunction between two geometric objects, the number of intersections returned calculated: NOCROSS, , ONECROSS, TWOCROSS(numerousMANYCROSS intersections).

Intersection calculating function defined as follows

int getPoint(Line l1, Line l2, Point& crossPoint) noexcept;
int getPoint(Line l, Segment s, Point& crossPoint) noexcept;
int getPoint(Line l, Ray r, Point& crossPoint) noexcept;
int getPoint(Line l, Circle c, pair<Point, Point>& crossPair) noexcept;

int getPoint(Segment s1, Segment s2, Point& crossPoint) noexcept;
int getPoint(Segment s, Ray r, Point& crossPoint) noexcept;
int getPoint(Segment s, Circle c, pair<Point, Point>& crossPair) noexcept;

int getPoint(Ray r1, Ray r2, Point& crossPoint) noexcept;
int getPoint(Ray r, Circle c, pair<Point, Point>& crossPair) noexcept;

int getPoint(Circle c1, Circle c2, pair<Point, Point>& crossPair) noexcept;

int calPoint(vector<Line>& lineSet, set<Point>& pointSet);
int calPoint(vector<Line>& lineSet, vector<Segment>& segmentSet, set<Point>& pointSet);
int calPoint(vector<Line>& lineSet, vector<Ray>& raySet, set<Point>& pointSet);
int calPoint(vector<Line>& lineSet, vector<Circle>& circleSet, set<Point>& pointSet);

int calPoint(vector<Segment>& segmentSet, set<Point>& pointSet);
int calPoint(vector<Segment>& segmentSet, vector<Ray>& raySet, set<Point>& pointSet);
int calPoint(vector<Segment>& segmentSet, vector<Circle>& circleSet, set<Point>& pointSet);

int calPoint(vector<Ray>& raySet, set<Point>& pointSet);
int calPoint(vector<Ray>& raySet, vector<Circle>& circleSet, set<Point>& pointSet);

int calPoint(vector<Circle>& circleSet, set<Point>& pointSet);

int calPoint(vector<Line>& lineSet, vector<Segment>& segmentSet, vector<Ray>& raySet, vector<Circle>& circleSet, set<Point>& pointSet);

The rays into a linear segment or determines whether a key point in the function of a line segment or range of radiation:

//将线段转化成对应的直线
//将横坐标较小的点作为p1,若两点横坐标相同则将纵坐标较小的点作为p1
Line segmentToLine(Segment s) {
	Line l;
	if ((s.p1.x < s.p2.x) || ((s.p1.x == s.p2.x) && (s.p1.y < s.p2.y))) {
		l.p1 = s.p1;
		l.p2 = s.p2;
	} else {
		l.p1 = s.p2;
		l.p2 = s.p1;
	}
	return l;
}

//将射线转化成对应的直线
Line rayToLine(Ray r) {
	Line l{ r.start, r.direction };
	return l;
}

//判断一个点是否在一线段的坐标范围内
int pointIfOnSeg(Point p, Line l)
{
	if (l.p1.x == l.p2.x) {
		if ((p.y >= l.p1.y) && (p.y <= l.p2.y)) {
			return ON;
		} else {
			return NOTON;
		}
	} else {
		if ((p.x >= l.p1.x) && (p.x <= l.p2.x)) {
			return ON;
		} else {
			return NOTON;
		}
	}
}

//判断一个点是否在一射线的坐标范围内
int pointIfOnRay(Point p, Line l)
{
	if (l.p2.x < l.p1.x) {
		//若射线指向负方向
		if (p.x <= l.p1.x) {
			return ON;
		} else {
			return NOTON;
		}
	} else if (l.p2.x == l.p1.x && l.p2.y < l.p1.y) {
		//若射线指向正下方
		if (p.y <= l.p1.y) {
			return ON;
		} else {
			return NOTON;
		}
	} else if (l.p2.x == l.p1.x && l.p2.y > l.p1.y) {
		//若射线指向正上方
		if (p.y >= l.p1.y) {
			return ON;
		} else {
			return NOTON;
		}
	} else {
		//若射线指向正方向
		if (p.x >= l.p1.x) {
			return ON;
		} else {
			return NOTON;
		}
	}
}

Calculation module interface section 6. Performance Improvement

Using a randomly generated test set contains more than a thousand pieces of data.

Obviously, the program will use most of the time in the set of elements inserted on.

In addition, based on the exact value determined rewriting equals significance also take up a lot of time

8. The display calculation module of the unit test

Defined above function module design part of the show, the calculation module is divided into LL, LR, LS, LC, SS, SR, SC, RR, RC, CC several functions, as long as these are covered calculate the intersection of these getPointfunctions, you to cover other computing functions that call. In order to cover all calPointfunctions, and then write a large test set contains a complete test of all types of calPointfunctions to achieve better coverage.

//测试圆与圆交点的多种情况,除保证计算交点个数正确外,还要保证计算的交点坐标正确
TEST_METHOD(Circle_Circle_TwoCross)
{
	Circle c1;
	Circle c2;
	c1.center.x = 0; c1.center.y = 0; c1.r = 2;
	c2.center.x = 2; c2.center.y = 0; c2.r = 2;
	Point realPoint1, realPoint2;
	pair<Point, Point> testPair;
	realPoint1.x = 1; realPoint1.y = 1.73205081;
	realPoint2.x = 1; realPoint2.y = -1.73205081;
	Assert::IsTrue(getPoint(c1, c2, testPair) == 2);
	Assert::IsTrue(((realPoint1 == testPair.first) && (realPoint2 == testPair.second)) || ((realPoint2 == testPair.first) && (realPoint1 == testPair.second)));
}

TEST_METHOD(Circle_Circle_OneCross)
{
	Circle c1;
	Circle c2;
	c1.center.x = 0; c1.center.y = 0; c1.r = 2;
	c2.center.x = 4; c2.center.y = 0; c2.r = 2;
	Point realPoint1, realPoint2;
	pair<Point, Point> testPair;
	realPoint1.x = 2; realPoint1.y = 0;
	Assert::IsTrue(getPoint(c1, c2, testPair) == 1);
	Assert::IsTrue(realPoint1 == testPair.first);
}

TEST_METHOD(Circle_Circle_NoCross)
{
	Circle c1;
	Circle c2;
	c1.center.x = 0; c1.center.y = 0; c1.r = 2;
	c2.center.x = 5; c2.center.y = 0; c2.r = 2;
	Point realPoint1, realPoint2;
	pair<Point, Point> testPair;
	Assert::IsTrue(getPoint(c1, c2, testPair) == 0);
}

TEST_METHOD(TestAll)
{
	vector<Line> lineSet;
	vector<Segment> segmentSet;
	vector<Ray> raySet;
	vector<Circle> circleSet;
	set<Point> pointSet;
			
	Line l1, l2; Segment s1, s2, s3; Ray r1, r2, r3; Circle c1, c2;
	l1.p1.x = 1; l1.p1.y = 2; l1.p2.x = 3; l1.p2.y = 3;
	l2.p1.x = 4; l2.p1.y = 2; l2.p2.x = 2; l2.p2.y = -4;
	lineSet.push_back(l1); lineSet.push_back(l2);
	s1.p1.x = -5; s1.p1.y = 1; s1.p2.x = 5; s1.p2.y = -3;
	s2.p1.x = 5; s2.p1.y = 3; s2.p2.x = 2; s2.p2.y = 2;
	s3.p1.x = 6; s3.p1.y = -5; s3.p2.x = 6; s3.p2.y = 6;
	segmentSet.push_back(s1); segmentSet.push_back(s2);
    segmentSet.push_back(s3);
	r1.start.x = 5; r1.start.y = 2; r1.direction.x = 3; r1.direction.y = 4;
	r2.start.x = 2; r2.start.y = -4; r2.direction.x = -1; r2.direction.y = -1;
	r3.start.x = -10; r3.start.y = 1; r3.direction.x = 10; r3.direction.y = 1;
	raySet.push_back(r1); raySet.push_back(r2); raySet.push_back(r3);
	c1.center.x = 2; c1.center.y = 3; c1.r = 4;
	c2.center.x = 5; c2.center.y = 2; c2.r = 2;
	circleSet.push_back(c1); circleSet.push_back(c2);
	Assert::AreEqual(calPoint(lineSet, segmentSet, raySet, circleSet, pointSet), 31);
}

Screenshot coverage calculation module GeoCalculate.ppcoverage reached 90%:

9. The computing module sections exception handling instructions. Each exception in a blog presentation design goals in detail. Each anomaly must choose a unit test sample posted in the blog, and indicate the error corresponding to the scene.

We designed the following categories exception:

  • Illegal input format
  • Enter the lack of geometric objects
  • Enter the end of the file contents too
  • Coordinate range exceeds the limit
  • Command line parameters are other characters
  • The number of intersection for the countless
Illegal input format

When confronted with the input data does not meet the requirements, such as the beginning of the file does not appear n, the illegal character, when the data is not correct geometric objects, throw exceptions illegalInputPattern

Unit Testing Sample:

Enter the lack of geometric objects

The first line of the file obtained from n, but when the input data is less than the n after the file, an exception is thrownnotEnoughInputElement

Unit Testing Sample:

Enter the end of the file contents too

After reading of the data of n and n geometric object file There undesirable content, an exception is thrownTooManyInputElements

Unit Testing Sample:

Coordinate range exceeds the limit

For each input data, it is determined in the range of (-100000,100000), if not, an exception is thrown outRangeException. And when the small circle is equal to zero or an input radius, this will throw an exception.

Unit Testing Sample:

Command line parameters are other characters

If the command-line parameter is incorrect, an exception is thrown commandException.

Unit testing sample :( command-line arguments for the "-d")

The number of intersection is an infinite number of

If the two figures there are numerous points of intersection, an exception is thrown infException.

Unit test samples the two straight lines coinciding :()

Detailed design process 10. The interface module. In a blog details how to interface module is designed for, and write some necessary code description explains the implementation process.

Qt Creator interface module development, design of two windows, a main interface Dialog , the other is a drawing interface new_window .

The main interface as shown:

Then one by one to introduce four functions implemented:

  • open a file

    void Dialog::readFile()function

    Using the getOpenFileNamemethod of acquiring the file path, the file open and, with readLinethe method to read the file line by line content, and with splitthe string dividing method according to the space, is stored in the corresponding structure. Finally, using the ui->label->setTextcontents of the read method displayed on the interface.

    Click "Open File" button and select the file results as shown:

  • Adding Graphics

    void Dialog::addone()function

    Using the ui->text->toPlainTextmethod of acquiring the character string in the text box, with splitthe method divided and stored into the respective structure. Finally, using the ui->label_2->setTextmethod to add the data displayed on the screen.

    Click on the "Add" button shown in FIG effect:

  • Delete Graphics

    void Dialog::deleteone()function

    Using the ui->text->toPlainTextmethod of acquiring the character string in the text box, a splitmethod of segmenting, elements corresponding to the data is found and deleted. Finally, using the ui->label_2->setTextmethod the deleted data is displayed on the screen.

    Click the "Delete" button effects as shown:

  • Graphing and intersection

    void Dialog::open()function

    Open a new window new_window , rewrite paintEventmethod, image rendering.

    Drawing method:

    • Line: drawLine
    • Round: drawEllipse
    • Point: drawPoint

    Graphics rendering results as shown:

11. The docking module and the computing module interface. Description docking UI module design and two modules in detail, and the screenshot function implemented in the blog.

We need to use the intersection point calculation calPointmethod, which is a set of five interface structure, representing the straight line segment, radiation, and round point. My idea is to structure the interface module is also packaged in the same form, call the direct method can be calculated. Add the Release version of dynamic link libraries and header files related to your project, you can call this method directly.

Display functions to achieve

Add 3 from graphics file and add a pattern (rays) manually, as shown:

Click "draw graphics and intersection" button results as shown:

Add 4 from the graphic file, and manually remove a pattern (line), as shown:

Click "draw graphics and intersection" button results as shown:

Guess you like

Origin www.cnblogs.com/syncline/p/12559007.html