Twinning project work - to find the intersections

Twinning project work - to find the intersections

project content
This work belongs courses Spring 2020 Computer Software Engineering Institute (Roger Ren Jian)
Where this requirement in the job Twinning project work
My aim in this course is Learning software engineering way of thinking, to write good software and maintenance
In particular aspects of the job which helped me achieve goals Learn the pros and cons of how to encapsulate core, how to write dynamic libraries and referenced in another project, while the initial contact pair programming, recognized this development approach.
class 006
project address github

A, PSP record time

PSP2.1 Personal Software Process Stages Estimated time consuming (minutes) The actual time-consuming (minutes)
Planning plan
· Estimate • Estimate how much time this task requires 1420 1700
Development Develop
· Analysis · Needs analysis (including learning new technologies) 600 600
· Design Spec Generate design documents 90 120
· Design Review · Design Review (and his colleagues reviewed the design documents) 10 10
· Coding Standard · Code specifications (development of appropriate norms for the current development) 40 60
· Design · Specific design 40 80
· Coding · Specific coding 400 520
· Code Review · Code Review 20 30
· Test · Test (self-test, modify the code, submit modifications) 60 240
Reporting report
· Test Report · testing report 30 15
· Size Measurement · Computing workload 30 20
· Postmortem & Process Improvement Plan · Hindsight, and propose process improvement plan 20 5
total 1420 1700

Second, the intersection of the extended computing function

1. New Features

The new feature is support for this segment and ray intersection geometry is added to the calculation, the change was analyzed after the addition of these two new geometry, the program needs to do the following.

First, after data is read into a geometry, first determine what, if it is radiation, it is the same equation and the straight line, denoted $$ Ax + By + c = 0 $$

In addition, the recording of the emission point (x1, y1), while the direction of the radiation emitted from the recording Dirct, here are four directions: left, right, vertically upward, vertically downward; if a line segment, also referred to as equation : $$ Ax + By + c = 0 $$, while recording its two vertices are (x1, y1), (x2, y2); other processing lines and circles of the same time, will not be repeated.

After the process is calculated, the general idea is the same, between the intersection geometry twenty-two seek, first between lines, the first simultaneous equations of two lines in parallel if it is returned directly, if there is an intersection, then to determine whether the point of intersection in two lines. If two lines, it must be in, it is added to the set, and if a radiation is a straight line, only determines whether a point can be determined on the ray, a function used here is_on_ray (Line l, crosspoint point) ,as follows:

bool is_on_ray(Line l, crosspoint point)
{//射线的交点问题
    if (l.dirct == 0) {
        if (point.x >= l.x1) {
            return true;
        }
        else {
            return false;
        }
    }
    else if (l.dirct == 1) {
        if (point.x <= l.x1) {
            return true;
        }
        else {
            return false;
        }
    }
    else if (l.dirct == 2) {
        if (point.y >= l.y1) {
            return true;
        }
        else {
            return false;
        }
    }
    else {
        if (point.y <= l.y1) {
            return true;
        }
        else {
            return false;
        }
    }
}

General idea is as follows, if the rightward direction of radiation, then the intersection of the abscissa obtained as long as greater than or equal to the abscissa of the vertex of the ray, ray empathy right abscissa intersection less than or equal to the abscissa of the vertex, the when the intersection ordinate less than or equal to the vertex of the ordinate, the upward ordinate intersection vertex greater than or equal to the ordinate.

With this function we can determine whether the intersection on the rays.

Continue the above, if two lines and one line segment is a straight line, can then only need to determine, as used herein whether another function is_on_segment intersections of the line segment (Line l, crosspoint point), the code as follows:

bool is_on_segment(Line l, crosspoint point)
{//直线和线段的交点问题
    if (l.x1 == l.x2) {
        if (point.y >= l.y1 && point.y <= l.y2) {
            return true;
        }
        else {
            return false;
        }
    }
    else {
        if (point.x >= l.x1 && point.x <= l.x2) {
            return true;
        }
        else {
            return false;
        }
    }
}

The idea here is that if this line is not perpendicular to the x-axis, then the intersection of the abscissa of the vertex is left must be greater than or less a right abscissa of the vertex abscissa, if it is vertical, the intersection of the vertical axis must be greater than longitudinal coordinates of vertices equal to or less on the vertical coordinates of the vertices.

With this function we can determine whether the intersection of the line segment.

Continue above, in addition to three cases said before, there are rays and ray intersection not only on the first ray, had on the second ray, ray and line segment, the segment with the segment the same token, not repeat them .

We can see the new calculate_line_line as follows:

int Intersect::calculate_line_circle(Line l, Circle c)
{
    crosspoint point1;
    crosspoint point2;
    if (l.aNotExist) {
        point1.x = l.t;
        point2.x = l.t;
        double k = ((double)l.t - c.m) * ((double)l.t - c.m);
        double r2 = (double)c.r * c.r;
        double left = r2 - k;
        if (left < 0) {//no result
            return 0;
        }
        else if (left == 0) {//one result
            point1.y = c.n;
            if (l.type == 0) {
                Setpoint.insert(point1);
                return 1;
            }
            else if (l.type == 1) {
                if (is_on_ray(l, point1)) {
                    Setpoint.insert(point1);
                    return 1;
                }
                else {
                    return 0;
                }
            }
            else {
                if (is_on_segment(l, point1)) {
                    Setpoint.insert(point1);
                    return 1;
                }
                else {
                    return 0;
                }
            }
        }
        else {//two result
            point1.y = sqrt(left) + c.n;
            point2.y = c.n - sqrt(left);
            if (l.type == 0) {
                Setpoint.insert(point1);
                Setpoint.insert(point2);
                return 2;
            }
            else if (l.type == 1) {
                int num = 0;
                if (is_on_ray(l, point1)) {
                    Setpoint.insert(point1);
                    num++;
                }
                if (is_on_ray(l, point2)) {
                    Setpoint.insert(point2);
                    num++;
                }
                return num;
            }
            else {
                int num = 0;
                if (is_on_segment(l, point1)) {
                    Setpoint.insert(point1);
                    num++;
                }
                if (is_on_segment(l, point2)) {
                    Setpoint.insert(point2);
                    num++;
                }
                return num;
            }
        }
    }
    else {//ax^2+bx+t=0
        double a = l.a * l.a + 1;
        double b = 2 * ((l.b - c.n) * l.a - c.m);
        double t = (double)c.m * c.m + (l.b - c.n) * (l.b - c.n) - (double)c.r * c.r;
        double deta = b * b - 4 * a * t;
        if (deta > 0) {
            point1.x = (sqrt(deta) - b) / (2 * a);
            point2.x = (-1 * sqrt(deta) - b) / (2 * a);
            point1.y = l.a * point1.x + l.b;
            point2.y = l.a * point2.x + l.b;
            if (l.type == 0) {
                Setpoint.insert(point1);
                Setpoint.insert(point2);
                return 2;
            }
            else if (l.type == 1) {
                int num = 0;
                if (is_on_ray(l, point1)) {
                    Setpoint.insert(point1);
                    num++;
                }
                if (is_on_ray(l, point2)) {
                    Setpoint.insert(point2);
                    num++;
                }
                return num;
            }
            else {
                int num = 0;
                if (is_on_segment(l, point1)) {
                    Setpoint.insert(point1);
                    num++;
                }
                if (is_on_segment(l, point2)) {
                    Setpoint.insert(point2);
                    num++;
                }
                return num;
            }
        }
        else if (deta == 0) {
            point1.x = (b == 0) ? 0 : -1 * b / (2 * a);
            point1.y = l.a * point1.x + l.b;
            if (l.type == 0) {
                Setpoint.insert(point1);
                return 1;
            }
            else if (l.type == 1) {
                if (is_on_ray(l, point1)) {
                    Setpoint.insert(point1);
                    return 1;
                }
                else {
                    return 0;
                }
            }
            else {
                if (is_on_segment(l, point1)) {
                    Setpoint.insert(point1);
                    return 1;
                }
                else {
                    return 0;
                }
            }
        }
        else {
            return 0;
        }
    }
}

The next line is the circle, the other logic is the same, the difference is determined whether the intersection point is determined to be at a ray or line, if only this point will be added to set.

Here is the new calculate_line_circle:

int Intersect::calculate_circle_circle(Circle c1, Circle c2)
{
    crosspoint point1;
    crosspoint point2;
    double norm = ((double)c1.m - c2.m) * ((double)c1.m - c2.m) + ((double)c1.n - c2.n) * ((double)c1.n - c2.n);
    double d = sqrt(norm);
    if (d > ((double)c1.r + c2.r)) {
        return 0;
    }
    if (d < (fabs((double)c1.r - c2.r))) {
        return 0;
    }
    double a = acos(((double)c1.r * c1.r + d * d - (double)c2.r * c2.r) / ((double)2 * c1.r * d));
    double t = arg((double)c2.m - c1.m, (double)c2.n - c1.n);
    point1.x = c1.m + cos(t + a) * c1.r;
    point1.y = c1.n + sin(t + a) * c1.r;
    if (a == 0) {
        Setpoint.insert(point1);
        return 1;
    }
    else {
        point2.x = c1.m + cos(t - a) * c1.r;
        point2.y = c1.n + sin(t - a) * c1.r;
        Setpoint.insert(point1);
        Setpoint.insert(point2);
        return 2;
    }
}

And logic circle intersects the circle without any change, it will not be repeated.

2. Unit testing of new features

TEST_METHOD(calculate_line_line)
		{
			Intersect p;
			Line l1(0, 0, 1, 1, 0);
			Line l2(0, 0, 0, 1, 0);
			int ret = p.calculate_line_line(l1, l2);
			Assert::AreEqual(ret,(int)1);
			Line l3(0, 0, 1, 1, 0);
			Line l4(1, 0, 2, 1, 0);
			ret = p.calculate_line_line(l3, l4);
			Assert::AreEqual(ret, (int)0);
			Line l5(0, 0, 1, 0, 2);
			Line l6(1, 0, 2, 0, 2);
			ret = p.calculate_line_line(l5, l6);
			Assert::AreEqual(ret, (int)1);
			Line l7(0, 0, 1, 0, 2);
			Line l8(1, 1, 2, 0, 2);
			ret = p.calculate_line_line(l7, l8);
			Assert::AreEqual(ret, (int)0);
			Line l9(0, 0, 1, 1, 1);
			Line l10(0, 0, -1, -1, 1);
			ret = p.calculate_line_line(l9, l10);
			Assert::AreEqual(ret, (int)1);
			Line l11(0, 0, 1, 0, 1);
			Line l12(0, 1, 0, 2, 1);
			ret = p.calculate_line_line(l11, l12);
			Assert::AreEqual(ret, (int)0);
		}

This is a test unit testing calculate_line_line function, consider the case where a combination of line, ray, segment, consider the case of two parallel lines, such as a special two non-parallel rays, rays but not the intersection point is obtained, the case where no intersection .

TEST_METHOD(calculate_line_circle)
		{
			Intersect p;
			Line l1(0, 0, 1, 1, 0);
			Circle c1(0, 1, 1);
			int ret = p.calculate_line_circle(l1, c1);
			Assert::AreEqual(ret, (int)2);
			Line l2(0, 0, 0, 1, 0);
			Circle c2(1, 0, 1);
			ret = p.calculate_line_circle(l2, c2);
			Assert::AreEqual(ret, (int)1);
			Line l3(0, 0, 1, 0, 0);
			Circle c3(0, 2, 1);
			ret = p.calculate_line_circle(l3, c3);
			Assert::AreEqual(ret, (int)0);
			Line l4(0, 1, 1, 1, 1);
			ret = p.calculate_line_circle(l4, c1);
			Assert::AreEqual(ret, (int)1);
			Line l5(0, 0, 0, 1, 2);
			Circle c4(0, 0, 3);
			ret = p.calculate_line_circle(l5, c4);
			Assert::AreEqual(ret, (int)0);
			Line l6(2, 1, 0, 1, 2);
			ret = p.calculate_line_circle(l4, c1);
			Assert::AreEqual(ret, (int)1);
		}

This is a test unit testing calculate_line_circle function, consider the line, ray, the intersection of circle segments and may, where considered linear and circular one, two, three cases no intersections, and segments and rays, and in fact the difference between a straight line just find the intersection may not online, it is also individually tested While the intersection can be determined by the equation, but not on the line.

TEST_METHOD(calculate_circle_circle)
		{
			Intersect cal;
			Circle c1(0, 0, 1);
			Circle c2(1, 1, 1);
			int ret = cal.calculate_circle_circle(c1, c2);
			Assert::AreEqual(ret, (int)2);
			Circle c3(0, 0, 2);
			Circle c4(3, 0, 1);
			ret = cal.calculate_circle_circle(c3, c4);
			Assert::AreEqual(ret, (int)1);
			Circle c5(0, 0, 3);
			Circle c6(0, 0, 1);
			ret = cal.calculate_circle_circle(c5, c6);
			Assert::AreEqual(ret, (int)0);
			Circle c7(0, 0, 1);
			Circle c8(0, 9, 1);
			ret = cal.calculate_circle_circle(c7, c8);
			Assert::AreEqual(ret, (int)0);
		}

This is a test unit testing calculate_circle_circle function, consider the two circles have two, one, zero intersection point, but also considered the case where a circle inside another circle

We can see the test.

Third, after the extended function modules as a separate package

1. Look Design by Contract, Code Contract content, describing the advantages and disadvantages of these practices, explain how you put them into pairing job.

First of all let me say something a little more understanding (code contracts) I Design by Contract.

The main purpose of the contract is to design programmer to explicitly stated in the design of a program module unit (specific to object-oriented, is an instance of a class) in which an operation state before and after the call should belong. To put it plainly my understanding is that this is a code of grammar.

Contract design emphasizes three concepts: preconditions, postconditions, and invariants. Pre condition occurs in each operation (method or function) in the beginning, at the end of the post condition occurs each operation, in fact, is the intersection of invariant pre-conditions and post-conditions. Violation of these operations will cause the program to throw an exception.

The main advantage is to improve the reliability of the program; make your design more systematic and clearer and simpler; convenient debugging.

There are disadvantages to complete the design by contract need to learn their ideas and technology, it takes a lot of time; high cost of writing, the previous sentence may now want to write a few words; only a lot of good contractual practice in order to write the code, then it is possible to write code that is neither fish nor fowl front, but also a waste of time.

When I was writing the core part, only at the beginning of each function in addition to the data input will make some legitimacy judgment, postconditions, and invariants that should not understand how to use, do not know this does not count considered the application of this idea.

Since there is no systematic study of this kind of programming methods of thinking, so in this job and does not reflect much.

2. Look at the textbooks and other materials in the section on Information Hiding, Interface Design, Loose Coupling suggests that you are at the junction of how programming is the use of these methods for interface design.

The first is the Information Hiding, information hiding module is only meant to make public must let the outside world know something, hide everything else. Design of the interface module designed, fully embodies the principle of information hiding - the interface module is external features, should be open; and data structures, algorithms, implemented the like are internal features of the module, should be hidden. A module provides only limited interface, the interface module is the only way to interact with the outside world. This is my design ideas, only to realize specific interfaces, packaged inside the rear into the dll public, where data exist are hidden.

Second is the interface design. I think a good interface design should have the following aspects. I. readability interface, the interface named to reflect upon whether this interface allows users generally understand what is, in my design, I am all in English spelling of ways, such as calculate, insertLine and so on. Security II. Interface, which I think I basically did not do, the only to do is eliminate the warnings visual studio (also considered a safe?). III. Interface meets the requirements, which I designed, first read through the entire operational requirements, the core part of the need to do a section of the column down, so when writing code that will be more organized, there is provided an interface logic, the most critical is the exchange and companions after writing, we find the need to consider the added interface and useless interface, to make adjustments.

Finally Loose Coupling, which is reflected when an exception is thrown, if I want to modify the exception message, I just need to change the exception classes can be, and do not care about my throwing an exception code looks like. But here I have done some bad places, such as design and Circle Line class when the class in which the data is special treatment, if you want to modify some of the parameters, it may cause the entire code again.

3. Overview of Interface Design

public:
	void clear();
	void readdata();
	void readdata_File(const char* name);
	int result();
	void calculate();
	int insertLine(int x1, int y1, int x2, int y2, char type);//0插入,非0出错
	int deleteLine(int x1, int y1, int x2, int y2, char type);//0删除 1出错
	int insertCircle(int x, int y, int r);
	int deleteCircle(int x, int y, int r);
	vector<pair<double, double>> pullIntersect();
	vector<vector<int>> pullgraph();

Providing more interfaces, one described below.

1. clear () Interface

Its object is to clear all the data, when the user wants to re-calculate the intersection, using the geometry data stored in this function before emptying.

2. readdata () Interface

For reading data from the console, can be read every n data.

3. calculate () Interface

When the user input is completed, uses this function to calculate the data, and saves the calculated intersection.

4. result () Interface

Returns the number of intersections calculated

5. insertLine () Interface

This interface is used to meet the needs of the "support insert, delete." Calling this function will insert a straight line (to see if legitimate) to the data, if the returns 0 for insertion is successful, nonzero if the data is not legitimate.

6. deleteLine () Interface

When this interface to meet the needs of the "support insert, delete", this function is called when the user wants to delete the straight line found, delete it and returns 0, otherwise it returns 1 was not found.

7. insertCircle () Interface

This interface is used to meet the needs of the "support insert, delete." Calling this function to insert data in a round (to see if legitimate), returns 0 for insertion is successful, nonzero if the data is not legitimate.

8. deleteCircle () Interface

This interface is designed to meet the needs of the time "support insert, delete", this function is called when the user wants to delete the circle is found, delete it and returns 0, otherwise it returns 1 was not found.

9. pullIntersect () Interface

This function is used to provide all the intersections of the front end to the UI data such that the UI may be drawn from these intersection coordinates. The purpose of this function is designed to meet the needs "support for solving the existing intersection geometry objects and draw."

10. pullgraph () Interface

This function is provided to the front end of all geometry data UI, UI may be such that the rendered image from these data. The purpose of this function is designed to meet the needs "support existing drawing geometric objects.".

11. readdata_File(const char* name)接口

For reading data from the file.

4. In the module design and implementation of the interface

To achieve these interfaces, I have a total defines three classes, Class Line, circle and Intersect class category, Intersect is responsible for the final calculation, etc. work, and Line class and the Circle class are respectively linear and circular geometry processing the relationship should be a link between them.

Design the whole process about three key points, the first is the newly added segments rays and deal with the problem, this section has been detailed in the beginning of this article; The second key is the user may be some false data into how identified these problems and error, the idea is here I have so few errors, a first format is input at the time in question, such as I enter L 0 0 1 1 such a linear format, less input I a number of L or the beginning of the other symbols, etc., this error handled well, can determine when scanf_s input is legal, although the second input format is correct, but the range of the parameter in question, more than limits or r is less than 0, whether these errors can have a problem if judged after each entry, and the third is the most troublesome is that after insertion of the geometry will be an infinite number of intersection, we first consider round and round produce the intersection between an infinite number, then the only possibility is that these two circles are overlapping, as the coordinates of the center of the circle and the two words have the same radius length , Then we only need to read a comparison with all round when the round has been deposited, as if there is an error, otherwise it will join the circle set, followed by circles and lines, certainly will not have an infinite number of intersection, do not consider, finally, an infinite number of intersection between the lines, the first to appear in any line intersection of an infinite number of them necessarily coincide, that is to say for a equation $$ Ax + By + C = 0 $$ in line l1, and an equation $$ ax + by + c = 0 $$ line l2, a necessary condition is overlapped a $$ B = B a a $$ and $$ C = Ca $$, secondly we also need to determine if this is really two lines coincide, if one is a straight line, then it must coincide, there will be an infinite number of intersection points, if no one is straight, so if the two are the rays, if two rays of the same direction, a certain overlap, if the opposite direction, then a ray of vertices will be superposed on the other ray, or will not (note here the problem if only the vertex coincidence will not cause an infinite intersection), if a ray is a line, then the endpoint of a line segment will have to be a problem in the infinite intersection ray, if two line segments, as long as the left end point of the line l1 is greater than equal to the right end point of another segment l2 or l1 right end of the line points or less left point l2 segment, there is no problem, otherwise there will be problems unlimited intersection; the last one key issue is the precision, here not thought out very good solution, but as much as possible to reduce the divide, square root No other operation times (such as required by the general formula intersection of two straight lines instead of oblique point), where the idea is also desirable to provide good big brother .

5. UML 图

6. The interface part of the unit test

From the point of view of difficulty, clear () interfaces, pullgraph () interfaces, result () interfaces, pullintersect () interfaces are not required for testing, because they simply return a data structure or a simple initialization process, calculate ( ), readdata () and other interfaces are in use from the time the personal job down, have been tested, so we are here to test the new four main interfaces

TEST_METHOD(deleteline)
		{
			Intersect p;
			int ret;
			p.insertLine(0, 0, 1, 1, 'L');
			p.insertLine(0, 0, 0, 1, 'R');
			p.insertLine(0, 0, 1, 0, 'S');
			ret = p.deleteLine(1, 1, 2, 2, 'R');
			Assert::AreEqual(ret, (int)1);
			ret = p.deleteLine(1, 1, 2, 2, 'L');
			Assert::AreEqual(ret, (int)0);
			ret = p.deleteLine(0, 0, 1, 1, 'L');
			Assert::AreEqual(ret, (int)1);
			ret = p.deleteLine(0, 0, 0, -1, 'R');
			Assert::AreEqual(ret, (int)1);
			ret = p.deleteLine(0, 0, 1, 2, 'S');
			Assert::AreEqual(ret, (int)1);
		}

This is a test deleteline () unit test interface, where I consider when design data is that even mainly two lines coincide, and they were not the case the same line, can not be deleted, such as the first point, the two lines coincide, but is a straight line, a ray is, it can not be deleted, 1 indicates an error return; the second point is a case where two lines overlap, needs to be removed, returns 0; third point is the point of a delete successful test, because the second point of this line has been deleted, the third point should not find the requested again when this line delete this line, it returns 1; and a fourth test point is the case when the two rays overlap, and the two rays coincident endpoints the same, but the ray direction is not the same, should return 1; the case of the last two tests a test point when the line segment, a line segment if two different identical to the other endpoint, certainly not the same segment, should return 1.

TEST_METHOD(deletecircle)
		{
			Intersect p;
			p.insertCircle(0, 0, 1);
			p.insertCircle(1, 1, 1);
			p.insertCircle(0, 0, 2);
			int ret = p.deleteCircle(1, 1, 1);
			Assert::AreEqual(ret, (int)0);
			ret = p.deleteCircle(1, 1, 1);
			Assert::AreEqual(ret, (int)1);
			ret = p.deleteCircle(0, 0, 1);
			Assert::AreEqual(ret, (int)0);
			ret = p.deleteCircle(0, 2, 1);
			Assert::AreEqual(ret, (int)1);
		}

This is a test deletecircle () unit test interface, a special point where my main consideration is deleted after a round, remove the circle again, it should be an error, and the same determination must be the center of the two circles are equal and have the same radius. Test is relatively simple, not repeat them.

TEST_METHOD(insertLine)
		{
			Intersect p;
			int ret = p.insertLine(1, 2, 1, 2, 'L');
			Assert::AreEqual(ret, (int)1);
			ret = p.insertLine(100001, 0, 2, 1, 'L');
			Assert::AreEqual(ret, (int)2);
			ret = p.insertLine(0, -100006, 2, 1, 'L');
			Assert::AreEqual(ret, (int)3);
			p.insertLine(0, 0, 1, 2, 'L');
			ret = p.insertLine(0, 0, -1, -2, 'R');
			Assert::AreEqual(ret, (int)4);
			ret = p.insertLine(0, 0, 1, 5, 'C');
			Assert::AreEqual(ret, (int)5);
			ret = p.insertLine(0, 0, 1, 1, 'L');
			Assert::AreEqual(ret, (int)0);
		}

This is a test insertLine () interface unit testing. Here my main consideration is to insert a coordinate value exceeds a defined line, is inserted into a type does not meet the value line standard, inserting a two vertices repeating lines, insert a generated numerous intersections of lines, and a normal interpolated line so it takes into account all possible abnormality.

TEST_METHOD(insertCircle)
		{
			Intersect p;
			int ret = p.insertCircle(0, 0, 100005);
			Assert::AreEqual(ret, (int)1);
			ret = p.insertCircle(-100008, 2, 4);
			Assert::AreEqual(ret, (int)2);
			ret = p.insertCircle(0, 2, -2);
			Assert::AreEqual(ret, (int)3);
			p.insertCircle(0, 0, 1);
			ret = p.insertCircle(0, 1, 1);
			Assert::AreEqual(ret, (int)0);
			ret = p.insertCircle(0, 0, 1);
			Assert::AreEqual(ret, (int)4);
		}

This is a test insertcircle () interface unit testing. Here my main consideration is to be inserted into a coordinate value exceeds a defined circle, is inserted into a radius negative round, inserting a generated circle numerous intersections, and a normal insertion of the line, so to take into account all the possible exception Happening.

Test results are as follows:

Fourth, support for exception handling

1. Support exception

abnormal description
Exception_OFB Bounds Exception, when the input parameters of geometry, if it exceeds the set range (-100000,100000), or the radius of the circle is less than 0, this exception will be thrown.
Exception_IP Unlimited intersection abnormal, when a new geometry, the infinite number of intersections into a plurality of request, this will throw an exception
Exception_WF Format Error exception, when the input geometry data format does not conform to a predetermined format, this exception is thrown
Exception_MD Invalid an exception, when the two-point input coordinate linear geometry are the same, that this line is invalid thrown
abnormal aims
Exception_OFB To remind the user to enter parameters should be within the range of what interval, and return to continue entering input
Exception_IP Remind users to join this geometry is prohibited, and returned to re-enter the input interface
Exception_WF Prompts the user to enter a standard format, and return to continue entering input interface
Exception_MD Prompts the user coordinates of two points must be different, and return to continue entering input interface

2. The unit test abnormalities

We tested by insertLine () function to test whether we are right throw an exception, because after each exception is thrown, our code will catch this exception and return a different value, so take advantage of this can be well for unit testing.

TEST_METHOD(insertLine)
		{
			Intersect p;
			int ret = p.insertLine(1, 2, 1, 2, 'L');
			Assert::AreEqual(ret, (int)1);
			ret = p.insertLine(100001, 0, 2, 1, 'L');
			Assert::AreEqual(ret, (int)2);
			ret = p.insertLine(0, -100006, 2, 1, 'L');
			Assert::AreEqual(ret, (int)3);
			p.insertLine(0, 0, 1, 2, 'L');
			ret = p.insertLine(0, 0, -1, -2, 'R');
			Assert::AreEqual(ret, (int)4);
			ret = p.insertLine(0, 0, 1, 5, 'C');
			Assert::AreEqual(ret, (int)5);
			ret = p.insertLine(0, 0, 1, 1, 'L');
			Assert::AreEqual(ret, (int)0);
		}

返回5说明抛出了Exception_WF,返回1说明抛出了Exception_MD,返回2和3说明抛出了Exception_OFB的两种不同格式的异常,返回4说明抛出了Exception_IP,返回0说明这条线是合法的。
通过这个测试,可以发现异常能被正确的抛出且捕获。

测试结果如下

3.所有单元测试覆盖率

五、性能测试以及修改

这是运行2000组数据的性能分析图,可以看到calculate()占用了64.09%的CPU时间,这是由于我们的算法采用暴力的做法,时间复杂度是O(n2),其次是readdata(),这是因为在读入数据时要检查数据的合法性,每读一个检查一次,每次检查是O(n)的时间复杂度,所以总共是O(n2)的时间复杂度。

在这组数据中运行次数最多的是calculate_line_line(),这也符合我们之前的推测,由于第一次作业我们发现用set会比map稍微快一点,所以这次也是采用set存点的方法,因此想要改善这里的速度只能更换算法,所以并没有对程序进行太多性能上的优化。

六、添加界面模块

七、结对编程总结

1.结对的过程

我们采用腾讯会议作为交流的平台,一个人在写的时候另一个人可以通过屏幕共享看到并时刻交流

2.结对编程的优缺点

优点 描述
互相监督,无法偷懒摸鱼 两个人互相监督互相配合,如果一个人偷懒那么另一个人会发现并去提醒他,可以保证工作的进度。
互相学习 两个人各有擅长所在,有的人可能擅长算法,有的人擅长UI的设计与编写,这样在结对编程时可以互相学习一些技巧。
互相帮助,渡过难关 当在处理某个问题时卡住了,两个人可以讨论,一起上网找资料,互相鼓励,更快的渡过难关。
一人写一人看减少bug 一人在写一人看,可以降低出错的概率,减少bug。
缺点 描述
容易内耗 两人就一个问题产生了意见的分歧,都想说服对方用自己的方法,无谓的降低效率。
降低了开发的速度 如果两人不是一人写一人看的模式,每天会多出一倍的工作时间,比如讲任务分为前端和后端,一人负责一部分,会比结对更快的完成任务。
容易在工作时聊天 两个人连着麦写代码,写了一会儿突然发起一个话题,无休止的聊了下去,降低工作效率。
对于性格不和的人会产生争执 一个人喜欢敏锐开发,每天工作8小时,另一个人喜欢多干几天,每天工作3小时,这两个人结对会造成就工作时长的争执,团队不和无法继续工作。

我的优点是:认真负责,对自己的工作要做到位;效率较高;善于从网上学习资料
缺点是:不能做到精益求精,感觉满足需求了,到位了,就不想优化了。
同伴的优点是:分工能力强;同样的认真负责,效率高;能很好地提供思路,指出问题所在
缺点是:不能一次指出所有问题(hhh这样改起代码有时需回退版本)。

Guess you like

Origin www.cnblogs.com/Boming/p/12542363.html