problem with vectors

Pages: 12
Hi all.What I am trying to do is a program that calculates the area of a polygon.
I divided my program into two subcodes.The first part computes the area, and the second calculates which points create the largest area of the polygon,.My problem is that now I got the points, and the calculation mechanism of the area works, but I cant make it so the calculated points go automatically to the function which calculates the area.Because the points are in vector stack and mass, I try to assign the two of them to the vector v, which goes to the function which computes the area...Here is my code so far, I tried several methods, now I am really stuck.I will be very happy if you help me.
Thanks

Rachel Anderson

Code:
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
157
158
159
160
161
162
163
164
165
#include <iostream>
#include <math.h>
#include <algorithm>
#include <vector>
using namespace std;

struct A{      //stores the pairs of points
int x;
int y;
};

int N;
int sx=10000,sy=10000; //Coordinates of the smallest point.

vector <A> mass;

int used[100];


bool CMP(A i,A j)     //Which point is bigger by sin
{                                            
       if((i.x-sx)/(sqrt(pow(i.x-sx,2)+pow(i.y-sy,2)))>(j.x-sx)/(sqrt(pow(j.x-sx,2)+pow(j.y-sy,2))))
		return 1;
	else return 0;
}

// Function that calculates the absolute value
// of a double type.
double MyAbs(double num)
{
    double inv = num * -1;
    return (num <= 0) ? inv : num;
}

// Function that calculates the area.
//Given vector of points in the XY plane.
double CalcArea(vector<pair<double, double > > list)
{
    double area = 0; // Total Area
    double diff = 0; // Difference Of Y{i + 1} - Y{i - 1}
    unsigned int last = list.size() - 1; // Size Of Vector - 1

   //That loop goes to all points from 2 to n-1.
    for(unsigned int i = 1; i < last; i++)
    {
        diff =list[i + 1].second - list[i - 1].second;
        area += list[i].first * diff;
    }

    //Now we consider the points 1 and n.
    diff = list[1].second - list[last].second;
    area += list[0].first * diff; // 

    diff = list[0].second - list[last - 1].second;
    area += list[last].first * diff; 

    /* Calculate The Final Answer */
    area = 0.5 * MyAbs(area);
    return area; // Return The Area
}

int main()
{

N=5;

double it;
int i;
for(i=1;i<=N;i++)
{	A temp;

	cin>>temp.x>>temp.y;
	mass.push_back(temp);

	if(sy>mass[mass.size()-1].y)
	{
		it=mass.size()-1;
		sy=mass[mass.size()-1].y;
		sx=mass[mass.size()-1].x;
	}
	
           if(mass[mass.size()-1].y==sy&&mass[mass.size()-1].x<sx)
	{
		it=mass.size()-1;
		sx=mass[mass.size()-1].x;
	}
}

mass.erase(mass.begin()+it);

sort(mass.begin(),mass.end(),CMP);

cout<<endl<<endl<<endl<<endl;
 
for(i=0;i<mass.size();i++)
    
	cout<<mass[i].x<<" "<<mass[i].y<<endl;//Here it outputs the points which creates the external 
                                         //line of the polygon.
vector<A> stack;

A temp;
temp.x=sx;
temp.y=sy;

stack.push_back(temp);
stack.push_back(mass[0]);

for(i=1;i<mass.size();i++)
{
	int x1,x2,x3,y1,y2,y3;
	
	int status=0;

	while(status==0)
   {
	x3=mass[i].x;
	y3=mass[i].y;
	x1=stack[stack.size()-2].x;
	y1=stack[stack.size()-2].y;
	x2=stack[stack.size()-1].x;
	y2=stack[stack.size()-1].y;


	if((x1*y3+y1*x2+x3*y2)-(x2*y3+y2*x1+x3*y1)>0)
		stack.pop_back();
	else 
      {
		stack.push_back(mass[i]);
		status=1;
      }
   }
}
 

   for(i=0;i<stack.size();i++)
   cout<<stack[i].x<<" "<<stack[i].y<<endl;                                                           

    double x = 0;
    double y = 0;
  
 vector< pair<double, double> > v;

int mm=mass.size();   
int nn=stack.size();

 while(stack.size() > 0)
  {
       for (i=0;i<=stack.size();i++)
       v.push_back(make_pair(x[i], y[i]));// here I want to push back the pairs x and y into V
       nn--;                                             //which goes ti the function that computes the area.
  }                                                

     
    while(mass.size() > 0)
 {
    for (i=0;i<=mass.size();i++)
    v.push_back(make_pair(x[i], y[i]));// here I want to push back the pairs x and y into V
    mm--;                                            //which goes ti the function that computes the area.
 }
cout<<"The Area Of The Polygon Is: " << CalcArea(v) <<endl;

system ("pause");
return 0;
}
Last edited on
In line 174 and 183 it gives 2 errors for each line.The error is : 183 double[int]' for array subscript.
Can i change this one- v.push_back(make_pair(x[i], y[i])); with something else to avoid this error?
You are trying to use x and y as arrays, but they are only doubles.
So, what should I do?
If I make a new vector and push every x[i] and y[i] in it, and after that use this vector in the function where I want to put them now?
Last edited on
Nobody can give me an advice?Come on people.I really need your help...
closed account (S6k9GNh0)
Is the polygon regular?
Why do you need vectors in the case that the need for dynamically sized memory doesn't seem to be needed?

And last but not least, I stopped about 1/5 of the way through your example and said that it's basically unreadable. Either comment and reformat some of the rather strange things you did or you won't be finding much help here. You have well over enough unneeded lines of white space.
Last edited on
I think now its more understandable.The polygon is not regular.As I said, the code works, but I made it to output the points which are needed to calculate the area of the polygon
 
cout<<mass[i].x<<" "<<mass[i].y<<endl;

 
cout<<stack[i].x<<" "<<stack[i].y<<endl; 

, and after that the user should input them again.Now what I want to do is to input them automatically.
So I use this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
while(stack.size() > 0)
  {
       for (i=0;i<=stack.size();i++)
       v.push_back(make_pair(x[i], y[i]));// here I want to push back the pairs x and y into V
       nn--;                                             //which goes ti the function that computes the area.
  }                                                

     
    while(mass.size() > 0)
 {
    for (i=0;i<=mass.size();i++)
    v.push_back(make_pair(x[i], y[i]));// here I want to push back the pairs x and y into V
    mm--;                                            //which goes ti the function that computes the area.
 }

That vector "v" goes to the function that calculates the area.
There is some logical mistake, and I dont know how to fix it.
Thanks :)
Last edited on
To be more clear, I will post the code which works. Here it is:
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
#include <iostream>
#include <math.h>
#include <algorithm>
#include <vector>
using namespace std;
struct A{
int x;
int y;
};
int N;
int sx=10000,sy=10000;


vector <A> mass;

int used[100];

bool CMP(A i,A j)
{
        if((i.x-sx)/(sqrt(pow(i.x-sx,2)+pow(i.y-sy,2)))>(j.x-sx)/(sqrt(pow(j.x-sx,2)+pow(j.y-sy,2))))
		return 1;
	else return 0;
}


double MyAbs(double num)
{
    double inv = num * -1;
    return (num <= 0) ? inv : num;
}

double CalcArea(vector<pair<double, double > > list)
{
    double area = 0; // Total Area
    double diff = 0; // Difference Of Y{i + 1} - Y{i - 1}
    unsigned int last = list.size() - 1; // Size Of Vector - 1

    
    for(unsigned int i = 1; i < last; i++)
    {
        diff =list[i + 1].second - list[i - 1].second;
        area += list[i].first * diff;
    }

    
    diff = list[1].second - list[last].second;
    area += list[0].first * diff; // 

    diff = list[0].second - list[last - 1].second;
    area += list[last].first * diff; 

    /* Calculate The Final Answer */
    area = 0.5 * MyAbs(area);
    return area; // Return The Area
}

int main()
{

N=5;

double it;
int i;
for(i=1;i<=N;i++)
{	A temp;

	cin>>temp.x>>temp.y;
	mass.push_back(temp);

	if(sy>mass[mass.size()-1].y)
	{
		it=mass.size()-1;
		sy=mass[mass.size()-1].y;
		sx=mass[mass.size()-1].x;
	}
	
if(mass[mass.size()-1].y==sy&&mass[mass.size()-1].x<sx)
	{
		it=mass.size()-1;
		sx=mass[mass.size()-1].x;
	}
}
mass.erase(mass.begin()+it);

sort(mass.begin(),mass.end(),CMP);

cout<<endl<<endl<<endl<<endl;
for(i=0;i<mass.size();i++)
    
	cout<<mass[i].x<<" "<<mass[i].y<<endl;

vector<A> stack;

A temp;
temp.x=sx;
temp.y=sy;

stack.push_back(temp);
stack.push_back(mass[0]);

for(i=1;i<mass.size();i++)
{
	int x1,x2,x3,y1,y2,y3;
	
	int status=0;

	while(status==0)
	{
	x3=mass[i].x;
	y3=mass[i].y;
	x1=stack[stack.size()-2].x;
	y1=stack[stack.size()-2].y;
	x2=stack[stack.size()-1].x;
	y2=stack[stack.size()-1].y;


	if((x1*y3+y1*x2+x3*y2)-(x2*y3+y2*x1+x3*y1)>0)
		stack.pop_back();
	else {
		stack.push_back(mass[i]);
		status=1;}
	}
}
 
for(i=0;i<stack.size();i++)
	
    cout<<stack[i].x<<" "<<stack[i].y<<endl;

unsigned int vertex = 0;
    double x = 0;
    double y = 0;

    vector< pair<double, double> > v;

cout<<"Enter A Valid Number Of Vertices: " <<endl;
    cin >> vertex;
    cout<< endl;

    while(vertex > 0) {
        cout<<"Enter Pair X Y: ";
        cin >> x >> y;
        v.push_back(make_pair(x, y));
        vertex--;
    }

    cout<<"The Area Of The Polygon Is: " << CalcArea(v) <<endl;

system ("pause");

return 0;
}


Look at the way the pairs are pusshed in v.I want to change it.
When the program starts, it asks the user to input the points.
The program outputs the points which are needed to be calculated the area.Then the program asks how many are those points.The user inputs the number of the points, and after that He/she should input the points.Then the program computes the area...My question is- can I avoid all of this and make it more simple so the user inputs the points of the polygon, and the program makes the rest?
Is it so complicated?I had a new idea.To use v.push_back(make_pair(stack.x[i], stack.y[i]));
instead of v.push_back(make_pair(x[i], y[i]));.I think it should be like this, but it gives an error- 141 'class std::vector<A, std::allocator<A> >' has no member named 'x'
141 'class std::vector<A, std::allocator<A> >' has no member named 'y'
Any ideas?
The way you've named your variables based on nothing in particular, your inconsistent indentations and use of brackets, lack of whitespace where it matters, random declaration style and habit of making new variables as you need them is what's making it complicated. So to answer your question, your task although simple is being made more difficult having to decipher this mass of code.

"x" and "y" are NOT array's so they CAN NOT be used as arrays. You fix this by redefining "x" and "y" as arrays.
Yes yes, you are right, I just have the habit to write the code, and after its compiling and running properly, i make it more "elegant".As for the x's and y's, yes I made a mistake (omg), instead of v.push_back(make_pair(stack[i].x, stack[i].y)); i wrote v.push_back(make_pair(stack.x[i], stack.y[i]));.I fixed that.Now it compiles without errors, but gives an error in the computations.Now I am trying to fix it...
I reduced my code a lot, and now it looks like this:
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
#include <iostream>
#include <vector>
#include <cmath>
using namespace std;

// Function that calculates the absolute value
double MyAbs(double num)
{
    double inv = num * -1;
    return (num <= 0) ? inv : num;
}

// Function that calculates the area  
double CalcArea(vector< pair<double, double> > list)
{
    double area = 0; // Total Area
    double diff = 0; // Difference Of Y{i + 1} - Y{i - 1}
    unsigned int last = list.size() - 1; // Size Of Vector - 1

    /* Given vertices from 1 to n, we first loop through
    the vertices 2 to n - 1. */
    for(unsigned int i = 1; i < last; i++)
    {
        diff =list[i + 1].second - list[i - 1].second;
        area += list[i].first * diff;
    }

    /* Now We Consider The Vertex 1 And The Vertex N */
    diff = list[1].second - list[last].second;
    area += list[0].first * diff; // Vertex 1

    diff = list[0].second - list[last - 1].second;
    area += list[last].first * diff; // Vertex N

    /* Calculate The Final Answer */
    area = 0.5 * MyAbs(area);
    return area; // Return The Area
}


int main()
{
    unsigned int vertex = 0;
    double x = 0;
    double y = 0;
 vector< pair<double, double> > v;
  vector <double> a(5);
    a[0] = 4;
    a[1] = 5;
    a[2] = 6;
    a[3] = 7;
    a[4] = 8; 
    vector <double> b(5);
    b[0] = 79;
    b[1] =98;
    b[2] = 88;
    b[3] = 99;
    b[4] = 90; 
    
int verte=5;
    while(verte > 0) 
{
        //cout<<"Enter Pair X Y: ";
         
        for(int i=0;i<=a.size();i++)
        for(int j=0;j<=b.size();j++)
        v.push_back(make_pair(a[i], b[j]));
        verte--;
}

    cout<<"The Area Of The Polygon Is: " << CalcArea(v) <<endl;
    system ("pause");
    return 0;
}


The problem now is that I cant find a way to assign the points which I need for the calculations.The best result would be to take the points from a .txt file, but I couldnt do it.Now I try to make two vectors, which stores the points, and with two loops to take those points and merge them in vector "v".The code works, but there is a logic error, because the calculations are wrong..
Any ideas what should I do?
Thanks :)
Last edited on
Nobody helps me, not very nice feeling ;)...
1
2
3
4
5
6
7
8
9
   while(verte > 0) 
{
        //cout<<"Enter Pair X Y: ";
         
        for(int i=0;i<=a.size();i++)
        for(int j=0;j<=b.size();j++)
        v.push_back(make_pair(a[i], b[j]));
        verte--;
}


How many points did you intend to create there?
Actually two points.I noticed that I can make it without the second loop.I also added a diagnostic messages, to see why I get a wrong answer.
I made it like this:
1
2
3
4
5
6
7
for(int i=0;i<=a.size();i++)
        {
       v.push_back(make_pair(a[i], b[i]));
        cout<<a[i]<<" ";
        cout<<b[i]<<"\n";
       
}

the output is:
56 39
35 68
62 18
7 44
18 30//everything is good so far
1699946596 83//That shouldnt be here

ps. With different set of points it gives the same strange output at the end-1699946596 83
ps. After some tests I found out that it comes from here cout<<b[i]<<"\n";...
Last edited on
I found it when I removed cout<<a[i]<<" ";.But when I changed the places of cout<<a[i]<<" "; and cout<<b[i]<<"\n";, this 1699946596 83 comes with "a"..Any ideas, I really dont know what it means.
If a and b are of size 5, and your for loop goes from i=0 to i=5 (which is being done with i<=a.size()), you're going to read a[0], a[1], a[2], a[3], a[4], a[5].

What is a[5]? It is off the end of your vector and will be some garbage value. You need to stop reading values at a[4].
If I understand you correctly, I should make it: for (int i=1...), but when I make it like this, the garbage still appears, but there is missing one pair of the points.
A vector named a of size 5 has the following elements: a[0], a[1], a[2], a[3], a[4].

If you start at i=i and end at i=5, you will read the following elements: a[1], a[2], a[3], a[4], a[5]. If you do this, you will have missed out a[0] (and, of course, in your code b[0] as well) and you'll be reading the garbage value a[5], which is exactly what you're doing.

You need to read a[0], a[1], a[2], a[3], a[4]. You need to start at i=0 and finished at i=4.
Pages: 12