Node: Path Constructors and Setting Functions, Next: , Previous: Path Data Members, Up: Path Reference

Constructors and Setting Functions

void Path (void) Default constructor
Creates an empty Path with no Points and no connectors.

void Path (const Point& p0, const Point& p1) Constructor
Creates a line (more precisely, a line segment) between p0 and p1. The single connector between the two Points is set to "--" and the data member line_switch (of type bool) is set to true. There are certain operations on Paths that are only applicable to lines, so it's necessary to store the information that a Path is a line.1
          Point A(-2, -2.5, -1);
          Point B(3, 2, 2.5)
          Path p(A, B);
          -| p:
             (-2, -2.5, -1) -- (3, 2, 2.5);

[Figure 110. Not displayed.]

Fig. 110.

void set (const Point& p0, const Point& p1) Setting function
Corresponds to the constructor above.
          Point P0(1, 2, 3);
          Point P1(3.5, -12, 75);
          Path q;
          q.set(P0, P1);
          -| q:
             (1, 2, 3) -- (3.5, -12, 75);

void Path (string connector, bool cycle, Point* p, [...], 0) Constructor
For Paths with an arbitrary number of Points and one type of connector.

connector is passed unchanged to out_file, so it must be a valid connector in MetaPost.

cycle indicates whether the Path is a cycle or not. cycle_switch is set to cycle. See Path Reference; Data Members. The filling and unfilling functions only work for Paths that are cycles. See Path Reference; Drawing and Filling. If a Path is a cycle, it is up to the user to make sure that it has sensible Point and connector values; 3DLDF doesn't check them. If they are not sensible, for instance, if the Path crosses itself, and you try to fill it, this will cause an error in MetaPost. It is possible that a Path will be "sensible" in some projections and not in others, although I have not tested this.

p is a pointer to the first Point that should go onto the Path. The ellipsis points (...) represent an arbitrary number of pointers to Points that should go onto the Path. The final argument must be 0, which is interpreted by the C++ compiler as the null pointer.2

It is admittedly a bit awkward to have to type "&p0" rather than "p0", and I have frequently forgotten to do it, which causes a compiler error, but all of the arguments must be pointers in order to be able to use 0 to indicate the end of the argument list. Convenience in typing function calls is not a high priority in 3DLDF, because once I've written an input routine, these function calls should be generated automatically. It will be more important to define a convenient syntax for the input routine.

          Point P0;
          Point P1(2);
          Point P2(2,2);
          Point P3(0,2);
          Path p("..", true, &P0, &P1, &P2, &P3, 0);

[Figure 111. Not displayed.]

Fig. 111.

void set (string connector, bool cycle, Point* p, [...], 0) Setting function
Corresponds to the constructor above.
          Point P[4];
          P[0].set(2, 1, 3);
          P[3] = P[2] =  P[1] = P[0];
          P[3] *= P[2] *=  P[1].rotate(3, 12, 18);
          P[3] *= P[2].shift(-2, -1, 3);
          P[3].shear(1.5, .5, 3.5);
          Path q("...", false, &P[0], &P[1], &P[2], &P[3], 0);
          -| q:
             (2, 1, 3) ... (0.92139, 1.51449, 3.29505) ...
             (-1.07861, 0.514487, 6.29505) ... (2.84065, -3.26065, 6.29505);

[Figure 112. Not displayed.]

Fig. 112.

void Path (Point* first_point_ptr, char* s, Point* p, [...], 0) Constructor
Constructor for Paths with an arbitrary number of Points and connectors. The first, required, argument is a pointer to a Point, followed by pointers to char alternating with pointers to Points.3 The last argument must be 0, i.e., the null pointer.

There is no need to indicate by means of an argument whether the Path is a cycle or not: If it is, the last argument before the 0 will be a char* (pointer to char), if not, it will be a Point*. The data member cycle_switch (of type bool) will be set to true or false accordingly.

          Point A;
          Point B(2, 0);
          Point C(3, 2);
          Point D(1, 3);
          Path p(&A, "..", &B, "..", &C, "--", &D, "...", 0);

[Figure 113. Not displayed.]

Fig. 113.

void set (Point *first_point_ptr, string s, Point *p, [...], 0) Setting function
Corresponds to the constructor above.

void Path (const Path& p) Copy constructor
Creates a new Path, making it a copy of p.

Path* create_new<Path> (const Path* p) Template specializations
Path* create_new<Path> (const Path& p)
Pseudo-constructors for dynamic allocation of Paths. They create a Path on the free store and allocate memory for it using new(Path). They return a pointer to the new Path.

If p is a non-zero pointer or a reference, the new Path will be a copy of p. If the new object is not meant to be a copy of an existing one, 0 must be passed to create_new<Path>() as its argument. See Dynamic Allocation of Shapes, for more information.

create_new<Path>() is used in the drawing and filling functions for copying a Path and putting the copy onto a Picture. See Path Reference; Drawing and Filling.


  1. It isn't sufficient to check whether a Path consists of only two Points to determine whether it is a line or not, since a connector with ``curl'' could cause it to be non-linear. On the other hand, Paths containing only colinear Points and the connector "--" are perfectly legitimate lines. I'm in the process of changing all of the code that tests for linearity by checking the value of line_switch, so that it uses is_linear() instead. When I've done this, it may be possible to eliminate line_switch. See Path Reference; Data Members, and Path Reference; Querying.

  2. Stroustrup, The C++ Programming Language, p. 88.

  3. Where possible, I prefer to use the C++ data type string rather than char*, however it was necessary to use char* here because 0 is not a valid string, even though string may be implemented as char*, and 0 must be a valid argument, since it is needed to indicate the end of the argument list.