Structured Data: Nesting Triangles(using structs and doing some geometric calculations)


nestedTriangles.cpp (attached) description:


The program takes as input a pair of triangles, specified be giving the coordinates of each trangle's vertices. It then determines if either triangle is "nested" within the other, meaning that one triangle lies entirely within the interior of the other.

Pseudocode:

One triangle lies within another if and only if all three vertices of the first triangle lie within the interior of the second triangle.
Suppose that we have a triangle with vertices A, B, and C, described by the coordinates (xA, yA), (xB, yB), and (xC, yC), respectively. The sides of the triangle are the line segments AB, BC, and CA.
A line passing through two points (x1, y1) and (x2, y2) can be considered to be the set of points (x,y) satisfying the equation
f(x,y) = 0
where f(x,y) is given as
f(x,y) = (x - x1) (y2 - y1) - (y - y1) (x2 - x1)
One of the interesting things about that f(x,y) is that we can use it to determine which "side" of the line an abitrary point (x,y) is on:

If f(x,y) = 0, the point is exactly on the line.
All points for which f(x,y) > 0 are on one side of the line, and
All points for which f(x,y) < 0 are on the other side
So the problem of determining whether a point (x,y) is on the inside of a trangle can be checking the sign of f(x,y) for each of the three lines making up the triangle.
A complicating factor is that we don't know, for any given triangle, whether those three signs should be all positive, all negative, or some mixture of the two.

The centroid of a triangle can be computed as the "average" of the x and y coordinates of the vertices:
xcen = (xA + xB + xC)/3
ycen = (yA + yB + yC)/3
This point (xcen, ycen) is definitely inside the trangle (unless the triangle is "degenerate" and has no interior points).

The problem of determining whether (x,y) is on the inside of a triangle can therefore be resolved by checking to see if it is on the same side of each of the trangle's line segments as (xcen, ycen).



What I need:

I want to fill in the missing bodies for the functions eval and areOnSameSideOf, which manipulate line segments. I think calling eval from within areOnSameSideOf will simplify the implementation of the latter.




1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
#include <iostream>

using namespace std;

/**
 * 2D Cartesian coordinates
 */
struct Point {
  double x;
  double y;
};


/**
 * A simple triangle, modeled as a collection of 3 vertices
 */
struct Triangle {
  Point vertices[3];
};

/**
 * A line segment, indicated by its two endpoints
 */
//*** Insert your structure declaration here

/**
 * Read a trangle from the input stream.
 *
 * A triangle is presented as a sequence of 6 floating point values,
 * each successive pair of numbers being the x,y coordinates of one vertex.
 *
 * @param t  the triangle being read in
 * @param in the input from which it should be read
 */
void readTriangle (Triangle& t, istream& in)
{
  for (int i = 0; i < 3; ++i)
    {
      double x, y;
      in >> x >> y;
      Point p = {x, y};
      t.vertices[i] = p;
    }
}


/**
 * Evaluate a point with respect to the equation defining the line
 * passing through a line segment.
 *
 *  A line is defined as the set of points satisfying f(x,y) = 0
 *  where f(x,y) is a function of the form ax + by + c. This function
 *  computes that f(x,y) for an arbitrary point, which might not be
 *  on that line.
 *
 * @param line a line segment
 * @param p a point at which we ant the line function evaluated
 * @return A value that is zero for points on the line, positive for all
 *          points on one side of the line, and negative for all points
 *          on the other side of the line.
 */
double eval (LineSegment line, Point p)
{
  //*** implement this function
}




/**
 * Check two points to see if they lie on the same side of a line
 *
 * @param p1 a point
 * @param p2 another point
 * @param line a line segment
 * @return true iff p1 and p2 are on the same side of the line
 *                  passing through the given line segment.
 *                  If either or both points lie exactly on the line,
 *                  return false.
 */
bool areOnSameSideOf (Point p1, Point p2, LineSegment line)
{
  //*** implement this function
}

/**
 * Check to see if a point lies on the interior of a triangle.
 *
 * @param p a point
 * @param t a triangle
 * @return true iff p lies in the interior of the trangle t
 */
bool isWithin (Point p, Triangle t)
{
  Point centroid = {0.0, 0.0};
  for (int i = 0; i < 3; ++i)
    {
      centroid.x += t.vertices[i].x;
      centroid.y += t.vertices[i].y;
      
    }
  centroid.x /= 3.0;
  centroid.y /= 3.0;
  
  for (int i = 0; i < 3; ++i)
    {
      LineSegment side = {t.vertices[i], t.vertices[(i+1)%3]};
      if (!areOnSameSideOf (p, centroid, side))
    return false;
    }
  return true;
}

/**
 * Check to see if one triangle lies entirely within the
 * interior of the other.
 *
 * @param outer
 * @param inner
 * @return true iff inner lies entirely within the interior of outer
 */
bool contains (Triangle outer, Triangle inner)
{
  for (int i = 0; i < 3; ++i)
    {
      if (!isWithin(inner.vertices[i], outer))
    return false;
    }
  return true;
}

/**
 * Check to see if either of two triangles is
 * entirely contained within the other.
 *
 * @param t1
 * @param t2
 */
void checkForNesting (Triangle t1, Triangle t2)
{
  if (contains(t1, t2) || contains(t2, t1))
    cout << "These triangles nest." << endl;
  else
    cout << "These triangles do not nest." << endl;
}

int main (int argc, char** argv)
{
  cout << "Enter the x,y coordinates of three vertices of a triangle: " << flush;
  Triangle t1;
  readTriangle (t1, cin);
  cout << "Enter the x,y coordinates of three vertices of another triangle: " << flush;
  Triangle t2;
  readTriangle (t2, cin);
  checkForNesting (t1, t2);
}
Topic archived. No new replies allowed.