Draw an Equilateral Triangle using FLTK (indirectly)

Pages: 12
Yeah, just got that fixed. One line is crooked, but aside from that it's a good triangle. But its top point isn't facing the top of the window. How do I fix that?

Here:
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
// Osman Zakir
// 3 / 22 / 2017
// Bjarne Stroustrup: Programming: Principles and Practice Using C++ 2nd Edition
// Chapter 12 Exercise 11
// File chapter12ex11.cpp
// Exercise Specifications:
/**
* Draw a series of regular polygons, one inside the other. The innermost
* should be an equilateral triangle, enclosed by a square, enclosed by a
* pentagon, etc. For the mathematically adept only: let all the points of
* each N-polygon touch sides of the (N+1) -polygon. Hint: The trigonometric
* functions are found in <cmath> (§24.8, §B.9.2).
*/

#include "../../Simple_window.h"
#include "../../Graph.h"
#include <cmath>

int main()
{
	using namespace Graph_lib;

	Point top_left{ 100, 100 };
	constexpr int win_width = 600;
	constexpr int win_height = 400;
	Simple_window win{ top_left, win_width, win_height, "Polygons" };

	try
	{
		constexpr double pi = 3.14159265359;
		constexpr int revolution = 360;
		constexpr int radius = 100;
		int sides = 3;
		Graph_lib::Polygon tri;
		for (int deg = 0; deg < revolution; deg += (revolution / sides))
		{
			Point pt
			{
				int(radius * cos(deg * pi / 180) + (win_width / 2.0)),
				abs(int(radius * sin(deg * pi / 180) - (win_height / 2.0)))
			};
			tri.add(pt);
			tri.set_color(Color::black);
			cout << pt.x << ',' << pt.y << '\n';
		}

		win.attach(tri);

		win.wait_for_button();
	}
	catch (const runtime_error &rte)
	{
		Text err_msg_start{ Point{ 150, 200 }, "Runtime_error: " };
		Text err_msg{ Point{ 250, 200 }, rte.what() };

		err_msg_start.set_color(Color::black);
		err_msg.set_color(Color::black);

		win.attach(err_msg_start);
		win.attach(err_msg);

		win.wait_for_button();
		return 1;
	}
	catch (const exception &e)
	{
		Text err_msg_start{ Point{ 150, 200 }, "Exception: " };
		Text err_msg{ Point{ 250, 200 }, e.what() };

		err_msg_start.set_color(Color::black);
		err_msg.set_color(Color::black);

		win.attach(err_msg_start);
		win.attach(err_msg);

		win.wait_for_button();
		return 2;
	}
	catch (...)
	{
		Text err_msg{ Point{ 150, 200 }, "An unknown exception occurred." };

		err_msg.set_color(Color::black);

		win.attach(err_msg);

		return 3;
	}
}


Output screenshot: https://1drv.ms/i/s!As6LkLqTe7Ps7gbhqd2mUKTz47bM

I wonder if it depends on where I put parentheses in the calculation? Maybe I should check and see.

Is it possible to direct std::cout's output to a GUI window?
Last edited on
The reason the triangle points to the right, is because cos(0) == 1 and sin(0) == 0, giving you the point (1, 0), which is to the right of the origin.
If you want it to start at the top (θ = 90° or π/2 radians), do
1
2
3
4
5
Point point
(
    radius * cos(deg * pi / 180.0 + pi / 2) + win_width / 2.0,
    radius * sin(deg * pi / 180.0 + pi / 2) - win_height / 2.0 
)


Is it possible to direct std::cout's output to a GUI window?

If I recall correctly, there is a text/label object which allows you to do that.
Thanks for the formula help.

As for the text object, I think you can only draw the letters by pointing out the top left point of the message you want to print. The book shows how to attach a stringstream message to a Text object, but that's about it.

I tried it. The "square" is still coming out as a diamond and one or two sides are crooked. Isn't there a way to fix all that?

Screenshot: https://1drv.ms/i/s!As6LkLqTe7Ps7gc1rYwEMluUYIdh

Edit: Okay, I have it now. Would just like to know of a way to make the diamond into an actual square.

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
// Osman Zakir
// 3 / 22 / 2017
// Bjarne Stroustrup: Programming: Principles and Practice Using C++ 2nd Edition
// Chapter 12 Exercise 11
// File chapter12ex11.cpp
// Exercise Specifications:
/**
* Draw a series of regular polygons, one inside the other. The innermost
* should be an equilateral triangle, enclosed by a square, enclosed by a
* pentagon, etc. For the mathematically adept only: let all the points of
* each N-polygon touch sides of the (N+1) -polygon. Hint: The trigonometric
* functions are found in <cmath> (§24.8, §B.9.2).
*/

#include "../../Simple_window.h"
#include "../../Graph.h"
#include <cmath>

void draw_poly(Simple_window &win, Graph_lib::Polygon& poly,
	const int sides, const int win_width, const int win_height);

int main()
{
	using namespace Graph_lib;

	Point top_left{ 100, 100 };
	constexpr int win_width = 600;
	constexpr int win_height = 400;
	Simple_window win{ top_left, win_width, win_height, "Polygons" };

	try
	{
		Graph_lib::Polygon tri;
		constexpr int tri_sides = 3;
		draw_poly(win, tri, tri_sides, win_width, win_height);

		Graph_lib::Polygon quadr;
		constexpr int quadr_sides = 4;
		draw_poly(win, quadr, quadr_sides, win_width, win_height);

		Graph_lib::Polygon penta;
		constexpr int penta_sides = 5;
		draw_poly(win, penta, penta_sides, win_width, win_height);

		Graph_lib::Polygon hexa;
		constexpr int hexa_sides = 6;
		draw_poly(win, hexa, hexa_sides, win_width, win_height);

		Graph_lib::Polygon septa;
		constexpr int septa_sides = 7;
		draw_poly(win, septa, septa_sides, win_width, win_height);

		Graph_lib::Polygon octa;
		constexpr int octa_sides = 8;
		draw_poly(win, octa, octa_sides, win_width, win_height);

		Graph_lib::Polygon nova;
		constexpr int nova_sides = 9;
		draw_poly(win, nova, nova_sides, win_width, win_height);

		Graph_lib::Polygon deca;
		constexpr int deca_sides = 10;
		draw_poly(win, deca, deca_sides, win_width, win_height);

		win.wait_for_button();
	}
	catch (const runtime_error &rte)
	{
		Text err_msg_start{ Point{ 150, 200 }, "Runtime_error: " };
		Text err_msg{ Point{ 250, 200 }, rte.what() };

		err_msg_start.set_color(Color::black);
		err_msg.set_color(Color::black);

		win.attach(err_msg_start);
		win.attach(err_msg);

		win.wait_for_button();
		return 1;
	}
	catch (const exception &e)
	{
		Text err_msg_start{ Point{ 150, 200 }, "Exception: " };
		Text err_msg{ Point{ 250, 200 }, e.what() };

		err_msg_start.set_color(Color::black);
		err_msg.set_color(Color::black);

		win.attach(err_msg_start);
		win.attach(err_msg);

		win.wait_for_button();
		return 2;
	}
	catch (...)
	{
		Text err_msg{ Point{ 150, 200 }, "An unknown exception occurred." };

		err_msg.set_color(Color::black);

		win.attach(err_msg);

		return 3;
	}
}

void draw_poly(Simple_window &win, Graph_lib::Polygon& poly, 
	const int sides, const int win_width, const int win_height)
{
	constexpr double pi = 3.14159265359;
	constexpr int revolution = 360;
	constexpr int radius = 100;
	for (int deg = 0; deg < revolution; deg += (revolution / sides))
	{
		Point pt
		{
			int(radius * cos(deg * pi / 180.0 + pi / 2) + win_width / 2.0),
			abs(int(radius * sin(deg * pi / 180.0 + pi / 2) - win_height / 2.0))
		};
		poly.add(pt);
		poly.set_color(Color::black);
	}
	win.attach(poly);
}


Screenshot: https://1drv.ms/i/s!As6LkLqTe7Ps7ggkHDmL1jsf_Jde
Last edited on
I tried it. The "square" is still coming out as a diamond and one or two sides are crooked. Isn't there a way to fix all that?

A diamond is a square but rotated 90°. I believe the reason the sides seem crooked is due to diagonals.
https://i.stack.imgur.com/pA7uy.png
Topic archived. No new replies allowed.
Pages: 12