Hexagon Class


Hello all,

The exercise 8 of chapter 13 of book
( http://www.stroustrup.com/programming1.html ) says:

Define a class Hexagon (a Hexagon is a regular six sided polygon). Use the center and the distance from the center to a corner point as constructor arguments.


I solved it this way (below code). And although I had doubt about the answer but anyway then went for exercise 13-10 which says:

Define a class regular_polygon. Use the center, the number of sides (>2) and the distance from the center to a corner as constructor arguments.


When I thought about a solution for this one, I found that utilize a loop and finding a relationship between i & j is very difficult, more than the previous one (13-8).

First: Is this below code *what you expected* as a solution for exercise 13-8 please?

Then: Is there any way related to the answer of exercise 13-8 (below code) which is possible to be used for solving the exercise 13-10 please?

Thanks in advance.

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
#include <Simple_window.h>
  
 struct Hexagon : Shape {
        Hexagon(Point p, int d): d(d)
	   { add(Point(p)); }

	void draw_lines() const 
	    { 
		fl_line(point(0).x-d,point(0).y,  point(0).x-d/2,point(0).y-(d-d/20*3),
                        point(0).x+d/2,point(0).y-(d-d/20*3));    
		fl_line(point(0).x+d/2,point(0).y-(d-d/20*3),  point(0).x+d,point(0).y,
                        point(0).x+d/2,point(0).y+(d-d/20*3));             
		fl_line(point(0).x+d/2,point(0).y+(d-d/20*3),  point(0).x-d/2,point(0).y+(d-d/20*3),
                        point(0).x-d,  point(0).y);  
	    }
 private:
	int d;
};

 int main() {
	using namespace Graph_lib; 

     Simple_window win(Point(100,100), 600,400, "Hexagon");	
     Graph_lib::Rectangle r(Point (50,50), 400,200);
     Point p(100,100);
      int d = 50;
      Hexagon h(p,d);
      win.attach(h);
    win.wait_for_button();
}
Last edited on
Just use trigonometry to find all the vertices, and loop over the number of vertices.
Last edited on
Yeah, but the problem is how to use of trigonometry! Anyway I thought about it and wrote this one. Although it works properly for square and I didn't use any magic number in it but for other regular polygons it doesn't work properly. May you please have a look at it?

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
#include <Simple_window.h>

struct Regular_Polygon : Shape {

	Regular_Polygon(Point p, int d, int s): d(d), s(s)
	   { add(Point(p)); }

	void draw_lines() const 
	{ 
	     fl_line(point(0).x-d+(360/s-d),point(0).y-d+(360/s-d),   point(0).x+d-(360/s-d),point(0).y-d+(360/s-d));
	     fl_line(point(0).x+d-(360/s-d),point(0).y-d+(360/s-d),   point(0).x+d-(360/s-d),point(0).y+d-(360/s-d));
             fl_line(point(0).x+d-(360/s-d),point(0).y+d-(360/s-d),   point(0).x-d+(360/s-d),point(0).y+d-(360/s-d));
	     fl_line(point(0).x-d+(360/s-d),point(0).y+d-(360/s-d),   point(0).x-d+(360/s-d),point(0).y-d+(360/s-d));
	}

private:
	int d, s;
};

int main()
{
	using namespace Graph_lib; 

    Simple_window win(Point(100,100), 600,400, "Regular_Polygon");	
    Point p(200,200);
	int d = 100;
	int s = 4;
	Regular_Polygon r_p(p,d,s);
	win.attach(r_p);
    win.wait_for_button();
}

For trigonometry, here is a brief rundown - I won't give you code, but you should be able to work it out from here.

Assume you have a point. From this point, you have drawn a horizontal line, and from the end of that horizontal line, you have drawn a vertical line. From the end of that vertical line, you now have a triangle:
  /|
 / |
----

Let the angle on the inside of the triangle (around your starting point) be called theta. Now, for a bit of trigonometry - you know that the sine of an angle is the length of the opposite side / the length of the hypotenuse:
sin(theta) = O/H; // pseudocode
Also, the cosine of an angle is the length of the adjacent side / the length of the hypotenuse:
cos(theta) = A/H; // pseudocode

Now, we already know the hypotenuse - that is the radius of the polygon you are drawing! We can also give it the angle. With this, we can work out a point for the vertex of a polygon, by rearranging the equation:
1
2
H * cos(theta) = A; // H = radius, A = x value
H * sin(theta) = O; // H = radius, O = y value 


Now you can work out the positions of the point in an n-sided polygon - divide 360 by the number of sides in the polygon and get the vertices using those formulas we derived above. Note that the C++ Standard Library sin and cos functions take their operands in radians, you'll need to multiply your angles by (PI/180) (there are 2*pi radians in a circle).

Hope this helps!
First of all, thank you very much for your instructions.

Yeah, you are right about the lengths of the sides of a regular polygon.
For example using that equation or another one (http://en.wikipedia.org/wiki/Law_of_sines ) we can obtain the lengths of the sides.
For example when d=100;
if s=3 => all the sides have the length of 172,
if s=4 => all the sides have the length of 141,
and so on.

We can use of 360/s (where s is the number of sides) and also use those equations.

But, consider we have obtained the lengths of the sides of a regular polygon, how draw them!? The problem is this.
We can't use of fl_src() because it draws arcs. For using something like fl_line() we NEED points not the length of the sides!
When did I say I was getting the length of the sides? Or are you talking to someone else? Anyway, here is an example implementation, try it to see if it works (I can't test it myself):
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
#include <Simple_window.h>
#include <cmath>

class Regular_Polygon : public Shape {
    public:
        Regular_Polygon(Point p, int r, int s): _r(r), _s(s) { add(Point(p)); }

        void draw_lines() const {
            const float PiOn180 = 3.1415926535f / 180.0f;
            const float angle = (360.0f / _s) * PiOn180;

            for (int i = 0; i < _s; ++i) {
                fl_line(point(0).x + std::cos(i * angle) * _r,
                        point(0).y + std::sin(i * angle) * _r,
                        point(0).x + std::cos((i+1) * angle) * _r, 
                        point(0).y + std::sin((i+1) * angle) * _r);
            }
        }

    private:
        int _r;
        int _s;
};

int main() {
    using namespace Graph_lib; 

    Simple_window win(Point(100,100), 600,400, "Regular_Polygon");	

    Point p(200,200);
    int r = 100;
    int s = 4;
	
    Regular_Polygon r_p(p, r, s);
    win.attach(r_p);
    win.wait_for_button();

    return 0;
}

Something like that should work. At least now you should get the idea. Note that there are also more efficient ways of doing this that don't require lots of expensive trigonometric calculations, but this is easier to understand conceptually unless you know some vector maths.

EDIT:
Note I could've gotten this completely wrong by not understanding how fl_line works, but from what I'd expect it takes four parameters (?), being the x,y coords of the start of the line and the x,y coords of the end of the line, as in: void fl_line(int x1, int y1, int x2, int y2);
Last edited on
About the fl_line(), yes, that's it but I haven't understood how those sin and cos here work! Although I haven't been thought about them until this now from that book but they appear clear!
When I tried to obtain the output points from that fl_line() they were these:

fl_line(200,100,200,103);
fl_line(200,103,200,105);
fl_line(200,105,200,108);
fl_line(200,108,200,110);


But how they can draw a polygon, I don't know!
Anyway, I think I should think of this subject more.
Thank you for the time you assigned to guide me.
Last edited on
Topic archived. No new replies allowed.