How to define a class

Hello all,

The exercise is as follows;
Define a class Arc, which draws a part of an ellipse. Hint: fl_arc()

And the body of the class ellipse is as follows in the book (PPP):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
struct Ellipse :Shape {
	Ellipse(Point p, int w, int h); //center, max and min distance from center

	void draw_lines()const;

	Point center()const;
	Point focus1()const;
	Point focus2()const;

	void set_major(int ww) {w=ww;}
	int major() const {return w;}

	void set_minor(int hh) {h=hh;}
	int minor() const {return h;}

private:
	int w;
	int h;
};


and the fl_arc() probably is part of FLTK which I've installed it on my machine.

Now the problem here is that while I don't can see the full version of the body of the ellipse how to do this exercise?
Any help?
Why would you need to see implementation of ellipse at all?
To see an inteface is enough. If you post what fl_arc() does, we probably will be able to help you.
This is the implementation of fl_arc:

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
//
// "$Id: fl_arc.cxx 5349 2006-08-23 14:43:07Z matt $"
//
// Arc functions for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-2005 by Bill Spitzak and others.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
// USA.
//
// Please report all bugs and problems on the following page:
//
//     http://www.fltk.org/str.php
//

// Utility for drawing arcs and circles.  They are added to
// the current fl_begin/fl_vertex/fl_end path.
// Incremental math implementation:

#include <FL/fl_draw.H>
#include <FL/math.h>

// avoid problems with some platforms that don't 
// implement hypot.
static double _fl_hypot(double x, double y) {
  return sqrt(x*x + y*y);
}


void fl_arc(double x, double y, double r, double start, double end) {

  // draw start point accurately:
  
  double A = start*(M_PI/180);		// Initial angle (radians)
  double X =  r*cos(A);			// Initial displacement, (X,Y)
  double Y = -r*sin(A);			//   from center to initial point
  fl_vertex(x+X,y+Y);			// Insert initial point

  // Maximum arc length to approximate with chord with error <= 0.125
  
  double epsilon; {
    double r1 = _fl_hypot(fl_transform_dx(r,0), // Horizontal "radius"
		          fl_transform_dy(r,0));
    double r2 = _fl_hypot(fl_transform_dx(0,r), // Vertical "radius"
		          fl_transform_dy(0,r));
		      
    if (r1 > r2) r1 = r2;		// r1 = minimum "radius"
    if (r1 < 2.) r1 = 2.;		// radius for circa 9 chords/circle
    
    epsilon = 2*acos(1.0 - 0.125/r1);	// Maximum arc angle
  }
  A = end*(M_PI/180) - A;		// Displacement angle (radians)
  int i = int(ceil(fabs(A)/epsilon));	// Segments in approximation
  
  if (i) {
    epsilon = A/i;			// Arc length for equal-size steps
    double cos_e = cos(epsilon);	// Rotation coefficients
    double sin_e = sin(epsilon);
    do {
      double Xnew =  cos_e*X + sin_e*Y;
		Y = -sin_e*X + cos_e*Y;
      fl_vertex(x + (X=Xnew), y + Y);
    } while (--i);
  }
}

#if 0 // portable version.  X-specific one in fl_vertex.cxx
void fl_circle(double x,double y,double r) {
  _fl_arc(x, y, r, r, 0, 360);
}
#endif

//
// End of "$Id: fl_arc.cxx 5349 2006-08-23 14:43:07Z matt $".
// 


But it made the problem more complex seemingly.
Try following 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
void fl_el_arc(double x, double y, double rx, double ry, double start, double end) {

  // draw start point accurately:

  double A = start*(M_PI/180);		// Initial angle (radians)
  double X =  rx*cos(A);			// Initial displacement, (X,Y)
  double Y = -ry*sin(A);			//   from center to initial point
  fl_vertex(x+X,y+Y);			// Insert initial point

  // Maximum arc length to approximate with chord with error <= 0.125

  double epsilon; {
    double r1 = _fl_hypot(fl_transform_dx(ry,0), // Horizontal "radius"
		          fl_transform_dy(ry,0));
    double r2 = _fl_hypot(fl_transform_dx(0,ry), // Vertical "radius"
		          fl_transform_dy(0,ry));

    if (r1 > r2) r1 = r2;		// r1 = minimum "radius"
    if (r1 < 2.) r1 = 2.;		// radius for circa 9 chords/circle

    epsilon = 2*acos(1.0 - 0.125/r1);	// Maximum arc angle
  }
  double xy = rx / ry;
  A = end*(M_PI/180) - A;		// Displacement angle (radians)
  int i = int(ceil(fabs(A)/epsilon));	// Segments in approximation

  if (i) {
    epsilon = A/i;			// Arc length for equal-size steps
    double cos_e = cos(epsilon) * xy;	// Rotation coefficients
    double sin_e = sin(epsilon);
    do {
      double Xnew =  cos_e*X + sin_e*Y;
		Y = -sin_e*X + cos_e*Y;
      fl_vertex(x + (X=Xnew), y + Y);
    } while (--i);
  }
}
And call it like fl_el_arc(5, 3, 5, 3, 90, 360);. Tell me what happened (There should be part of ellipse drawn)
The following was the code I ran. Although it was compiled successfully but it didn't show any thing.


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
#include <Simple_window.h>
#include <FL/fl_draw.H>
#include <FL/math.h>

static double _fl_hypot(double x, double y) {
  return sqrt(x*x + y*y);
}

void fl_el_arc(double x, double y, double rx, double ry, double start, double end) {

  // draw start point accurately:

  double A = start*(M_PI/180);		// Initial angle (radians)
  double X =  rx*cos(A);			// Initial displacement, (X,Y)
  double Y = -ry*sin(A);			//   from center to initial point
  fl_vertex(x+X,y+Y);			// Insert initial point

  // Maximum arc length to approximate with chord with error <= 0.125

  double epsilon; {
    double r1 = _fl_hypot(fl_transform_dx(ry,0), // Horizontal "radius"
		          fl_transform_dy(ry,0));
    double r2 = _fl_hypot(fl_transform_dx(0,ry), // Vertical "radius"
		          fl_transform_dy(0,ry));

    if (r1 > r2) r1 = r2;		// r1 = minimum "radius"
    if (r1 < 2.) r1 = 2.;		// radius for circa 9 chords/circle

    epsilon = 2*acos(1.0 - 0.125/r1);	// Maximum arc angle
  }
  double xy = rx / ry;
  A = end*(M_PI/180) - A;		// Displacement angle (radians)
  int i = int(ceil(fabs(A)/epsilon));	// Segments in approximation

  if (i) {
    epsilon = A/i;			// Arc length for equal-size steps
    double cos_e = cos(epsilon) * xy;	// Rotation coefficients
    double sin_e = sin(epsilon);
    do {
      double Xnew =  cos_e*X + sin_e*Y;
		Y = -sin_e*X + cos_e*Y;
      fl_vertex(x + (X=Xnew), y + Y);
    } while (--i);
  }
}

int main()

{
	using namespace Graph_lib;

	Point t(100,100);            
	Simple_window win(t,500,300,"Test");
	fl_el_arc(5, 3, 5, 3, 90, 360);
	win.wait_for_button();
}


PS: I think the solution for that exercise isn't it because the knowledge level that I have been taught till this chapter (13th of PPP) is less than being able to write such a complex codes -with respect to you. And I appreciate your responses.
Well I tried to quickpatch function to draw an ellipse instead of circle — ellipse is basically a stretched/squished circle.

Bu in reality it is simplier: http://www.fltk.org/documentation.php/doc-1.1/drawing.html#drawing
void fl_arc(int x, int y, int w, int h, double a1, double a2)
void fl_pie(int x, int y, int w, int h, double a1, double a2)

Draw ellipse sections using integer coordinates. These functions match the rather limited circle drawing code provided by X and WIN32. The advantage over using fl_arc with floating point coordinates is that they are faster because they often use the hardware, and they draw much nicer small circles, since the small sizes are often hard-coded bitmaps.

If a complete circle is drawn it will fit inside the passed bounding box. The two angles are measured in degrees counterclockwise from 3'oclock and are the starting and ending angle of the arc, a2 must be greater or equal to a1.

fl_arc() draws a series of lines to approximate the arc. Notice that the integer version of fl_arc() has a different number of arguments than the fl_arc() function described later in this chapter.

fl_pie() draws a filled-in pie slice. This slice may extend outside the line drawn by fl_arc; to avoid this use w - 1 and h - 1.


So you just need to define class Arc, which will hold an Ellipse and two angles: start and end. Also you need to provide draw_lines function which will call fl_arc()
If draw_lines is virtual, you might inherit from ellipse (do it only if assigment say so) or Shape (your best bet)
Classes are an expanded concept of data structures: like data structures, they can contain data members, but they can also contain functions as members.

An object is an instantiation of a class. In terms of variables, a class would be the type, and an object would be the variable.

Classes are defined using either keyword class or keyword struct, with the following syntax:



class class_name {
access_specifier_1:
member1;
access_specifier_2:
member2;
...
} object_names;



Where class_name is a valid identifier for the class, object_names is an optional list of names for objects of this class. The body of the declaration can contain members, which can either be data or function declarations, and optionally access specifiers.

The format is the same as for plain data structures, except that they can also include functions, and have this new things called access specifiers. An access specifier is one of the following three keywords: private, public or protected. These specifiers modify the access rights for the members that follow them:

•private members of a class are accessible only from within other members of the same class (or from their "friends").
•protected members are accessible from other members of the same class (or from their "friends"), but also from members of their derived classes.
•Finally, public members are accessible from anywhere where the object is visible.
OK guys, this is the code that contains the struct "arc" which is exactly like Ellipse. I first copied the Ellipse struct and then modified it and named the Ellipse to "arc". I also changed the "fl_arc" which has its changed parts underlined below.

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

struct arc : Shape {

    arc(Point p, int w, int h)    // center, min, and max distance from center
        : w(w), h(h)
    { 
        add(Point(p.x-w,p.y-h));
    }

	void draw_lines() const {fl_arc(point(0).x,point(0).y,w+w,h+h,0,120);}

    Point center() const { return Point(point(0).x+w,point(0).y+h); }
    Point focus1() const { return Point(center().x+int(sqrt(double(w*w-h*h))),center().y); }
    Point focus2() const { return Point(center().x-int(sqrt(double(w*w-h*h))),center().y); }

    void set_major(int ww) { w=ww; }
    int major() const { return w; }
    void set_minor(int hh) { h=hh; }
    int minor() const { return h; }

private:
    int w;
    int h;
};

int main()
{
	using namespace Graph_lib;

	Point t(100,100);
	Simple_window win(t,600,400, "semi-ellipse");
	arc e(Point(200,200),150,50);
   win.wait_for_button();
}


This code will be complied but it doesn't show anything!
What do you think about this sample please?
Last edited on
Although I could to find the bug of that code but still I have some issues about that exercise that I like to mention them among you professional guys.

If this line win.attach(e); will be included the problem runs successfully.

The remained problems are these:

1- Now when I use the name "Arc" instead of the "arc" in above code I get this error.

Error 8 error C2146: syntax error : missing ';' before identifier 'a' c:\users\cs\documents\visual studio 2012\projects\test2\test2\test2.cpp 25 Error 10 error C3861: 'a': identifier not found c:\users\cs\documents\visual studio 2012\projects\test2\test2\test2.cpp 25

2- The problem has wanted us to define a class (not a struct) so when I replace struct with class and put keyword public: just after class arc : Shape {, I get this error.

*Error 8 error C2243: 'type cast' : conversion from 'arc *' to 'Graph_lib::Shape &' exists, but is inaccessible c:\users\cs\documents\visual studio 2012\projects\test2\test2\test2.cpp 29 Error 9 error C2243: 'type cast' : conversion from 'arc ' to 'Graph_lib::Shape &' exists, but is inaccessible c:\users\cs\documents\visual studio 2012\projects\test2\test2\test2.cpp 30

Any idea?
Last edited on
Topic archived. No new replies allowed.