summaryrefslogtreecommitdiff
path: root/app/bin/trkseg.h
blob: 8a3909771ed2f3f7211d633594e47042648942d3 (plain)
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
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
/** \file trkseg.h
 *
 */

/*  XTrkCad - Model Railroad CAD
 *  Copyright (C) 2005 Dave Bullis
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program 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 General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

#ifndef TRKSEG_H
#define TRKSEG_H

#include "common.h"

#define MAX_PATH_SEGS	(127)

typedef enum { FREEFORM, RECTANGLE, POLYLINE
             } PolyType_e;


typedef struct trkSeg_t {
	char type;
	wDrawColor color;
	LWIDTH_T lineWidth;
	dynArr_t bezSegs;       //placed here to avoid overwrites
	union {
		struct {
			coOrd pos[4];
			ANGLE_T angle;
			long option;
		} l;
		struct {
			coOrd pos[4];
			ANGLE_T angle0;
			ANGLE_T angle3;
			DIST_T minRadius;
			DIST_T radius0;
			DIST_T radius3;
			DIST_T length;
		} b;
		struct {
			coOrd center;
			ANGLE_T a0, a1;
			DIST_T radius;
		} c;
		struct {
			coOrd pos;
			ANGLE_T angle;
			DIST_T R, L;
			DIST_T l0, l1;
			unsigned int flip:1;
			unsigned int negate:1;
			unsigned int Scurve:1;
		} j;
		struct {
			coOrd pos;
			ANGLE_T angle;
			wFont_p fontP;
			FONTSIZE_T fontSize;
			BOOL_T boxed;
			char * string;
		} t;
		struct {
			int cnt;
			pts_t * pts;
			coOrd orig;
			ANGLE_T angle;
			PolyType_e polyType;
		} p;
	} u;
} trkSeg_t;
typedef struct trkSeg_t * trkSeg_p;

#define SEG_STRTRK		('S')
#define SEG_CRVTRK		('C')
#define SEG_BEZTRK      ('W')
#define SEG_STRLIN		('L')
#define SEG_CRVLIN		('A')
#define SEG_BEZLIN      ('H')
#define SEG_JNTTRK		('J')
#define SEG_FILCRCL		('G')
#define SEG_POLY		('Y')
#define SEG_FILPOLY		('F')
#define SEG_TEXT		('Z')
#define SEG_UNCEP		('E')
#define SEG_CONEP		('T')
#define SEG_PATH		('P')
#define SEG_SPEC		('X')
#define SEG_CUST		('U')
#define SEG_DOFF		('D')
#define SEG_BENCH		('B')
#define SEG_DIMLIN		('M')
#define SEG_TBLEDGE		('Q')

#define IsSegTrack( S ) ( (S)->type == SEG_STRTRK || (S)->type == SEG_CRVTRK || (S)->type == SEG_JNTTRK || (S)->type == SEG_BEZTRK)

extern dynArr_t tempSegs_da;

#define tempSegs(N) DYNARR_N( trkSeg_t, tempSegs_da, N )

extern char tempSpecial[4096];
extern char tempCustom[4096];

void ComputeCurvedSeg(
        trkSeg_p s,
        DIST_T radius,
        coOrd p0,
        coOrd p1 );

coOrd GetSegEndPt(
        trkSeg_p segPtr,
        EPINX_T ep,
        BOOL_T bounds,
        ANGLE_T * );

void GetTextBounds( coOrd, ANGLE_T, char *, FONTSIZE_T, coOrd *, coOrd * );
void GetSegBounds( coOrd, ANGLE_T, wIndex_t, trkSeg_p, coOrd *, coOrd * );
void MoveSegs( wIndex_t, trkSeg_p, coOrd );
void RotateSegs( wIndex_t, trkSeg_p, coOrd, ANGLE_T );
void FlipSegs( wIndex_t, trkSeg_p, coOrd, ANGLE_T );
void RescaleSegs( wIndex_t, trkSeg_p, DIST_T, DIST_T, DIST_T );
void CloneFilledDraw( wIndex_t, trkSeg_p, BOOL_T );
void FreeFilledDraw( wIndex_t, trkSeg_p );
DIST_T DistanceSegs( coOrd, ANGLE_T, wIndex_t, trkSeg_p, coOrd *, wIndex_t * );
ANGLE_T GetAngleSegs( wIndex_t, trkSeg_p, coOrd *, wIndex_t *, DIST_T *,
                      BOOL_T *, wIndex_t *, BOOL_T * );
void RecolorSegs( wIndex_t, trkSeg_p, wDrawColor );
BOOL_T ReadSegs( void );
BOOL_T WriteSegs( FILE * f, wIndex_t segCnt, trkSeg_p segs );
BOOL_T WriteSegsEnd(FILE * f, wIndex_t segCnt, trkSeg_p segs, BOOL_T writeEnd);


typedef union {
	struct {
		coOrd pos;				/* IN the point to get to */
		ANGLE_T angle;			/* IN  is the angle that the object starts at (-ve for forwards) */
		DIST_T dist;			/* OUT is how far it is along the track to get to pos*/
		BOOL_T backwards;		/* OUT which way are we going? */
		BOOL_T reverse_seg;		/* OUT the seg is backwards curve */
		BOOL_T negative;		/* OUT the curve is negative */
		int BezSegInx;			/* OUT for Bezier Seg - the segment we are on in Bezier */
		BOOL_T segs_backwards;  /* OUT for Bezier Seg - the direction of the overall Bezier */
	} traverse1;				// Find dist between pos and end of track that starts with angle set backwards
	struct {
		BOOL_T segDir;			/* IN Direction to go in this seg*/
		int BezSegInx;			/* IN for Bezier Seg which element to start with*/
		BOOL_T segs_backwards;  /* IN for Bezier Seg  which way to go down the array*/
		DIST_T dist;			/* IN/OUT In = distance to go, Out = distance left */
		coOrd pos;				/* OUT = point reached if dist = 0 */
		ANGLE_T angle;			/* OUT = angle at point */
	} traverse2;			//Return distance left (or 0) and angle and pos when going dist from segDir end
	struct {
		int first, last;		/* IN */
		ANGLE_T side;
		DIST_T roadbedWidth;
		wDrawWidth rbw;
		coOrd orig;
		ANGLE_T angle;
		wDrawColor color;
		drawCmd_p d;
	} drawRoadbedSide;
	struct {
		coOrd pos1;				/* IN pos to find */
		DIST_T dd;				/* OUT distance from nearest point in seg to input pos */
	} distance;
	struct {
		track_p trk;			/* OUT */
		EPINX_T ep[2];
	} newTrack;
	struct {
		DIST_T length;			/* OUT */
	} length;
	struct {
		coOrd pos;				/* IN */
		DIST_T length[2];		/* OUT */
		trkSeg_t newSeg[2];
	} split;
	struct {
		coOrd pos;				/* IN Pos to find nearest to  - OUT found pos on curve*/
		ANGLE_T angle;			/* OUT angle at pos - (-ve if backwards)*/
		BOOL_T negative_radius; /* OUT Radius <0? */
		BOOL_T backwards;		/* OUT Seg is backwards */
		DIST_T radius;			/* OUT radius at pos */
		coOrd center;			/* OUT center of curvature at pos (0 = straight)*/
		int  bezSegInx;			/* OUT if a bezier proc, the index of the sub segment */
	} getAngle;			// Get pos on seg nearest, angle at that (-ve for forwards)
} segProcData_t, *segProcData_p;
typedef enum {
	SEGPROC_TRAVERSE1,
	SEGPROC_TRAVERSE2,
	SEGPROC_DRAWROADBEDSIDE,
	SEGPROC_DISTANCE,
	SEGPROC_FLIP,
	SEGPROC_NEWTRACK,
	SEGPROC_LENGTH,
	SEGPROC_SPLIT,
	SEGPROC_GETANGLE
} segProc_e;

void SegProc( segProc_e, trkSeg_p, segProcData_p );
void DrawDimLine( drawCmd_p, coOrd, coOrd, char *, wFontSize_t, FLOAT_T,
                  wDrawWidth, wDrawColor, long );
void DrawSegs(
        drawCmd_p d,
        coOrd orig,
        ANGLE_T angle,
        trkSeg_p segPtr,
        wIndex_t segCnt,
        DIST_T trackGauge,
        wDrawColor color );
void DrawSegsDA(
        drawCmd_p d,
        track_p trk,
        coOrd orig,
        ANGLE_T angle,
        dynArr_t * da,
        DIST_T trackGauge,
        wDrawColor color,
        long options );
void DrawSegsO(
        drawCmd_p d,
        track_p trk,
        coOrd orig,
        ANGLE_T angle,
        trkSeg_p segPtr,
        wIndex_t segCnt,
        DIST_T trackGauge,
        wDrawColor color,
        long options );


void StraightSegProc( segProc_e, trkSeg_p, segProcData_p );
void CurveSegProc( segProc_e, trkSeg_p, segProcData_p );
void JointSegProc( segProc_e, trkSeg_p, segProcData_p );
void BezierSegProc( segProc_e, trkSeg_p, segProcData_p );   //Used in Cornu join
void CleanSegs( dynArr_t *);
void CopyPoly(trkSeg_p seg_p, wIndex_t segCnt);
wBool_t CompareSegs( trkSeg_p, int, trkSeg_p, int );
#endif