summaryrefslogtreecommitdiff
path: root/app/bin/tbezier.c
diff options
context:
space:
mode:
Diffstat (limited to 'app/bin/tbezier.c')
-rw-r--r--app/bin/tbezier.c2078
1 files changed, 1122 insertions, 956 deletions
diff --git a/app/bin/tbezier.c b/app/bin/tbezier.c
index fc949a2..c5cff99 100644
--- a/app/bin/tbezier.c
+++ b/app/bin/tbezier.c
@@ -14,7 +14,7 @@
*
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*****************************************************************************
* BEZIER TRACK (and LINE)
@@ -41,26 +41,21 @@
#include "ccurve.h"
#include "cstraigh.h"
#include "cjoin.h"
-#include "utility.h"
-#include "i18n.h"
#include "param.h"
-#include "math.h"
-#include "string.h"
#include "cundo.h"
#include "layout.h"
#include "fileio.h"
-#include "assert.h"
EXPORT TRKTYP_T T_BEZIER = -1;
EXPORT TRKTYP_T T_BZRLIN = -1;
-struct extraData {
- BezierData_t bezierData;
- };
-
static int log_bezier = 0;
static DIST_T GetLengthBezier( track_p );
+static DIST_T BezierMathDistance( coOrd * pos, coOrd p[4], int segments,
+ double * t_value);
+static void BezierSplit(coOrd input[4], coOrd left[4], coOrd right[4],
+ double t);
/****************************************
*
@@ -71,32 +66,36 @@ static DIST_T GetLengthBezier( track_p );
/*
* Run after any changes to the Bezier points
*/
-EXPORT void FixUpBezier(coOrd pos[4], struct extraData* xx, BOOL_T track) {
- xx->bezierData.a0 = NormalizeAngle(FindAngle(pos[1], pos[0]));
- xx->bezierData.a1 = NormalizeAngle(FindAngle(pos[2], pos[3]));
-
- ConvertToArcs(pos, &xx->bezierData.arcSegs, track, xx->bezierData.segsColor,
- xx->bezierData.segsWidth);
- xx->bezierData.minCurveRadius = BezierMinRadius(pos,
- xx->bezierData.arcSegs);
- xx->bezierData.length = BezierLength(pos, xx->bezierData.arcSegs);
+EXPORT void FixUpBezier(coOrd pos[4], struct extraDataBezier_t * xx,
+ BOOL_T track)
+{
+ xx->a0 = NormalizeAngle(FindAngle(pos[1], pos[0]));
+ xx->a1 = NormalizeAngle(FindAngle(pos[2], pos[3]));
+
+ ConvertToArcs(pos, &xx->arcSegs, track, xx->segsColor,
+ xx->segsLineWidth);
+ xx->minCurveRadius = BezierMinRadius(pos,
+ xx->arcSegs);
+ xx->length = BezierLength(pos, xx->arcSegs);
}
/*
* Run after any changes to the Bezier points for a Segment
*/
-EXPORT void FixUpBezierSeg(coOrd pos[4], trkSeg_p p, BOOL_T track) {
+EXPORT void FixUpBezierSeg(coOrd pos[4], trkSeg_p p, BOOL_T track)
+{
p->u.b.angle0 = NormalizeAngle(FindAngle(pos[1], pos[0]));
p->u.b.angle3 = NormalizeAngle(FindAngle(pos[2], pos[3]));
ConvertToArcs(pos, &p->bezSegs, track, p->color,
- p->width);
+ p->lineWidth);
p->u.b.minRadius = BezierMinRadius(pos,
- p->bezSegs);
+ p->bezSegs);
p->u.b.length = BezierLength(pos, p->bezSegs);
}
-EXPORT void FixUpBezierSegs(trkSeg_p p,int segCnt) {
- for (int i=0;i<segCnt;i++,p++) {
+EXPORT void FixUpBezierSegs(trkSeg_p p,int segCnt)
+{
+ for (int i=0; i<segCnt; i++,p++) {
if (p->type == SEG_BEZTRK || p->type == SEG_BEZLIN) {
FixUpBezierSeg(p->u.b.pos,p,p->type == SEG_BEZTRK);
}
@@ -104,118 +103,157 @@ EXPORT void FixUpBezierSegs(trkSeg_p p,int segCnt) {
}
+#if 0
static void GetBezierAngles( ANGLE_T *a0, ANGLE_T *a1, track_p trk )
{
- assert( trk != NULL );
-
- *a0 = NormalizeAngle( GetTrkEndAngle(trk,0) );
- *a1 = NormalizeAngle( GetTrkEndAngle(trk,1) );
-
- LOG( log_bezier, 4, ( "getBezierAngles: = %0.3f %0.3f\n", *a0, *a1 ) )
+ CHECK( trk != NULL );
+
+ *a0 = NormalizeAngle( GetTrkEndAngle(trk,0) );
+ *a1 = NormalizeAngle( GetTrkEndAngle(trk,1) );
+
+ LOG( log_bezier, 4, ( "getBezierAngles: = %0.3f %0.3f\n", *a0, *a1 ) )
}
+#endif
-static void ComputeBezierBoundingBox( track_p trk, struct extraData * xx )
+static void ComputeBezierBoundingBox( track_p trk,
+ struct extraDataBezier_t * xx )
{
- coOrd hi, lo;
- hi.x = lo.x = xx->bezierData.pos[0].x;
- hi.y = lo.y = xx->bezierData.pos[0].y;
-
- for (int i=1; i<=3;i++) {
- hi.x = hi.x < xx->bezierData.pos[i].x ? xx->bezierData.pos[i].x : hi.x;
- hi.y = hi.y < xx->bezierData.pos[i].y ? xx->bezierData.pos[i].y : hi.y;
- lo.x = lo.x > xx->bezierData.pos[i].x ? xx->bezierData.pos[i].x : lo.x;
- lo.y = lo.y > xx->bezierData.pos[i].y ? xx->bezierData.pos[i].y : lo.y;
- }
- SetBoundingBox( trk, hi, lo );
+ coOrd hi, lo;
+ LWIDTH_T lineWidth = xx->segsLineWidth;
+ LWIDTH_T lwidth = 0;
+
+ if (lineWidth < 0) {
+ lwidth = -lineWidth / mainD.scale;
+ } else {
+ lwidth = lineWidth;
+ }
+
+ hi.x = lo.x = xx->pos[0].x;
+ hi.y = lo.y = xx->pos[0].y;
+
+ for (int i=1; i<=3; i++) {
+ hi.x = hi.x < xx->pos[i].x ? xx->pos[i].x : hi.x;
+ hi.y = hi.y < xx->pos[i].y ? xx->pos[i].y : hi.y;
+ lo.x = lo.x > xx->pos[i].x ? xx->pos[i].x : lo.x;
+ lo.y = lo.y > xx->pos[i].y ? xx->pos[i].y : lo.y;
+ }
+ lo.x -= lwidth;
+ lo.y -= lwidth;
+ hi.x += lwidth;
+ hi.y += lwidth;
+
+ SetBoundingBox( trk, hi, lo );
}
+static DIST_T DistanceBezier( track_p t, coOrd * p );
DIST_T BezierDescriptionDistance(
- coOrd pos,
- track_p trk,
- coOrd * dpos,
- BOOL_T show_hidden,
- BOOL_T * hidden)
+ coOrd pos,
+ track_p trk,
+ coOrd * dpos,
+ BOOL_T show_hidden,
+ BOOL_T * hidden)
{
- struct extraData *xx = GetTrkExtraData(trk);
coOrd p1;
- if (hidden) *hidden = FALSE;
- if ( GetTrkType( trk ) != T_BEZIER || ((( GetTrkBits( trk ) & TB_HIDEDESC ) != 0 ) && !show_hidden))
- return 100000;
-
- coOrd offset = xx->bezierData.descriptionOff;
+ if (hidden) { *hidden = FALSE; }
+ if ( GetTrkType( trk ) != T_BEZIER
+ || ((( GetTrkBits( trk ) & TB_HIDEDESC ) != 0 ) && !show_hidden)) {
+ return DIST_INF;
+ }
+
+ struct extraDataBezier_t *xx = GET_EXTRA_DATA(trk, T_BEZIER, extraDataBezier_t);
+ if (( GetTrkBits( trk ) & TB_HIDEDESC ) != 0 ) { xx->descriptionOff = zero; }
- if (( GetTrkBits( trk ) & TB_HIDEDESC ) != 0 ) offset = zero;
+ coOrd end0, end0off, end1, end1off;
+ end0 = xx->pos[0];
+ end1 = xx->pos[3];
+ ANGLE_T a;
+ a = FindAngle(end0,end1);
+ Translate(&end0off,end0,a+90,xx->descriptionOff.y);
+ Translate(&end1off,end1,a+90,xx->descriptionOff.y);
- p1.x = xx->bezierData.pos[0].x + ((xx->bezierData.pos[3].x-xx->bezierData.pos[0].x)/2) + offset.x;
- p1.y = xx->bezierData.pos[0].y + ((xx->bezierData.pos[3].y-xx->bezierData.pos[0].y)/2) + offset.y;
- if (hidden) *hidden = (GetTrkBits( trk ) & TB_HIDEDESC);
+ p1.x = (end1off.x - end0off.x)*(xx->descriptionOff.x+0.5) + end0off.x;
+ p1.y = (end1off.y - end0off.y)*(xx->descriptionOff.x+0.5) + end0off.y;
+
+ if (hidden) { *hidden = (GetTrkBits( trk ) & TB_HIDEDESC); }
*dpos = p1;
+
+ coOrd tpos = pos;
+ if (DistanceBezier(trk,&tpos)<FindDistance( p1, pos )) {
+ return DistanceBezier(trk,&pos);
+ }
return FindDistance( p1, pos );
}
static void DrawBezierDescription(
- track_p trk,
- drawCmd_p d,
- wDrawColor color )
+ track_p trk,
+ drawCmd_p d,
+ wDrawColor color )
{
- struct extraData *xx = GetTrkExtraData(trk);
- wFont_p fp;
- coOrd pos;
+ struct extraDataBezier_t *xx = GET_EXTRA_DATA(trk, T_NOTRACK,
+ extraDataBezier_t);
+// wFont_p fp;
+ coOrd epos0,epos1;
- if (layoutLabels == 0)
+ if (layoutLabels == 0) {
return;
- if ((labelEnable&LABELENABLE_TRKDESC)==0)
+ }
+ if ((labelEnable&LABELENABLE_TRKDESC)==0) {
return;
- pos.x = xx->bezierData.pos[0].x + ((xx->bezierData.pos[3].x - xx->bezierData.pos[0].x)/2);
- pos.y = xx->bezierData.pos[0].y + ((xx->bezierData.pos[3].y - xx->bezierData.pos[0].y)/2);
- pos.x += xx->bezierData.descriptionOff.x;
- pos.y += xx->bezierData.descriptionOff.y;
- fp = wStandardFont( F_TIMES, FALSE, FALSE );
- sprintf( message, _("Bezier: len=%0.2f min_rad=%0.2f"),
- xx->bezierData.length, xx->bezierData.minCurveRadius>10000?0.0:xx->bezierData.minCurveRadius);
- DrawBoxedString( BOX_BOX, d, pos, message, fp, (wFontSize_t)descriptionFontSize, color, 0.0 );
+ }
+
+
+ epos0 = xx->pos[0];
+ epos1 = xx->pos[3];
+ ANGLE_T a = FindAngle(epos0,epos1);
+ Translate(&epos0,epos0,a+90,xx->descriptionOff.y);
+ Translate(&epos1,epos1,a+90,xx->descriptionOff.y);
+ /*fp = */wStandardFont( F_TIMES, FALSE, FALSE );
+ sprintf( message, _("Bez: L%s A%0.3f trk_len=%s min_rad=%s"),
+ FormatDistance(FindDistance(xx->pos[0],xx->pos[3])),
+ FindAngle(xx->pos[0],xx->pos[3]),
+ FormatDistance(xx->length),
+ FormatDistance(xx->minCurveRadius>10000?0.0:xx->minCurveRadius));
+ DrawLine(d,xx->pos[0],epos0,0,color);
+ DrawLine(d,xx->pos[3],epos1,0,color);
+ DrawDimLine( d, epos0, epos1, message, (wFontSize_t)descriptionFontSize,
+ xx->descriptionOff.x+0.5, 0, color, 0x00 );
+
+ if (GetTrkBits( trk ) & TB_DETAILDESC) {
+ coOrd details_pos;
+ details_pos.x = (epos1.x - epos0.x)*(xx->descriptionOff.x+0.5) + epos0.x;
+ details_pos.y = (epos1.y - epos0.y)*(xx->descriptionOff.x+0.5) + epos0.y -
+ (2*descriptionFontSize/mainD.dpi);
+ AddTrkDetails(d, trk, details_pos, xx->length, color);
+ }
+
}
STATUS_T BezierDescriptionMove(
- track_p trk,
- wAction_t action,
- coOrd pos )
+ track_p trk,
+ wAction_t action,
+ coOrd pos )
{
- struct extraData *xx = GetTrkExtraData(trk);
- static coOrd p0,p1;
- static BOOL_T editState = FALSE;
-
- if (GetTrkType(trk) != T_BEZIER) return C_TERMINATE;
- p0.x = xx->bezierData.pos[0].x + ((xx->bezierData.pos[3].x - xx->bezierData.pos[0].x)/2);
- p0.y = xx->bezierData.pos[0].y + ((xx->bezierData.pos[3].y - xx->bezierData.pos[0].y)/2);
- switch (action) {
- case C_DOWN:
- DrawBezierDescription( trk, &mainD, wDrawColorWhite );
- case C_MOVE:
- case C_UP:
- editState = TRUE;
- p1 = pos;
- xx->bezierData.descriptionOff.x = pos.x - p0.x;
- xx->bezierData.descriptionOff.y = pos.y - p0.y;
- if (action == C_UP) {
- editState = FALSE;
- wDrawColor color = GetTrkColor( trk, &mainD );
- DrawBezierDescription( trk, &mainD, color );
- }
- return action==C_UP?C_TERMINATE:C_CONTINUE;
- case C_REDRAW:
- if (editState) {
- DrawBezierDescription( trk, &tempD, wDrawColorBlue );
- DrawLine( &tempD, p1, p0, 0, wDrawColorBlue );
- }
- break;
+// static coOrd p0,p1;
+// static BOOL_T editState = FALSE;
+
+ if (GetTrkType(trk) != T_BEZIER) { return C_TERMINATE; }
+ struct extraDataBezier_t *xx = GET_EXTRA_DATA(trk, T_BEZIER, extraDataBezier_t);
+ ANGLE_T ap;
+ coOrd end0, end1;
+ end0 = xx->pos[0];
+ end1 = xx->pos[3];
+ ap = NormalizeAngle(FindAngle(end0,pos)-FindAngle(end0,end1));
+
+ xx->descriptionOff.y = FindDistance(end0,pos)*sin(D2R(ap));
+ xx->descriptionOff.x = -0.5 + FindDistance(end0,
+ pos)*cos(D2R(ap))/FindDistance(end0,end1);
+ if (xx->descriptionOff.x > 0.5) { xx->descriptionOff.x = 0.5; }
+ if (xx->descriptionOff.x < -0.5) { xx->descriptionOff.x = -0.5; }
-
- }
return C_CONTINUE;
}
@@ -226,166 +264,189 @@ STATUS_T BezierDescriptionMove(
*/
static struct {
- coOrd pos[4];
- FLOAT_T elev[2];
- FLOAT_T length;
- DIST_T minRadius;
- FLOAT_T grade;
- unsigned int layerNumber;
- ANGLE_T angle[2];
- DIST_T radius[2];
- coOrd center[2];
- dynArr_t segs;
- long width;
- wDrawColor color;
- long lineType;
- } bezData;
+ coOrd pos[4];
+ FLOAT_T elev[2];
+ FLOAT_T length;
+ DIST_T minRadius;
+ FLOAT_T grade;
+ unsigned int layerNumber;
+ ANGLE_T angle[2];
+ DIST_T radius[2];
+ coOrd center[2];
+ dynArr_t segs;
+ LWIDTH_T lineWidth;
+ wDrawColor color;
+ long lineType;
+} bezData;
typedef enum { P0, A0, R0, C0, Z0, CP1, CP2, P1, A1, R1, C1, Z1, RA, LN, GR, LT, WI, CO, LY} crvDesc_e;
static descData_t bezDesc[] = {
-/*P0*/ { DESC_POS, N_("End Pt 1: X,Y"), &bezData.pos[0] },
-/*A0*/ { DESC_ANGLE, N_("End Angle"), &bezData.angle[0] },
-/*R0*/ { DESC_DIM, N_("Radius"), &bezData.radius[0] },
-/*C0*/ { DESC_POS, N_("Center X,Y"), &bezData.center[0]},
-/*Z0*/ { DESC_DIM, N_("Z1"), &bezData.elev[0] },
-/*CP1*/ { DESC_POS, N_("Ctl Pt 1: X,Y"), &bezData.pos[1] },
-/*CP2*/ { DESC_POS, N_("Ctl Pt 2: X,Y"), &bezData.pos[2] },
-/*P1*/ { DESC_POS, N_("End Pt 2: X,Y"), &bezData.pos[3] },
-/*A1*/ { DESC_ANGLE, N_("End Angle"), &bezData.angle[1] },
-/*R1*/ { DESC_DIM, N_("Radius"), &bezData.radius[1] },
-/*C1*/ { DESC_POS, N_("Center X,Y"), &bezData.center[1]},
-/*Z1*/ { DESC_DIM, N_("Z2"), &bezData.elev[1] },
-/*RA*/ { DESC_DIM, N_("MinRadius"), &bezData.radius },
-/*LN*/ { DESC_DIM, N_("Length"), &bezData.length },
-/*GR*/ { DESC_FLOAT, N_("Grade"), &bezData.grade },
-/*LT*/ { DESC_LIST, N_("Line Type"), &bezData.lineType},
-/*WI*/ { DESC_LONG, N_("Line Width"), &bezData.width},
-/*CO*/ { DESC_COLOR, N_("Line Color"), &bezData.color},
-/*LY*/ { DESC_LAYER, N_("Layer"), &bezData.layerNumber },
- { DESC_NULL } };
-
-static void UpdateBezier( track_p trk, int inx, descData_p descUpd, BOOL_T final )
+ /*P0*/ { DESC_POS, N_("End Pt 1: X,Y"), &bezData.pos[0] },
+ /*A0*/ { DESC_ANGLE, N_("End Angle"), &bezData.angle[0] },
+ /*R0*/ { DESC_DIM, N_("Radius"), &bezData.radius[0] },
+ /*C0*/ { DESC_POS, N_("Center X,Y"), &bezData.center[0]},
+ /*Z0*/ { DESC_DIM, N_("Z1"), &bezData.elev[0] },
+ /*CP1*/ { DESC_POS, N_("Ctl Pt 1: X,Y"), &bezData.pos[1] },
+ /*CP2*/ { DESC_POS, N_("Ctl Pt 2: X,Y"), &bezData.pos[2] },
+ /*P1*/ { DESC_POS, N_("End Pt 2: X,Y"), &bezData.pos[3] },
+ /*A1*/ { DESC_ANGLE, N_("End Angle"), &bezData.angle[1] },
+ /*R1*/ { DESC_DIM, N_("Radius"), &bezData.radius[1] },
+ /*C1*/ { DESC_POS, N_("Center X,Y"), &bezData.center[1]},
+ /*Z1*/ { DESC_DIM, N_("Z2"), &bezData.elev[1] },
+ /*RA*/ { DESC_DIM, N_("MinRadius"), &bezData.radius },
+ /*LN*/ { DESC_DIM, N_("Length"), &bezData.length },
+ /*GR*/ { DESC_FLOAT, N_("Grade"), &bezData.grade },
+ /*LT*/ { DESC_LIST, N_("Line Type"), &bezData.lineType},
+ /*WI*/ { DESC_FLOAT, N_("Line Width"), &bezData.lineWidth},
+ /*CO*/ { DESC_COLOR, N_("Line Color"), &bezData.color},
+ /*LY*/ { DESC_LAYER, N_("Layer"), &bezData.layerNumber },
+ { DESC_NULL }
+};
+
+static void UpdateBezier( track_p trk, int inx, descData_p descUpd,
+ BOOL_T final )
{
- struct extraData *xx = GetTrkExtraData(trk);
+ struct extraDataBezier_t *xx = GET_EXTRA_DATA(trk, T_NOTRACK,
+ extraDataBezier_t);
BOOL_T updateEndPts;
EPINX_T ep;
ANGLE_T angle1, angle2;
+ BOOL_T is_Track = (GetTrkType(trk)==T_BEZIER);
- if ( inx == -1 )
+ if ( inx == -1 ) {
return;
+ }
updateEndPts = FALSE;
+ UndrawNewTrack( trk );
switch ( inx ) {
- case P0:
- if (GetTrkEndTrk(trk,0)) break;
- updateEndPts = TRUE;
- xx->bezierData.pos[0] = bezData.pos[0];
- bezDesc[P0].mode |= DESC_CHANGE;
- /* no break */
- case P1:
- if (GetTrkEndTrk(trk,0) && GetTrkEndTrk(trk,1)) break;
- updateEndPts = TRUE;
- xx->bezierData.pos[3]= bezData.pos[3];
- bezDesc[P1].mode |= DESC_CHANGE;
- break;
- case A0:
- case A1:
- break;
- case CP1:
- if (GetTrkEndTrk(trk,0)) {
- angle1 = NormalizeAngle(GetTrkEndAngle(trk,0));
- angle2 = NormalizeAngle(FindAngle(bezData.pos[1], xx->bezierData.pos[0])-angle1);
- if (angle2 > 90.0 && angle2 < 270.0)
- Translate( &bezData.pos[1], xx->bezierData.pos[0], angle1, -FindDistance( xx->bezierData.pos[0], bezData.pos[1] )*cos(D2R(angle2)));
- }
- xx->bezierData.pos[1] = bezData.pos[1];
- bezDesc[CP1].mode |= DESC_CHANGE;
- updateEndPts = TRUE;
- break;
- case CP2:
- if (GetTrkEndTrk(trk,1)) {
- angle1 = NormalizeAngle(GetTrkEndAngle(trk,1));
- angle2 = NormalizeAngle(FindAngle(bezData.pos[2], xx->bezierData.pos[3])-angle1);
- if (angle2 > 90.0 && angle2 < 270.0)
- Translate( &bezData.pos[2], xx->bezierData.pos[3], angle1, -FindDistance( xx->bezierData.pos[3], bezData.pos[0] )*cos(D2R(angle2)));
- }
- xx->bezierData.pos[2] = bezData.pos[2];
- bezDesc[CP2].mode |= DESC_CHANGE;
- updateEndPts = TRUE;
- break;
- case Z0:
+ case P0:
+ updateEndPts = TRUE;
+ xx->pos[0] = bezData.pos[0];
+ xx->a0 = bezData.angle[1] = FindAngle(xx->pos[1],xx->pos[0]);
+ bezDesc[A0].mode |= DESC_CHANGE;
+ bezDesc[P0].mode |= DESC_CHANGE;
+ /* no break */
+ case P1:
+ updateEndPts = TRUE;
+ xx->pos[3]= bezData.pos[3];
+ xx->a1 = bezData.angle[1] = FindAngle(xx->pos[2],xx->pos[3]);
+ bezDesc[A1].mode |= DESC_CHANGE;
+ bezDesc[P1].mode |= DESC_CHANGE;
+ break;
+ case CP1:
+ if (is_Track) {
+ if (GetTrkEndTrk(trk,0)) {
+ angle1 = NormalizeAngle(GetTrkEndAngle(trk,0));
+ angle2 = DifferenceBetweenAngles(FindAngle(bezData.pos[1], xx->pos[0]),angle1);
+ if (fabs(angle2)<90) {
+ Translate( &bezData.pos[1], xx->pos[0], angle1, -FindDistance( xx->pos[0],
+ bezData.pos[1] )*cos(D2R(angle2)));
+ } else { bezData.pos[1] = xx->pos[1]; }
+ }
+ }
+ xx->pos[1] = bezData.pos[1];
+ xx->a0 = bezData.angle[0] = FindAngle(xx->pos[1],xx->pos[0]);
+ bezDesc[A0].mode |= DESC_CHANGE;
+ bezDesc[CP1].mode |= DESC_CHANGE;
+ updateEndPts = TRUE;
+ break;
+ case CP2:
+ if (is_Track) {
+ if (GetTrkEndTrk(trk,1)) {
+ angle1 = NormalizeAngle(GetTrkEndAngle(trk,1));
+ angle2 = DifferenceBetweenAngles(FindAngle(bezData.pos[2], xx->pos[3]),angle1);
+ if (fabs(angle2)<90) {
+ Translate( &bezData.pos[2], xx->pos[3], angle1, -FindDistance( xx->pos[3],
+ bezData.pos[2] )*cos(D2R(angle2)));
+ } else { bezData.pos[2] = xx->pos[2]; }
+ }
+ }
+ xx->pos[2] = bezData.pos[2];
+ xx->a1 = bezData.angle[1] = FindAngle(xx->pos[2],xx->pos[3]);
+ bezDesc[A1].mode |= DESC_CHANGE;
+ bezDesc[CP2].mode |= DESC_CHANGE;
+ updateEndPts = TRUE;
+ break;
+ case Z0:
case Z1:
ep = (inx==Z0?0:1);
- UpdateTrkEndElev( trk, ep, GetTrkEndElevUnmaskedMode(trk,ep), bezData.elev[ep], NULL );
+ UpdateTrkEndElev( trk, ep, GetTrkEndElevUnmaskedMode(trk,ep), bezData.elev[ep],
+ NULL );
ComputeElev( trk, 1-ep, FALSE, &bezData.elev[1-ep], NULL, TRUE );
- if ( bezData.length > minLength )
+ if ( bezData.length > minLength ) {
bezData.grade = fabs( (bezData.elev[0]-bezData.elev[1])/bezData.length )*100.0;
- else
+ } else {
bezData.grade = 0.0;
+ }
bezDesc[GR].mode |= DESC_CHANGE;
bezDesc[inx==Z0?Z1:Z0].mode |= DESC_CHANGE;
- return;
+ return;
case LY:
SetTrkLayer( trk, bezData.layerNumber);
break;
case WI:
- xx->bezierData.segsWidth = bezData.width/mainD.dpi;
+ xx->segsLineWidth = bezData.lineWidth;
break;
case CO:
- xx->bezierData.segsColor = bezData.color;
+ xx->segsColor = bezData.color;
break;
case LT:
- xx->bezierData.lineType = bezData.lineType;
+ xx->lineType = bezData.lineType;
break;
default:
- AbortProg( "updateBezier: Bad inx %d", inx );
+ CHECKMSG( FALSE, ( "updateBezier: Bad inx %d", inx ) );
}
- ConvertToArcs(xx->bezierData.pos, &xx->bezierData.arcSegs, IsTrack(trk)?TRUE:FALSE, xx->bezierData.segsColor, xx->bezierData.segsWidth);
+ ConvertToArcs(xx->pos, &xx->arcSegs, IsTrack(trk)?TRUE:FALSE, xx->segsColor,
+ xx->segsLineWidth);
trackParams_t params;
- for (int i=0;i<2;i++) {
- GetTrackParams(0,trk,xx->bezierData.pos[i],&params);
- bezData.radius[i] = params.arcR;
- bezData.center[i] = params.arcP;
- }
- if (updateEndPts) {
- if ( GetTrkEndTrk(trk,0) == NULL ) {
- SetTrkEndPoint( trk, 0, bezData.pos[0], NormalizeAngle( FindAngle(bezData.pos[1], bezData.pos[0]) ) );
- bezData.angle[0] = GetTrkEndAngle(trk,0);
- bezDesc[A0].mode |= DESC_CHANGE;
- GetTrackParams(PARAMS_CORNU,trk,xx->bezierData.pos[0],&params);
- bezData.radius[0] = params.arcR;
- bezData.center[0] = params.arcP;
- }
- if ( GetTrkEndTrk(trk,1) == NULL ) {
- SetTrkEndPoint( trk, 1, bezData.pos[3], NormalizeAngle( FindAngle(bezData.pos[2], bezData.pos[3]) ) );
- bezData.angle[1] = GetTrkEndAngle(trk,1);
- bezDesc[A1].mode |= DESC_CHANGE;
- GetTrackParams(PARAMS_CORNU,trk,xx->bezierData.pos[1],&params);
- bezData.radius[1] = params.arcR;
- bezData.center[1] = params.arcP;
- }
+ for (int i=0; i<2; i++) {
+ GetTrackParams(0,trk,xx->pos[i],&params);
+ bezData.radius[i] = params.arcR;
+ bezData.center[i] = params.arcP;
}
-
- FixUpBezier(xx->bezierData.pos, xx, IsTrack(trk));
+ if (updateEndPts && is_Track) {
+ if ( GetTrkEndTrk(trk,0) == NULL ) {
+ SetTrkEndPoint( trk, 0, bezData.pos[0],
+ NormalizeAngle( FindAngle(bezData.pos[1], bezData.pos[0]) ) );
+ bezData.angle[0] = GetTrkEndAngle(trk,0);
+ bezDesc[A0].mode |= DESC_CHANGE;
+ GetTrackParams(PARAMS_CORNU,trk,xx->pos[0],&params);
+ bezData.radius[0] = params.arcR;
+ bezData.center[0] = params.arcP;
+ }
+ if ( GetTrkEndTrk(trk,1) == NULL ) {
+ SetTrkEndPoint( trk, 1, bezData.pos[3],
+ NormalizeAngle( FindAngle(bezData.pos[2], bezData.pos[3]) ) );
+ bezData.angle[1] = GetTrkEndAngle(trk,1);
+ bezDesc[A1].mode |= DESC_CHANGE;
+ GetTrackParams(PARAMS_CORNU,trk,xx->pos[1],&params);
+ bezData.radius[1] = params.arcR;
+ bezData.center[1] = params.arcP;
+ }
+ }
+ FixUpBezier(xx->pos, xx, IsTrack(trk));
ComputeBezierBoundingBox(trk, xx);
DrawNewTrack( trk );
}
static void DescribeBezier( track_p trk, char * str, CSIZE_T len )
{
- struct extraData *xx = GetTrkExtraData(trk);
+ struct extraDataBezier_t *xx = GET_EXTRA_DATA(trk, T_NOTRACK,
+ extraDataBezier_t);
DIST_T d;
- int fix0, fix1 = 0;
-
- d = xx->bezierData.length;
- sprintf( str, _("Bezier %s(%d): Layer=%u MinRadius=%s Length=%s EP=[%0.3f,%0.3f] [%0.3f,%0.3f] CP1=[%0.3f,%0.3f] CP2=[%0.3f, %0.3f]"),
- GetTrkType(trk)==T_BEZIER?"Track":"Line",
- GetTrkIndex(trk),
- GetTrkLayer(trk)+1,
- FormatDistance(xx->bezierData.minCurveRadius),
- FormatDistance(d),
- PutDim(xx->bezierData.pos[0].x),PutDim(xx->bezierData.pos[0].y),
- PutDim(xx->bezierData.pos[3].x),PutDim(xx->bezierData.pos[3].y),
- PutDim(xx->bezierData.pos[1].x),PutDim(xx->bezierData.pos[1].y),
- PutDim(xx->bezierData.pos[2].x),PutDim(xx->bezierData.pos[2].y));
+ int fix0 = 0, fix1 = 0;
+
+ d = xx->length;
+ sprintf( str,
+ _("Bezier %s(%d): Layer=%u MinRadius=%s Length=%s EP=[%0.3f,%0.3f] [%0.3f,%0.3f] CP1=[%0.3f,%0.3f] CP2=[%0.3f, %0.3f]"),
+ GetTrkType(trk)==T_BEZIER?"Track":"Line",
+ GetTrkIndex(trk),
+ GetTrkLayer(trk)+1,
+ FormatDistance(xx->minCurveRadius),
+ FormatDistance(d),
+ PutDim(xx->pos[0].x),PutDim(xx->pos[0].y),
+ PutDim(xx->pos[3].x),PutDim(xx->pos[3].y),
+ PutDim(xx->pos[1].x),PutDim(xx->pos[1].y),
+ PutDim(xx->pos[2].x),PutDim(xx->pos[2].y));
if (GetTrkType(trk) == T_BEZIER) {
fix0 = GetTrkEndTrk(trk,0)!=NULL;
@@ -393,48 +454,48 @@ static void DescribeBezier( track_p trk, char * str, CSIZE_T len )
}
bezData.length = GetLengthBezier(trk);
- bezData.minRadius = xx->bezierData.minCurveRadius;
- if (bezData.minRadius >= 100000.00) bezData.minRadius = 0;
- bezData.layerNumber = GetTrkLayer(trk);
- bezData.pos[0] = xx->bezierData.pos[0];
- bezData.pos[1] = xx->bezierData.pos[1];
- bezData.pos[2] = xx->bezierData.pos[2];
- bezData.pos[3] = xx->bezierData.pos[3];
- bezData.angle[0] = xx->bezierData.a0;
- bezData.angle[1] = xx->bezierData.a1;
- trackParams_t params;
- GetTrackParams(PARAMS_CORNU,trk,xx->bezierData.pos[0],&params);
- bezData.radius[0] = params.arcR;
- bezData.center[0] = params.arcP;
- GetTrackParams(PARAMS_CORNU,trk,xx->bezierData.pos[3],&params);
- bezData.radius[1] = params.arcR;
- bezData.center[1] = params.arcP;
-
- if (GetTrkType(trk) == T_BEZIER) {
+ bezData.minRadius = xx->minCurveRadius;
+ if (bezData.minRadius >= DIST_INF) { bezData.minRadius = 0; }
+ bezData.layerNumber = GetTrkLayer(trk);
+ bezData.pos[0] = xx->pos[0];
+ bezData.pos[1] = xx->pos[1];
+ bezData.pos[2] = xx->pos[2];
+ bezData.pos[3] = xx->pos[3];
+ bezData.angle[0] = xx->a0;
+ bezData.angle[1] = xx->a1;
+ trackParams_t params;
+ GetTrackParams(PARAMS_CORNU,trk,xx->pos[0],&params);
+ bezData.radius[0] = params.arcR;
+ bezData.center[0] = params.arcP;
+ GetTrackParams(PARAMS_CORNU,trk,xx->pos[3],&params);
+ bezData.radius[1] = params.arcR;
+ bezData.center[1] = params.arcP;
+
+ if (GetTrkType(trk) == T_BEZIER) {
ComputeElev( trk, 0, FALSE, &bezData.elev[0], NULL, FALSE );
ComputeElev( trk, 1, FALSE, &bezData.elev[1], NULL, FALSE );
-
- if ( bezData.length > minLength )
+
+ if ( bezData.length > minLength ) {
bezData.grade = fabs( (bezData.elev[0]-bezData.elev[1])/bezData.length )*100.0;
- else
+ } else {
bezData.grade = 0.0;
- }
+ }
+ }
bezDesc[P0].mode = fix0?DESC_RO:0;
bezDesc[P1].mode = fix1?DESC_RO:0;
bezDesc[LN].mode = DESC_RO;
- bezDesc[CP1].mode = 0;
- bezDesc[CP2].mode = 0;
- if (GetTrkType(trk) == T_BEZIER) {
- bezDesc[Z0].mode = EndPtIsDefinedElev(trk,0)?0:DESC_RO;
+ bezDesc[CP1].mode = 0;
+ bezDesc[CP2].mode = 0;
+ if (GetTrkType(trk) == T_BEZIER) {
+ bezDesc[Z0].mode = EndPtIsDefinedElev(trk,0)?0:DESC_RO;
bezDesc[Z1].mode = EndPtIsDefinedElev(trk,1)?0:DESC_RO;
bezDesc[LT].mode = DESC_IGNORE;
- }
- else {
- bezDesc[Z0].mode = bezDesc[Z1].mode = DESC_IGNORE;
- bezDesc[LT].mode = 0;
- bezData.lineType = xx->bezierData.lineType;
- }
+ } else {
+ bezDesc[Z0].mode = bezDesc[Z1].mode = DESC_IGNORE;
+ bezDesc[LT].mode = 0;
+ bezData.lineType = xx->lineType;
+ }
bezDesc[A0].mode = DESC_RO;
bezDesc[A1].mode = DESC_RO;
bezDesc[C0].mode = DESC_RO;
@@ -442,56 +503,58 @@ static void DescribeBezier( track_p trk, char * str, CSIZE_T len )
bezDesc[R0].mode = DESC_RO;
bezDesc[R1].mode = DESC_RO;
bezDesc[GR].mode = DESC_RO;
- bezDesc[RA].mode = DESC_RO;
+ bezDesc[RA].mode = DESC_RO;
bezDesc[LY].mode = DESC_NOREDRAW;
- bezData.width = (long)floor(xx->bezierData.segsWidth*mainD.dpi+0.5);
+ bezData.lineWidth = xx->segsLineWidth;
bezDesc[WI].mode = GetTrkType(trk) == T_BEZIER?DESC_IGNORE:0;
- bezData.color = xx->bezierData.segsColor;
+ bezData.color = xx->segsColor;
bezDesc[CO].mode = GetTrkType(trk) == T_BEZIER?DESC_IGNORE:0;
-
- if (GetTrkType(trk) == T_BEZIER)
+
+ if (GetTrkType(trk) == T_BEZIER) {
DoDescribe( _("Bezier Track"), trk, bezDesc, UpdateBezier );
- else {
+ } else {
DoDescribe( _("Bezier Line"), trk, bezDesc, UpdateBezier );
if (bezDesc[LT].control0!=NULL) {
wListClear( (wList_p)bezDesc[LT].control0 );
- wListAddValue( (wList_p)bezDesc[LT].control0, _("Solid"), NULL, (void*)0 );
- wListAddValue( (wList_p)bezDesc[LT].control0, _("Dash"), NULL, (void*)1 );
- wListAddValue( (wList_p)bezDesc[LT].control0, _("Dot"), NULL, (void*)2 );
- wListAddValue( (wList_p)bezDesc[LT].control0, _("DashDot"), NULL, (void*)3 );
- wListAddValue( (wList_p)bezDesc[LT].control0, _("DashDotDot"), NULL, (void*)4 );
- wListAddValue( (wList_p)bezDesc[LT].control0, _("CenterDot"), NULL, (void*)5);
- wListAddValue( (wList_p)bezDesc[LT].control0, _("PhantomDot"), NULL, (void*)6 );
+ wListAddValue( (wList_p)bezDesc[LT].control0, _("Solid"), NULL, I2VP(0));
+ wListAddValue( (wList_p)bezDesc[LT].control0, _("Dash"), NULL, I2VP(1));
+ wListAddValue( (wList_p)bezDesc[LT].control0, _("Dot"), NULL, I2VP(2));
+ wListAddValue( (wList_p)bezDesc[LT].control0, _("DashDot"), NULL, I2VP(3));
+ wListAddValue( (wList_p)bezDesc[LT].control0, _("DashDotDot"), NULL, I2VP(4));
+ wListAddValue( (wList_p)bezDesc[LT].control0, _("CenterDot"), NULL, I2VP(5));
+ wListAddValue( (wList_p)bezDesc[LT].control0, _("PhantomDot"), NULL, I2VP(6));
wListSetIndex( (wList_p)bezDesc[LT].control0, bezData.lineType );
}
}
}
-EXPORT void SetBezierLineType( track_p trk, int width ) {
+EXPORT void SetBezierLineType( track_p trk, int width )
+{
if (GetTrkType(trk) == T_BZRLIN) {
- struct extraData * xx = GetTrkExtraData(trk);
+ struct extraDataBezier_t * xx = GET_EXTRA_DATA(trk, T_BZRLIN,
+ extraDataBezier_t);
switch(width) {
case 0:
- xx->bezierData.lineType = DRAWLINESOLID;
+ xx->lineType = DRAWLINESOLID;
break;
case 1:
- xx->bezierData.lineType = DRAWLINEDASH;
+ xx->lineType = DRAWLINEDASH;
break;
case 2:
- xx->bezierData.lineType = DRAWLINEDOT;
+ xx->lineType = DRAWLINEDOT;
break;
case 3:
- xx->bezierData.lineType = DRAWLINEDASHDOT;
+ xx->lineType = DRAWLINEDASHDOT;
break;
case 4:
- xx->bezierData.lineType = DRAWLINEDASHDOTDOT;
+ xx->lineType = DRAWLINEDASHDOTDOT;
break;
case 5:
- xx->bezierData.lineType = DRAWLINECENTER;
+ xx->lineType = DRAWLINECENTER;
break;
case 6:
- xx->bezierData.lineType = DRAWLINEPHANTOM;
+ xx->lineType = DRAWLINEPHANTOM;
break;
}
}
@@ -499,104 +562,103 @@ EXPORT void SetBezierLineType( track_p trk, int width ) {
static DIST_T DistanceBezier( track_p t, coOrd * p )
{
- struct extraData *xx = GetTrkExtraData(t);
+ struct extraDataBezier_t *xx = GET_EXTRA_DATA(t, T_NOTRACK, extraDataBezier_t);
- DIST_T d = 100000.0;
- coOrd p2 = xx->bezierData.pos[0]; //Set initial point
+ DIST_T d = DIST_INF;
+ coOrd p2 = xx->pos[0]; //Set initial point
segProcData_t segProcData;
- for (int i = 0;i<xx->bezierData.arcSegs.cnt;i++) {
+ for (int i = 0; i<xx->arcSegs.cnt; i++) {
segProcData.distance.pos1 = * p;
- SegProc(SEGPROC_DISTANCE,&DYNARR_N(trkSeg_t,xx->bezierData.arcSegs,i),&segProcData);
+ SegProc(SEGPROC_DISTANCE,&DYNARR_N(trkSeg_t,xx->arcSegs,i),&segProcData);
if (segProcData.distance.dd<d) {
d = segProcData.distance.dd;
p2 = segProcData.distance.pos1;
}
}
- * p = p2;
+ * p = p2;
return d;
}
static void DrawBezier( track_p t, drawCmd_p d, wDrawColor color )
{
- struct extraData *xx = GetTrkExtraData(t);
+ struct extraDataBezier_t *xx = GET_EXTRA_DATA(t, T_NOTRACK, extraDataBezier_t);
long widthOptions = DTS_LEFT|DTS_RIGHT;
if (GetTrkType(t) == T_BZRLIN) {
unsigned long NotSolid = ~(DC_NOTSOLIDLINE);
d->options &= NotSolid;
- if (xx->bezierData.lineType == DRAWLINESOLID) {}
- else if (xx->bezierData.lineType == DRAWLINEDASH) d->options |= DC_DASH;
- else if (xx->bezierData.lineType == DRAWLINEDOT) d->options |= DC_DOT;
- else if (xx->bezierData.lineType == DRAWLINEDASHDOT) d->options |= DC_DASHDOT;
- else if (xx->bezierData.lineType == DRAWLINEDASHDOTDOT) d->options |= DC_DASHDOTDOT;
- else if (xx->bezierData.lineType == DRAWLINECENTER) d->options |= DC_CENTER;
- else if (xx->bezierData.lineType == DRAWLINEPHANTOM) d->options |= DC_PHANTOM;
- DrawSegsO(d,t,zero,0.0,xx->bezierData.arcSegs.ptr,xx->bezierData.arcSegs.cnt, 0.0, color, 0);
+ if (xx->lineType == DRAWLINESOLID) {}
+ else if (xx->lineType == DRAWLINEDASH) { d->options |= DC_DASH; }
+ else if (xx->lineType == DRAWLINEDOT) { d->options |= DC_DOT; }
+ else if (xx->lineType == DRAWLINEDASHDOT) { d->options |= DC_DASHDOT; }
+ else if (xx->lineType == DRAWLINEDASHDOTDOT) { d->options |= DC_DASHDOTDOT; }
+ else if (xx->lineType == DRAWLINECENTER) { d->options |= DC_CENTER; }
+ else if (xx->lineType == DRAWLINEPHANTOM) { d->options |= DC_PHANTOM; }
+ DrawSegsDA(d,t,zero,0.0,&xx->arcSegs, 0.0, color, 0);
d->options &= NotSolid;
return;
}
if ( ((d->options&DC_SIMPLE)==0) &&
- (labelWhen == 2 || (labelWhen == 1 && (d->options&DC_PRINT))) &&
- labelScale >= d->scale &&
- ( GetTrkBits( t ) & TB_HIDEDESC ) == 0 ) {
+ (labelWhen == 2 || (labelWhen == 1 && (d->options&DC_PRINT))) &&
+ labelScale >= d->scale &&
+ ( GetTrkBits( t ) & TB_HIDEDESC ) == 0 ) {
DrawBezierDescription( t, d, color );
}
- DIST_T scale2rail = (d->options&DC_PRINT)?(twoRailScale*2+1):twoRailScale;
- DrawSegsO(d,t,zero,0.0,xx->bezierData.arcSegs.ptr,xx->bezierData.arcSegs.cnt, GetTrkGauge(t), color, widthOptions);
+ DrawSegsDA(d,t,zero,0.0,&xx->arcSegs, GetTrkGauge(t), color, widthOptions);
DrawEndPt( d, t, 0, color );
DrawEndPt( d, t, 1, color );
}
static void DeleteBezier( track_p t )
{
- struct extraData *xx = GetTrkExtraData(t);
+ struct extraDataBezier_t *xx = GET_EXTRA_DATA(t, T_NOTRACK, extraDataBezier_t);
- for (int i=0;i<xx->bezierData.arcSegs.cnt;i++) {
- trkSeg_t s = DYNARR_N(trkSeg_t,xx->bezierData.arcSegs,i);
+ // NOTE - should use trkSeg_p so we free seg in orig trk, instead of copy
+ for (int i=0; i<xx->arcSegs.cnt; i++) {
+ trkSeg_t s = DYNARR_N(trkSeg_t,xx->arcSegs,i);
if (s.type == SEG_BEZTRK || s.type == SEG_BEZLIN) {
- if (s.bezSegs.ptr) MyFree(s.bezSegs.ptr);
- s.bezSegs.max = 0;
- s.bezSegs.cnt = 0;
- s.bezSegs.ptr = NULL;
+ DYNARR_FREE( trkSeg_t, s.bezSegs );
}
}
- if (xx->bezierData.arcSegs.ptr && !xx->bezierData.arcSegs.max)
- MyFree(xx->bezierData.arcSegs.ptr);
- xx->bezierData.arcSegs.max = 0;
- xx->bezierData.arcSegs.cnt = 0;
- xx->bezierData.arcSegs.ptr = NULL;
+ // NOTE orig tests !xx->arcSegs.max ???
+ DYNARR_FREE( trkSeg_t, xx->arcSegs );
}
static BOOL_T WriteBezier( track_p t, FILE * f )
{
- struct extraData *xx = GetTrkExtraData(t);
+ struct extraDataBezier_t *xx = GET_EXTRA_DATA(t, T_NOTRACK, extraDataBezier_t);
+ int bits;
long options;
BOOL_T rc = TRUE;
BOOL_T track =(GetTrkType(t)==T_BEZIER);
options = GetTrkWidth(t) & 0x0F;
- if ( ( GetTrkBits(t) & TB_HIDEDESC ) == 0 ) options |= 0x80;
- rc &= fprintf(f, "%s %d %u %ld %ld %0.6f %s %d %0.6f %0.6f %0.6f %0.6f %0.6f %0.6f %0.6f %0.6f %d %0.6f %0.6f \n",
- track?"BEZIER":"BZRLIN",GetTrkIndex(t), GetTrkLayer(t), (long)options, wDrawGetRGB(xx->bezierData.segsColor), xx->bezierData.segsWidth,
- GetTrkScaleName(t), GetTrkVisible(t)|(GetTrkNoTies(t)?1<<2:0)|(GetTrkBridge(t)?1<<3:0),
- xx->bezierData.pos[0].x, xx->bezierData.pos[0].y,
- xx->bezierData.pos[1].x, xx->bezierData.pos[1].y,
- xx->bezierData.pos[2].x, xx->bezierData.pos[2].y,
- xx->bezierData.pos[3].x, xx->bezierData.pos[3].y,
- xx->bezierData.lineType,
- xx->bezierData.descriptionOff.x, xx->bezierData.descriptionOff.y )>0;
+ if ( ( GetTrkBits(t) & TB_HIDEDESC ) == 0 ) { options |= 0x80; }
+ bits = GetTrkVisible(t)|(GetTrkNoTies(t)?1<<2:0)|(GetTrkBridge(t)?1<<3:0)|
+ (GetTrkRoadbed(t)?1<<4:0);
+ rc &= fprintf(f,
+ "%s %d %u %ld %ld %0.6f %s %d %0.6f %0.6f %0.6f %0.6f %0.6f %0.6f %0.6f %0.6f %d %0.6f %0.6f \n",
+ track?"BEZIER":"BZRLIN",GetTrkIndex(t), GetTrkLayer(t), (long)options,
+ wDrawGetRGB(xx->segsColor), xx->segsLineWidth,
+ GetTrkScaleName(t), bits,
+ xx->pos[0].x, xx->pos[0].y,
+ xx->pos[1].x, xx->pos[1].y,
+ xx->pos[2].x, xx->pos[2].y,
+ xx->pos[3].x, xx->pos[3].y,
+ xx->lineType,
+ xx->descriptionOff.x, xx->descriptionOff.y )>0;
if (track) {
- rc &= WriteEndPt( f, t, 0 );
- rc &= WriteEndPt( f, t, 1 );
- }
- rc &= WriteSegs( f, xx->bezierData.arcSegs.cnt, xx->bezierData.arcSegs.ptr );
+ rc &= WriteEndPt( f, t, 0 );
+ rc &= WriteEndPt( f, t, 1 );
+ }
+ rc &= WriteSegs( f, xx->arcSegs.cnt, &DYNARR_N(trkSeg_t,xx->arcSegs,0) );
return rc;
}
static BOOL_T ReadBezier( char * line )
{
- struct extraData *xx;
+ struct extraDataBezier_t *xx;
track_p t;
wIndex_t index;
BOOL_T visible;
@@ -605,141 +667,154 @@ static BOOL_T ReadBezier( char * line )
wIndex_t layer;
long options;
int lt;
- char * cp = NULL;
+// char * cp = NULL;
unsigned long rgb;
- DIST_T width;
+ LWIDTH_T lineWidth;
TRKTYP_T trkTyp = strncmp(line,"BEZIER",6)==0?T_BEZIER:T_BZRLIN;
if (!GetArgs( line+6, "dLluwsdppppdp",
- &index, &layer, &options, &rgb, &width, scale, &visible, &p0, &c1, &c2, &p1, &lt, &dp ) ) {
+ &index, &layer, &options, &rgb, &lineWidth, scale, &visible, &p0, &c1, &c2, &p1,
+ &lt, &dp ) ) {
return FALSE;
}
- if ( !ReadSegs() )
+ if ( !ReadSegs() ) {
return FALSE;
+ }
t = NewTrack( index, trkTyp, 0, sizeof *xx );
- xx = GetTrkExtraData(t);
+ xx = GET_EXTRA_DATA(t, trkTyp, extraDataBezier_t);
SetTrkVisible(t, visible&2);
SetTrkNoTies(t,visible&4);
SetTrkBridge(t,visible&8);
+ SetTrkRoadbed(t,visible&16);
SetTrkScale(t, LookupScale(scale));
SetTrkLayer(t, layer );
SetTrkWidth(t, (int)(options&0x0F));
- if ( ( options & 0x80 ) == 0 ) SetTrkBits(t,TB_HIDEDESC);
- xx->bezierData.pos[0] = p0;
- xx->bezierData.pos[1] = c1;
- xx->bezierData.pos[2] = c2;
- xx->bezierData.pos[3] = p1;
- xx->bezierData.lineType = lt;
- xx->bezierData.descriptionOff = dp;
- xx->bezierData.segsWidth = width;
- xx->bezierData.segsColor = wDrawFindColor( rgb );
- FixUpBezier(xx->bezierData.pos,xx,GetTrkType(t) == T_BEZIER);
- ComputeBezierBoundingBox(t,xx);
- if (GetTrkType(t) == T_BEZIER) {
+ if ( paramVersion < VERSION_DESCRIPTION2 || ( options & 0x80 ) == 0 ) { SetTrkBits(t,TB_HIDEDESC); }
+ xx->pos[0] = p0;
+ xx->pos[1] = c1;
+ xx->pos[2] = c2;
+ xx->pos[3] = p1;
+ xx->lineType = lt;
+ xx->descriptionOff = dp;
+ xx->segsLineWidth = lineWidth;
+ xx->segsColor = wDrawFindColor( rgb );
+ FixUpBezier(xx->pos,xx,GetTrkType(t) == T_BEZIER);
+ ComputeBezierBoundingBox(t,xx);
+ if (GetTrkType(t) == T_BEZIER) {
SetEndPts(t,2);
}
return TRUE;
}
-static void MoveBezier( track_p trk, coOrd orig )
+EXPORT void MoveBezier( track_p trk, coOrd orig )
{
- struct extraData *xx = GetTrkExtraData(trk);
- for (int i=0;i<4;i++) {
- xx->bezierData.pos[i].x += orig.x;
- xx->bezierData.pos[i].y += orig.y;
- }
- FixUpBezier(xx->bezierData.pos,xx,IsTrack(trk));
- ComputeBezierBoundingBox(trk,xx);
+ struct extraDataBezier_t *xx = GET_EXTRA_DATA(trk, T_NOTRACK,
+ extraDataBezier_t);
+ for (int i=0; i<4; i++) {
+ xx->pos[i].x += orig.x;
+ xx->pos[i].y += orig.y;
+ }
+ FixUpBezier(xx->pos,xx,IsTrack(trk));
+ ComputeBezierBoundingBox(trk,xx);
}
-static void RotateBezier( track_p trk, coOrd orig, ANGLE_T angle )
+EXPORT void RotateBezier( track_p trk, coOrd orig, ANGLE_T angle )
{
- struct extraData *xx = GetTrkExtraData(trk);
- for (int i=0;i<5;i++) {
- Rotate( &xx->bezierData.pos[i], orig, angle );
- }
- FixUpBezier(xx->bezierData.pos,xx,IsTrack(trk));
- ComputeBezierBoundingBox(trk,xx);
+ struct extraDataBezier_t *xx = GET_EXTRA_DATA(trk, T_NOTRACK,
+ extraDataBezier_t);
+ for (int i=0; i<COUNT(xx->pos); i++) {
+ Rotate( &xx->pos[i], orig, angle );
+ }
+ FixUpBezier(xx->pos,xx,IsTrack(trk));
+ ComputeBezierBoundingBox(trk,xx);
}
static void RescaleBezier( track_p trk, FLOAT_T ratio )
{
- struct extraData *xx = GetTrkExtraData(trk);
- xx->bezierData.pos[0].x *= ratio;
- xx->bezierData.pos[0].y *= ratio;
- xx->bezierData.pos[1].x *= ratio;
- xx->bezierData.pos[1].y *= ratio;
- xx->bezierData.pos[2].x *= ratio;
- xx->bezierData.pos[2].y *= ratio;
- xx->bezierData.pos[3].x *= ratio;
- xx->bezierData.pos[3].y *= ratio;
- FixUpBezier(xx->bezierData.pos,xx,IsTrack(trk));
- ComputeBezierBoundingBox(trk,xx);
+ struct extraDataBezier_t *xx = GET_EXTRA_DATA(trk, T_NOTRACK,
+ extraDataBezier_t);
+ xx->pos[0].x *= ratio;
+ xx->pos[0].y *= ratio;
+ xx->pos[1].x *= ratio;
+ xx->pos[1].y *= ratio;
+ xx->pos[2].x *= ratio;
+ xx->pos[2].y *= ratio;
+ xx->pos[3].x *= ratio;
+ xx->pos[3].y *= ratio;
+ FixUpBezier(xx->pos,xx,IsTrack(trk));
+ ComputeBezierBoundingBox(trk,xx);
}
-EXPORT void AdjustBezierEndPt( track_p trk, EPINX_T inx, coOrd pos ) {
- struct extraData *xx = GetTrkExtraData(trk);
- UndoModify(trk);
- if (inx ==0 ) {
- xx->bezierData.pos[1].x += -xx->bezierData.pos[0].x+pos.x;
- xx->bezierData.pos[1].y += -xx->bezierData.pos[0].y+pos.y;
- xx->bezierData.pos[0] = pos;
- }
- else {
- xx->bezierData.pos[2].x += -xx->bezierData.pos[3].x+pos.x;
- xx->bezierData.pos[2].y += -xx->bezierData.pos[3].y+pos.y;
- xx->bezierData.pos[3] = pos;
- }
- FixUpBezier(xx->bezierData.pos, xx, IsTrack(trk));
- ComputeBezierBoundingBox(trk,xx);
- SetTrkEndPoint( trk, inx, pos, inx==0?xx->bezierData.a0:xx->bezierData.a1);
+EXPORT void AdjustBezierEndPt( track_p trk, EPINX_T inx, coOrd pos )
+{
+ struct extraDataBezier_t *xx = GET_EXTRA_DATA(trk, T_NOTRACK,
+ extraDataBezier_t);
+ UndoModify(trk);
+ if (inx ==0 ) {
+ xx->pos[1].x += -xx->pos[0].x+pos.x;
+ xx->pos[1].y += -xx->pos[0].y+pos.y;
+ xx->pos[0] = pos;
+ } else {
+ xx->pos[2].x += -xx->pos[3].x+pos.x;
+ xx->pos[2].y += -xx->pos[3].y+pos.y;
+ xx->pos[3] = pos;
+ }
+ FixUpBezier(xx->pos, xx, IsTrack(trk));
+ ComputeBezierBoundingBox(trk,xx);
+ SetTrkEndPoint( trk, inx, pos, inx==0?xx->a0:xx->a1);
}
/**
* Split the Track at approximately the point pos.
*/
-static BOOL_T SplitBezier( track_p trk, coOrd pos, EPINX_T ep, track_p *leftover, EPINX_T * ep0, EPINX_T * ep1 )
+static BOOL_T SplitBezier( track_p trk, coOrd pos, EPINX_T ep,
+ track_p *leftover, EPINX_T * ep0, EPINX_T * ep1 )
{
- struct extraData *xx = GetTrkExtraData(trk);
+ struct extraDataBezier_t *xx = GET_EXTRA_DATA(trk, T_NOTRACK,
+ extraDataBezier_t);
track_p trk1;
- double t;
- BOOL_T track;
- track = IsTrack(trk);
-
- coOrd current[4], newl[4], newr[4];
-
- double dd = DistanceBezier(trk, &pos);
- if (dd>minLength) return FALSE;
-
- BezierMathDistance(&pos, xx->bezierData.pos, 500, &t); //Find t value
-
- for (int i=0;i<4;i++) {
- current[i] = xx->bezierData.pos[i];
- }
-
- BezierSplit(current, newl, newr, t);
-
- if (track) {
- trk1 = NewBezierTrack(ep?newr:newl,NULL,0);
- //Move elev data from ep
- } else
- trk1 = NewBezierLine(ep?newr:newl,NULL,0, xx->bezierData.segsColor,xx->bezierData.segsWidth);
- DIST_T height;
- int opt;
- GetTrkEndElev(trk,ep,&opt,&height);
- UpdateTrkEndElev( trk1, ep, opt, height, (opt==ELEV_STATION)?GetTrkEndElevStation(trk,ep):NULL );
- UndoModify(trk);
- for (int i=0;i<4;i++) {
- xx->bezierData.pos[i] = ep?newl[i]:newr[i];
- }
- FixUpBezier(xx->bezierData.pos,xx,track);
- ComputeBezierBoundingBox(trk,xx);
- SetTrkEndPoint( trk, ep, xx->bezierData.pos[ep?3:0], ep?xx->bezierData.a1:xx->bezierData.a0);
- UpdateTrkEndElev( trk, ep, ELEV_NONE, 0, NULL);
+ double t;
+ BOOL_T track;
+ track = IsTrack(trk);
+
+ coOrd current[4], newl[4], newr[4];
+
+ double dd = DistanceBezier(trk, &pos);
+ if (dd>minLength) { return FALSE; }
+
+ BezierMathDistance(&pos, xx->pos, 500, &t); //Find t value
+
+ for (int i=0; i<4; i++) {
+ current[i] = xx->pos[i];
+ }
+
+ BezierSplit(current, newl, newr, t);
+
+ if (track) {
+ trk1 = NewBezierTrack(ep?newr:newl,NULL,0);
+ //Move elev data from ep
+ DIST_T height;
+ int opt;
+ GetTrkEndElev(trk,ep,&opt,&height);
+ UpdateTrkEndElev( trk1, ep, opt, height,
+ (opt==ELEV_STATION)?GetTrkEndElevStation(trk,ep):NULL );
+ } else {
+ trk1 = NewBezierLine(ep?newr:newl,NULL,0, xx->segsColor,xx->segsLineWidth);
+ }
+ UndoModify(trk);
+ for (int i=0; i<4; i++) {
+ xx->pos[i] = ep?newl[i]:newr[i];
+ }
+ FixUpBezier(xx->pos,xx,track);
+ ComputeBezierBoundingBox(trk,xx);
+ if ( track ) {
+ SetTrkEndPoint( trk, ep, xx->pos[ep?3:0], ep?xx->a1:xx->a0);
+ UpdateTrkEndElev( trk, ep, ELEV_NONE, 0, NULL);
+ }
*leftover = trk1;
*ep0 = 1-ep;
*ep1 = ep;
@@ -768,30 +843,33 @@ static int log_bezierSegments = 0;
*/
static BOOL_T TraverseBezier( traverseTrack_p trvTrk, DIST_T * distR )
{
- track_p trk = trvTrk->trk;
- struct extraData *xx = GetTrkExtraData(trk);
+ track_p trk = trvTrk->trk;
+ struct extraDataBezier_t *xx = GET_EXTRA_DATA(trk, T_BEZIER, extraDataBezier_t);
DIST_T dist = *distR;
segProcData_t segProcData;
BOOL_T segs_backwards= FALSE;
- DIST_T d = 10000;
+ DIST_T d = DIST_INF;
coOrd pos2 = trvTrk->pos;
ANGLE_T a1,a2;
int inx,segInx = 0;
EPINX_T ep;
BOOL_T back,neg;
- trkSeg_p segPtr = (trkSeg_p)xx->bezierData.arcSegs.ptr;
+ trkSeg_p segPtr = &DYNARR_N(trkSeg_t,xx->arcSegs,0);
a2 = GetAngleSegs( //Find correct Segment and nearest point in it
- xx->bezierData.arcSegs.cnt,segPtr,
- &pos2, &segInx, &d , &back, NULL, &neg ); //d = how far pos2 from old pos2 = trvTrk->pos
+ xx->arcSegs.cnt,segPtr,
+ &pos2, &segInx, &d, &back, NULL,
+ &neg ); //d = how far pos2 from old pos2 = trvTrk->pos
if ( d > 10 ) {
- ErrorMessage( "traverseBezier: Position is not near track: %0.3f", d );
- return FALSE; //This means the input pos is not on or close to the track.
+ ErrorMessage( "traverseBezier: Position is not near track: %0.3f", d );
+ return FALSE; //This means the input pos is not on or close to the track.
}
- if (back) a2 = NormalizeAngle(a2+180); //GetAngleSegs has reversed angle for backwards
- a1 = NormalizeAngle(a2-trvTrk->angle); //Establish if we are going fwds or backwards globally
- if (a1 <270 && a1>90) { //Must add 180 if the seg is reversed or inverted (but not both)
+ if (back) { a2 = NormalizeAngle(a2+180); } //GetAngleSegs has reversed angle for backwards
+ a1 = NormalizeAngle(a2
+ -trvTrk->angle); //Establish if we are going fwds or backwards globally
+ if (a1 <270
+ && a1>90) { //Must add 180 if the seg is reversed or inverted (but not both)
segs_backwards = TRUE;
ep = 0;
} else {
@@ -804,25 +882,34 @@ static BOOL_T TraverseBezier( traverseTrack_p trvTrk, DIST_T * distR )
}
segProcData.traverse1.pos = pos2; //actual point on curve
- segProcData.traverse1.angle = trvTrk->angle; //direction car is going for Traverse 1 has to be reversed...
-LOG( log_traverseBezier, 1, ( " TraverseBezier [%0.3f %0.3f] D%0.3f A%0.3f SB%d \n", trvTrk->pos.x, trvTrk->pos.y, dist, trvTrk->angle, segs_backwards ) )
+ segProcData.traverse1.angle =
+ trvTrk->angle; //direction car is going for Traverse 1 has to be reversed...
+ LOG( log_traverseBezier, 1,
+ ( " TraverseBezier [%0.3f %0.3f] D%0.3f A%0.3f SB%d \n", trvTrk->pos.x,
+ trvTrk->pos.y, dist, trvTrk->angle, segs_backwards ) )
inx = segInx;
- while (inx >=0 && inx<xx->bezierData.arcSegs.cnt) {
- segPtr = (trkSeg_p)xx->bezierData.arcSegs.ptr+inx; //move in to the identified segment
- SegProc( SEGPROC_TRAVERSE1, segPtr, &segProcData ); //Backwards or forwards for THIS segment - note that this can differ from segs_backward!!
+ while (inx >=0 && inx<xx->arcSegs.cnt) {
+ segPtr = &DYNARR_N(trkSeg_t,xx->arcSegs,
+ inx); //move in to the identified segment
+ SegProc( SEGPROC_TRAVERSE1, segPtr,
+ &segProcData ); //Backwards or forwards for THIS segment - note that this can differ from segs_backward!!
BOOL_T backwards = segProcData.traverse1.backwards; //Are we going to EP0?
- BOOL_T reverse_seg = segProcData.traverse1.reverse_seg; //is it a backwards segment (we don't actually care as Traverse1 takes care of it)
+ BOOL_T reverse_seg =
+ segProcData.traverse1.reverse_seg; //is it a backwards segment (we don't actually care as Traverse1 takes care of it)
dist += segProcData.traverse1.dist;
segProcData.traverse2.dist = dist;
segProcData.traverse2.segDir = backwards;
-LOG( log_traverseBezier, 2, ( " TraverseBezierT1 D%0.3f B%d RS%d \n", dist, backwards, reverse_seg ) )
+ LOG( log_traverseBezier, 2, ( " TraverseBezierT1 D%0.3f B%d RS%d \n", dist,
+ backwards, reverse_seg ) )
SegProc( SEGPROC_TRAVERSE2, segPtr, &segProcData ); //Angle at pos2
- if ( segProcData.traverse2.dist <= 0 ) { //-ve or zero distance left over so stop there
+ if ( segProcData.traverse2.dist <=
+ 0 ) { //-ve or zero distance left over so stop there
*distR = 0;
trvTrk->pos = segProcData.traverse2.pos;
trvTrk->angle = segProcData.traverse2.angle;
-LOG( log_traverseBezier, 1, ( " -> [%0.3f %0.3f] A%0.3f D%0.3f\n", trvTrk->pos.x, trvTrk->pos.y, trvTrk->angle, *distR ) )
+ LOG( log_traverseBezier, 1, ( " -> [%0.3f %0.3f] A%0.3f D%0.3f\n",
+ trvTrk->pos.x, trvTrk->pos.y, trvTrk->angle, *distR ) )
return TRUE;
} //NOTE Traverse1 and Traverse2 are overlays so get all out before storing
dist = segProcData.traverse2.dist; //How far left?
@@ -830,117 +917,108 @@ LOG( log_traverseBezier, 1, ( " -> [%0.3f %0.3f] A%0.3f D%0.3f\n", trvTrk->pos.
ANGLE_T angle = segProcData.traverse2.angle; //Angle of end
segProcData.traverse1.angle = angle; //Reverse to suit Traverse1
segProcData.traverse1.pos = pos;
- inx = segs_backwards?inx-1:inx+1; //Here's where the global segment direction comes in
-LOG( log_traverseBezier, 2, ( " TraverseBezierL D%0.3f A%0.3f\n", dist, angle ) )
+ inx = segs_backwards?inx-1:inx
+ +1; //Here's where the global segment direction comes in
+ LOG( log_traverseBezier, 2, ( " TraverseBezierL D%0.3f A%0.3f\n", dist,
+ angle ) )
}
*distR = dist; //Tell caller what is left
- //Must be at one end or another
+ //Must be at one end or another
trvTrk->pos = GetTrkEndPos(trk,ep);
- trvTrk->angle = NormalizeAngle(GetTrkEndAngle(trk, ep));//+(segs_backwards?180:0))
+ trvTrk->angle = NormalizeAngle(GetTrkEndAngle(trk,
+ ep));//+(segs_backwards?180:0))
trvTrk->trk = GetTrkEndTrk(trk,ep); //go to next track
if (trvTrk->trk==NULL) {
trvTrk->pos = pos2;
- return TRUE;
+ return TRUE;
}
-LOG( log_traverseBezier, 1, ( " -> [%0.3f %0.3f] A%0.3f D%0.3f\n", trvTrk->pos.x, trvTrk->pos.y, trvTrk->angle, *distR ) )
+ LOG( log_traverseBezier, 1, ( " -> [%0.3f %0.3f] A%0.3f D%0.3f\n",
+ trvTrk->pos.x, trvTrk->pos.y, trvTrk->angle, *distR ) )
return TRUE;
}
static BOOL_T MergeBezier(
- track_p trk0,
- EPINX_T ep0,
- track_p trk1,
- EPINX_T ep1 )
+ track_p trk0,
+ EPINX_T ep0,
+ track_p trk1,
+ EPINX_T ep1 )
{
- struct extraData *xx0 = GetTrkExtraData(trk0);
- struct extraData *xx1 = GetTrkExtraData(trk1);
- track_p trk2 = NULL;
- EPINX_T ep2=-1;
- BOOL_T tracks = FALSE;
-
- if (IsTrack(trk0) && IsTrack(trk1) ) tracks = TRUE;
- if (GetTrkType(trk0) != GetTrkType(trk1)) return FALSE;
-
- if (ep0 == ep1)
- return FALSE;
-
- UndoStart( _("Merge Bezier"), "MergeBezier( T%d[%d] T%d[%d] )", GetTrkIndex(trk0), ep0, GetTrkIndex(trk1), ep1 );
- UndoModify( trk0 );
- UndrawNewTrack( trk0 );
- if (tracks) {
- trk2 = GetTrkEndTrk( trk1, 1-ep1 );
- if (trk2) {
- ep2 = GetEndPtConnectedToMe( trk2, trk1 );
- DisconnectTracks( trk1, 1-ep1, trk2, ep2 );
- }
- }
- if (ep0 == 0) {
- xx0->bezierData.pos[3] = xx1->bezierData.pos[3];
- xx0->bezierData.pos[2] = xx1->bezierData.pos[2];
- } else {
- xx0->bezierData.pos[0] = xx1->bezierData.pos[0];
- xx0->bezierData.pos[1] = xx1->bezierData.pos[1];
- }
- FixUpBezier(xx0->bezierData.pos,xx0,tracks);
- ComputeBezierBoundingBox(trk0,xx0);
- DeleteTrack( trk1, FALSE );
- if (tracks && trk2) {
- if (ep0 == 1)
- SetTrkEndPoint( trk2, 1, xx0->bezierData.pos[0], xx0->bezierData.a0);
- else
- SetTrkEndPoint( trk2, 2, xx0->bezierData.pos[3], xx0->bezierData.a1);
- ConnectTracks( trk0, ep0, trk2, ep2 );
- }
- DrawNewTrack( trk0 );
-
- return TRUE;
+ return FALSE;
}
static BOOL_T EnumerateBezier( track_p trk )
{
- if (trk != NULL) {
+ if ((trk != NULL) && (GetTrkType(trk) == T_BEZIER)) {
DIST_T d;
- struct extraData *xx = GetTrkExtraData(trk);
- d = max(BezierOffsetLength(xx->bezierData.arcSegs,-GetTrkGauge(trk)/2.0),
- BezierOffsetLength(xx->bezierData.arcSegs,GetTrkGauge(trk)/2.0));
+ struct extraDataBezier_t *xx = GET_EXTRA_DATA(trk, T_BEZIER, extraDataBezier_t);
+ d = max(BezierOffsetLength(xx->arcSegs,-GetTrkGauge(trk)/2.0),
+ BezierOffsetLength(xx->arcSegs,GetTrkGauge(trk)/2.0));
ScaleLengthIncrement( GetTrkScale(trk), d );
+ return TRUE;
}
- return TRUE;
+ return FALSE;
}
static DIST_T GetLengthBezier( track_p trk )
{
- struct extraData *xx = GetTrkExtraData(trk);
+ struct extraDataBezier_t *xx = GET_EXTRA_DATA(trk, T_NOTRACK,
+ extraDataBezier_t);
DIST_T length = 0.0;
segProcData_t segProcData;
- for(int i=0;i<xx->bezierData.arcSegs.cnt;i++) {
- SegProc(SEGPROC_LENGTH,&(DYNARR_N(trkSeg_t,xx->bezierData.arcSegs,i)), &segProcData);
+ for(int i=0; i<xx->arcSegs.cnt; i++) {
+ SegProc(SEGPROC_LENGTH,&(DYNARR_N(trkSeg_t,xx->arcSegs,i)), &segProcData);
length += segProcData.length.length;
}
return length;
}
+EXPORT BOOL_T GetBezierMiddle( track_p trk, coOrd * pos)
+{
+
+ if (GetTrkType(trk) != T_BEZIER) {
+ return FALSE;
+ }
+// struct extraDataBezier_t *xx = GET_EXTRA_DATA(trk, T_BEZIER, extraDataBezier_t);
+ DIST_T length = GetLengthBezier(trk)/2;
+
+ traverseTrack_t tp;
+ tp.pos = GetTrkEndPos(trk,0);
+ tp.angle = NormalizeAngle(GetTrkEndAngle(trk,0)+180.0);
+ tp.trk = trk;
+ tp.length = length;
+
+ TraverseBezier(&tp,&length);
+
+ *pos = tp.pos;
+
+ return TRUE;
+
+}
+
-static BOOL_T GetParamsBezier( int inx, track_p trk, coOrd pos, trackParams_t * params )
+static BOOL_T GetParamsBezier( int inx, track_p trk, coOrd pos,
+ trackParams_t * params )
{
int segInx;
BOOL_T back,negative;
DIST_T d;
params->type = curveTypeBezier;
- struct extraData *xx = GetTrkExtraData(trk);
- for (int i=0;i<4;i++) params->bezierPoints[i] = xx->bezierData.pos[i];
- params->len = xx->bezierData.length;
- params->track_angle = GetAngleSegs( //Find correct Segment and nearest point in it
- xx->bezierData.arcSegs.cnt,xx->bezierData.arcSegs.ptr,
- &pos, &segInx, &d , &back, NULL, &negative );
- if ( negative != back ) params->track_angle = NormalizeAngle(params->track_angle+180); //Bezier is in reverse
- trkSeg_p segPtr = &DYNARR_N(trkSeg_t,xx->bezierData.arcSegs,segInx);
+ struct extraDataBezier_t *xx = GET_EXTRA_DATA(trk, T_NOTRACK,
+ extraDataBezier_t);
+ for (int i=0; i<4; i++) { params->bezierPoints[i] = xx->pos[i]; }
+ params->len = xx->length;
+ params->track_angle =
+ GetAngleSegs( //Find correct Segment and nearest point in it
+ xx->arcSegs.cnt,&DYNARR_N(trkSeg_t,xx->arcSegs,0),
+ &pos, &segInx, &d, &back, NULL, &negative );
+ if ( negative != back ) { params->track_angle = NormalizeAngle(params->track_angle+180); } //Bezier is in reverse
+ trkSeg_p segPtr = &DYNARR_N(trkSeg_t,xx->arcSegs,segInx);
if (segPtr->type == SEG_STRLIN) {
params->arcR = 0.0;
} else {
@@ -950,17 +1028,21 @@ static BOOL_T GetParamsBezier( int inx, track_p trk, coOrd pos, trackParams_t *
params->arcA1 = segPtr->u.c.a1;
}
if ( inx == PARAMS_NODES ) {
- if (GetTrkType(trk) == T_BEZIER) return FALSE;
- if (FindDistance(pos,params->bezierPoints[0]) > FindDistance(pos,params->bezierPoints[3]))
- params->ep = 1;
- else params->ep = 0;
- coOrd curr_pos = params->bezierPoints[params->ep*3];
+ if (GetTrkType(trk) == T_BEZIER) { return FALSE; }
+ //Pos is the place that is the end of the curve (params->ep set to 1 if the curve starts here)
+ if (FindDistance(pos,params->bezierPoints[0]) <= FindDistance(pos,
+ params->bezierPoints[3])) {
+ params->ep = 1;
+ } else { params->ep = 0; }
+ coOrd curr_pos = params->bezierPoints[0];
BOOL_T first = TRUE;
DYNARR_RESET(coOrd,params->nodes);
- for (int i = 0; i<xx->bezierData.arcSegs.cnt;i++) {
- trkSeg_p segPtr = &DYNARR_N(trkSeg_t,xx->bezierData.arcSegs,params->ep?xx->bezierData.arcSegs.cnt-1-i:i);
+ // Load out the points in order from bezierPoint[0] to bezierPoint[3]
+ for (int i = 0; i<xx->arcSegs.cnt; i++) {
+ trkSeg_p segPtr = &DYNARR_N(trkSeg_t,xx->arcSegs,i);
if (segPtr->type == SEG_STRLIN) {
- BOOL_T eps = FindDistance(segPtr->u.l.pos[0],curr_pos)>FindDistance(segPtr->u.l.pos[1],curr_pos);
+ BOOL_T eps = FindDistance(segPtr->u.l.pos[0],
+ curr_pos)>FindDistance(segPtr->u.l.pos[1],curr_pos);
if (first) {
first = FALSE;
DYNARR_APPEND(coOrd,params->nodes,1);
@@ -971,49 +1053,62 @@ static BOOL_T GetParamsBezier( int inx, track_p trk, coOrd pos, trackParams_t *
} else {
coOrd start,end;
Translate(&start,segPtr->u.c.center,segPtr->u.c.a0,fabs(segPtr->u.c.radius));
- Translate(&end,segPtr->u.c.center,segPtr->u.c.a0+segPtr->u.c.a1,fabs(segPtr->u.c.radius));
+ Translate(&end,segPtr->u.c.center,segPtr->u.c.a0+segPtr->u.c.a1,
+ fabs(segPtr->u.c.radius));
+ //Is this segment reversed in the curve?
BOOL_T back = FindDistance(start,curr_pos)>FindDistance(end,curr_pos);
if (segPtr->u.c.radius > 0.5) {
- double min_angle = 360*acos(1.0-(0.1/fabs(segPtr->u.c.radius)))/M_PI; //Error max is 0.1"
+ double min_angle = 360*acos(1.0-(0.1/fabs(
+ segPtr->u.c.radius)))/M_PI; //Error max is 0.1"
double number = ceil(segPtr->u.c.a1/min_angle);
double arc_size = segPtr->u.c.a1/number;
- for (int j=1-first;j<=number;j++) {
- DYNARR_APPEND(coOrd,params->nodes,1);
- if (back == params->ep)
- Translate(&DYNARR_LAST(coOrd,params->nodes),segPtr->u.c.center,segPtr->u.c.a0+segPtr->u.c.a1-(j*arc_size),fabs(segPtr->u.c.radius) );
- else
- Translate(&DYNARR_LAST(coOrd,params->nodes),segPtr->u.c.center,segPtr->u.c.a0+(j*arc_size),fabs(segPtr->u.c.radius) );
+ if (back) {
+ //If back, list sub-points in reverse. If first show first position, else skip
+ for (int j=(((int)number)-(1-first)); j>=0; j--) {
+ DYNARR_APPEND(coOrd,params->nodes,((int)number));
+ Translate(&DYNARR_LAST(coOrd,params->nodes),segPtr->u.c.center,
+ segPtr->u.c.a0+j*arc_size,fabs(segPtr->u.c.radius) );
+ }
+ } else {
+ for (int j=(1-first); j<=number; j++) {
+ DYNARR_APPEND(coOrd,params->nodes,((int)number));
+ Translate(&DYNARR_LAST(coOrd,params->nodes),segPtr->u.c.center,
+ segPtr->u.c.a0+j*arc_size,fabs(segPtr->u.c.radius) );
+ }
}
first = FALSE;
} else {
if (first) {
first = FALSE;
DYNARR_APPEND(coOrd,params->nodes,1);
- DYNARR_LAST(coOrd,params->nodes) = start;
+ DYNARR_LAST(coOrd,params->nodes) = back?end:start;
}
DYNARR_APPEND(coOrd,params->nodes,1);
- DYNARR_LAST(coOrd,params->nodes) = end;
-
+ DYNARR_LAST(coOrd,params->nodes) = back?start:end;
}
}
curr_pos = DYNARR_LAST(coOrd,params->nodes);
}
- params->lineOrig = params->bezierPoints[params->ep*3];
- params->lineEnd = params->bezierPoints[(1-params->ep)*3];
+ params->lineOrig = params->bezierPoints[params->ep?0:3];
+ params->lineEnd = params->bezierPoints[params->ep?3:0];
return TRUE;
- } else if ((inx == PARAMS_CORNU) || (inx == PARAMS_1ST_JOIN) || (inx == PARAMS_2ND_JOIN)){
+ } else if ((inx == PARAMS_CORNU) || (inx == PARAMS_1ST_JOIN)
+ || (inx == PARAMS_2ND_JOIN)) {
params->ep = PickEndPoint( pos, trk);
} else {
params->ep = PickUnconnectedEndPointSilent( pos, trk);
}
- if (params->ep>=0)
+ if (params->ep>=0) {
params->angle = GetTrkEndAngle(trk, params->ep);
+ }
return TRUE;
}
-static BOOL_T TrimBezier( track_p trk, EPINX_T ep, DIST_T dist, coOrd endpos, ANGLE_T angle, DIST_T radius, coOrd center ) {
+static BOOL_T TrimBezier( track_p trk, EPINX_T ep, DIST_T dist, coOrd endpos,
+ ANGLE_T angle, DIST_T radius, coOrd center )
+{
UndrawNewTrack( trk );
DeleteTrack(trk, TRUE);
return TRUE;
@@ -1023,17 +1118,21 @@ static BOOL_T TrimBezier( track_p trk, EPINX_T ep, DIST_T dist, coOrd endpos, AN
static BOOL_T QueryBezier( track_p trk, int query )
{
- struct extraData * xx = GetTrkExtraData(trk);
+ struct extraDataBezier_t * xx = GET_EXTRA_DATA(trk, T_NOTRACK,
+ extraDataBezier_t);
switch ( query ) {
case Q_CAN_GROUP:
return FALSE;
break;
case Q_FLIP_ENDPTS:
+ return GetTrkType(trk) == T_BEZIER?TRUE:FALSE;
+ break;
case Q_HAS_DESC:
return TRUE;
break;
case Q_EXCEPTION:
- return GetTrkType(trk) == T_BEZIER?fabs(xx->bezierData.minCurveRadius) < (GetLayoutMinTrackRadius()-EPSILON):FALSE;
+ return GetTrkType(trk) == T_BEZIER?fabs(xx->minCurveRadius) <
+ (GetLayoutMinTrackRadius()-EPSILON):FALSE;
break;
case Q_CAN_MODIFY_CONTROL_POINTS:
return TRUE;
@@ -1048,6 +1147,8 @@ static BOOL_T QueryBezier( track_p trk, int query )
return TRUE;
break;
case Q_MODIFY_CAN_SPLIT:
+ return TRUE;
+ break;
case Q_CORNU_CAN_MODIFY:
return (GetTrkType(trk) == T_BEZIER);
case Q_GET_NODES:
@@ -1059,72 +1160,92 @@ static BOOL_T QueryBezier( track_p trk, int query )
static void FlipBezier(
- track_p trk,
- coOrd orig,
- ANGLE_T angle )
+ track_p trk,
+ coOrd orig,
+ ANGLE_T angle )
{
- struct extraData * xx = GetTrkExtraData(trk);
- FlipPoint( &xx->bezierData.pos[0], orig, angle );
- FlipPoint( &xx->bezierData.pos[1], orig, angle );
- FlipPoint( &xx->bezierData.pos[2], orig, angle );
- FlipPoint( &xx->bezierData.pos[3], orig, angle );
- FixUpBezier(xx->bezierData.pos,xx,IsTrack(trk));
- ComputeBezierBoundingBox(trk,xx);
+ struct extraDataBezier_t * xx = GET_EXTRA_DATA(trk, T_NOTRACK,
+ extraDataBezier_t);
+ FlipPoint( &xx->pos[0], orig, angle );
+ FlipPoint( &xx->pos[1], orig, angle );
+ FlipPoint( &xx->pos[2], orig, angle );
+ FlipPoint( &xx->pos[3], orig, angle );
+
+ // Reverse control point order
+ coOrd pos = xx->pos[0];
+ xx->pos[0] = xx->pos[3];
+ xx->pos[3] = pos;
+
+ pos = xx->pos[1];
+ xx->pos[1] = xx->pos[2];
+ xx->pos[2] = pos;
+
+ FixUpBezier(xx->pos,xx,IsTrack(trk));
+ ComputeBezierBoundingBox(trk,xx);
}
static ANGLE_T GetAngleBezier(
- track_p trk,
- coOrd pos,
- EPINX_T * ep0,
- EPINX_T * ep1 )
+ track_p trk,
+ coOrd pos,
+ EPINX_T * ep0,
+ EPINX_T * ep1 )
{
- struct extraData * xx = GetTrkExtraData(trk);
+ struct extraDataBezier_t * xx = GET_EXTRA_DATA(trk, T_NOTRACK,
+ extraDataBezier_t);
ANGLE_T angle;
BOOL_T back, neg;
int indx;
- angle = GetAngleSegs( xx->bezierData.arcSegs.cnt, (trkSeg_p)xx->bezierData.arcSegs.ptr, &pos, &indx, NULL, &back, NULL, &neg );
- if (!back) angle = NormalizeAngle(angle+180); //Make CCW
- if ( ep0 ) *ep0 = neg?1:0;
- if ( ep1 ) *ep1 = neg?0:1;
+ angle = GetAngleSegs( xx->arcSegs.cnt, &DYNARR_N(trkSeg_t,xx->arcSegs,0), &pos,
+ &indx, NULL, &back, NULL, &neg );
+ if (!back) { angle = NormalizeAngle(angle+180); } //Make CCW
+ if ( ep0 ) { *ep0 = neg?1:0; }
+ if ( ep1 ) { *ep1 = neg?0:1; }
return angle;
}
-BOOL_T GetBezierSegmentFromTrack(track_p trk, trkSeg_p seg_p) {
- struct extraData * xx = GetTrkExtraData(trk);
+BOOL_T GetBezierSegmentFromTrack(track_p trk, trkSeg_p seg_p)
+{
+ struct extraDataBezier_t * xx = GET_EXTRA_DATA(trk, T_NOTRACK,
+ extraDataBezier_t);
seg_p->type = IsTrack(trk)?SEG_BEZTRK:SEG_BEZLIN;
- for (int i=0;i<4;i++) seg_p->u.b.pos[i] = xx->bezierData.pos[i];
- seg_p->color = xx->bezierData.segsColor;
- seg_p->bezSegs.cnt = 0;
- if (seg_p->bezSegs.ptr) MyFree(seg_p->bezSegs.ptr);
- seg_p->bezSegs.max = 0;
- seg_p->bezSegs.ptr = NULL;
+ for (int i=0; i<4; i++) { seg_p->u.b.pos[i] = xx->pos[i]; }
+ seg_p->color = xx->segsColor;
+ seg_p->lineWidth = xx->segsLineWidth;
+ DYNARR_FREE( trkSeg_t, seg_p->bezSegs );
FixUpBezierSeg(seg_p->u.b.pos,seg_p,seg_p->type == SEG_BEZTRK);
return TRUE;
}
-BOOL_T GetTracksFromBezierSegment(trkSeg_p bezSeg, track_p newTracks[2], track_p trk) {
+BOOL_T GetTracksFromBezierSegment(trkSeg_p bezSeg, track_p newTracks[2],
+ track_p trk)
+{
track_p trk_old = NULL;
newTracks[0] = NULL, newTracks[1] = NULL;
- if (bezSeg->type != SEG_BEZTRK) return FALSE;
- for (int i=0;i<bezSeg->bezSegs.cnt;i++) {
+ if (bezSeg->type != SEG_BEZTRK) { return FALSE; }
+ for (int i=0; i<bezSeg->bezSegs.cnt; i++) {
trkSeg_p seg = &DYNARR_N(trkSeg_t,bezSeg->bezSegs,i);
track_p new_trk;
- if (seg->type == SEG_CRVTRK)
- new_trk = NewCurvedTrack(seg->u.c.center,fabs(seg->u.c.radius),seg->u.c.a0,seg->u.c.a1,0);
- else if (seg->type == SEG_STRTRK)
+ if (seg->type == SEG_CRVTRK) {
+ new_trk = NewCurvedTrack(seg->u.c.center,fabs(seg->u.c.radius),seg->u.c.a0,
+ seg->u.c.a1,0);
+ } else if (seg->type == SEG_STRTRK) {
new_trk = NewStraightTrack(seg->u.l.pos[0],seg->u.l.pos[1]);
- if (newTracks[0] == NULL) newTracks[0] = new_trk;
+ }
+ if (newTracks[0] == NULL) { newTracks[0] = new_trk; }
CopyAttributes( trk, new_trk );
newTracks[1] = new_trk;
if (trk_old) {
- for (int i=0;i<2;i++) {
+ for (int i=0; i<2; i++) {
if (GetTrkEndTrk(trk_old,i)==NULL) {
coOrd pos = GetTrkEndPos(trk_old,i);
EPINX_T ep_n = PickUnconnectedEndPoint(pos,new_trk);
- if (connectDistance >= FindDistance(GetTrkEndPos(trk_old,i),GetTrkEndPos(new_trk,ep_n))) {
+ if ((connectDistance >= FindDistance(GetTrkEndPos(trk_old,i),
+ GetTrkEndPos(new_trk,ep_n))) &&
+ (connectAngle >= fabs(DifferenceBetweenAngles(GetTrkEndAngle(trk_old,i),
+ GetTrkEndAngle(new_trk,ep_n)+180))) ) {
ConnectTracks(trk_old,i,new_trk,ep_n);
break;
}
@@ -1136,91 +1257,86 @@ BOOL_T GetTracksFromBezierSegment(trkSeg_p bezSeg, track_p newTracks[2], track_p
return TRUE;
}
-BOOL_T GetTracksFromBezierTrack(track_p trk, track_p newTracks[2]) {
+BOOL_T GetTracksFromBezierTrack(track_p trk, track_p newTracks[2])
+{
trkSeg_t seg_temp;
- struct extraData * xx = GetTrkExtraData(trk);
+ DYNARR_INIT( trkSeg_t, seg_temp.bezSegs );
newTracks[0] = NULL, newTracks[1] = NULL;
- if (!IsTrack(trk)) return FALSE;
+ if (!IsTrack(trk)) { return FALSE; }
+ struct extraDataBezier_t * xx = GET_EXTRA_DATA(trk, T_BEZIER,
+ extraDataBezier_t);
seg_temp.type = SEG_BEZTRK;
- for (int i=0;i<4;i++) seg_temp.u.b.pos[i] = xx->bezierData.pos[i];
- seg_temp.color = xx->bezierData.segsColor;
- seg_temp.bezSegs.cnt = 0;
- seg_temp.bezSegs.max = 0;
- //if (seg_temp->bezSegs.ptr) MyFree(seg_temp->bezSegs.ptr);
- DYNARR_RESET(trkSeg_t,seg_temp.bezSegs);
+ for (int i=0; i<4; i++) { seg_temp.u.b.pos[i] = xx->pos[i]; }
+ seg_temp.color = xx->segsColor;
FixUpBezierSeg(seg_temp.u.b.pos,&seg_temp,TRUE);
GetTracksFromBezierSegment(&seg_temp, newTracks, trk);
- MyFree(seg_temp.bezSegs.ptr);
- seg_temp.bezSegs.cnt = 0;
- seg_temp.bezSegs.max = 0;
- seg_temp.bezSegs.ptr = NULL;
+ DYNARR_FREE( trkSeg_t, seg_temp.bezSegs );
return TRUE;
}
-
static BOOL_T MakeParallelBezier(
- track_p trk,
- coOrd pos,
- DIST_T sep,
- DIST_T factor,
- track_p * newTrkR,
- coOrd * p0R,
- coOrd * p1R,
- BOOL_T track)
+ track_p trk,
+ coOrd pos,
+ DIST_T sep,
+ DIST_T factor,
+ track_p * newTrkR,
+ coOrd * p0R,
+ coOrd * p1R,
+ BOOL_T track)
{
- struct extraData * xx = GetTrkExtraData(trk);
- coOrd np[4], p;
- ANGLE_T a,a2;
+ struct extraDataBezier_t * xx = GET_EXTRA_DATA(trk, T_NOTRACK,
+ extraDataBezier_t);
+ coOrd np[4], p;
+ ANGLE_T a0, a1,a2;
//Produce bezier that is translated parallel to the existing Bezier
- // - not a precise result if the bezier end angles are not in the same general direction.
- // The expectation is that the user will have to adjust it - unless and until we produce
- // a new algo to adjust the control points to be parallel to the endpoints.
-
- a = FindAngle(xx->bezierData.pos[0],xx->bezierData.pos[3]);
- p = pos;
- DistanceBezier(trk, &p);
- a2 = NormalizeAngle(FindAngle(pos,p)-a);
- //find parallel move x and y for points
- for (int i =0; i<4;i++) {
- np[i] = xx->bezierData.pos[i];
- }
- sep = sep+factor/xx->bezierData.minCurveRadius;
- // Adjust sep based on radius and factor
- if ( a2 > 180 ) {
- Translate(&np[0],np[0],a+90,sep);
- Translate(&np[1],np[1],a+90,sep);
- Translate(&np[2],np[2],a+90,sep);
- Translate(&np[3],np[3],a+90,sep);
- } else {
- Translate(&np[0],np[0],a-90,sep);
- Translate(&np[1],np[1],a-90,sep);
- Translate(&np[2],np[2],a-90,sep);
- Translate(&np[3],np[3],a-90,sep);
- }
+ // - not a precise result if the bezier end angles are not in the same general direction.
+ // The expectation is that the user will have to adjust it - unless and until we produce
+ // a new algo to adjust the control points to be parallel to the endpoints.
+
+ a0 = xx->a0;
+ a1 = xx->a1;
+ p = pos;
+ DistanceBezier(trk, &p);
+ a2 = NormalizeAngle(FindAngle(pos,p)-a0);
+ a2 = NormalizeAngle(FindAngle(pos,p)-a0);
+ //find parallel move x and y for points
+ for (int i =0; i<4; i++) {
+ np[i] = xx->pos[i];
+ }
+ sep = sep+factor/xx->minCurveRadius;
+ // Adjust sep based on radius and factor
+ if ( a2 > 180 ) {
+ Translate(&np[0],np[0],a0+90,sep);
+ Translate(&np[1],np[1],a0+90,sep);
+ Translate(&np[2],np[2],a1-90,sep);
+ Translate(&np[3],np[3],a1-90,sep);
+ } else {
+ Translate(&np[0],np[0],a0-90,sep);
+ Translate(&np[1],np[1],a0-90,sep);
+ Translate(&np[2],np[2],a1+90,sep);
+ Translate(&np[3],np[3],a1+90,sep);
+ }
if ( newTrkR ) {
- if (track)
+ if (track) {
*newTrkR = NewBezierTrack( np, NULL, 0);
- else
+ } else {
*newTrkR = NewBezierLine( np, NULL, 0, wDrawColorBlack, 0);
+ }
} else {
DYNARR_SET( trkSeg_t, tempSegs_da, 1 );
tempSegs(0).color = wDrawColorBlack;
- tempSegs(0).width = 0;
- tempSegs_da.cnt = 1;
+ tempSegs(0).lineWidth = 0;
tempSegs(0).type = track?SEG_BEZTRK:SEG_BEZLIN;
- if (tempSegs(0).bezSegs.ptr) MyFree(tempSegs(0).bezSegs.ptr);
- tempSegs(0).bezSegs.ptr = 0;
- tempSegs(0).bezSegs.max = 0;
- tempSegs(0).bezSegs.cnt = 0;
- for (int i=0;i<4;i++) tempSegs(0).u.b.pos[i] = np[i];
- FixUpBezierSeg(tempSegs(0).u.b.pos,&tempSegs(0),TRUE);
+ DYNARR_INIT( trkSeg_t, tempSegs(0).bezSegs );
+ for (int i=0; i<4; i++) { tempSegs(0).u.b.pos[i] = np[i]; }
+ FixUpBezierSeg(tempSegs(0).u.b.pos,&tempSegs(0),track);
}
- if ( p0R ) *p0R = np[0];
- if ( p1R ) *p1R = np[1];
+ if ( p0R ) { *p0R = np[0]; }
+ if ( p1R ) { *p1R = np[1]; }
return TRUE;
}
@@ -1229,28 +1345,32 @@ static BOOL_T MakeParallelBezier(
* ensure
* - that the Segs are restored and
* - other fields reset.
+ * Not called for deleted tracks
*/
BOOL_T RebuildBezier (track_p trk)
{
- struct extraData *xx;
- xx = GetTrkExtraData(trk);
- xx->bezierData.arcSegs.cnt = 0;
- FixUpBezier(xx->bezierData.pos,xx,IsTrack(trk));
+ CHECK( trk != NULL && !IsTrackDeleted(trk) );
+ struct extraDataBezier_t *xx;
+ xx = GET_EXTRA_DATA(trk, T_NOTRACK, extraDataBezier_t);
+ DYNARR_RESET( trkSeg_t, xx->arcSegs );
+ FixUpBezier(xx->pos,xx,IsTrack(trk));
ComputeBezierBoundingBox(trk, xx);
return TRUE;
}
-BOOL_T MoveBezierEndPt ( track_p *trk, EPINX_T *ep, coOrd pos, DIST_T d0 ) {
+
+BOOL_T MoveBezierEndPt ( track_p *trk, EPINX_T *ep, coOrd pos, DIST_T d0 )
+{
track_p trk2;
- struct extraData *xx;
+ struct extraDataBezier_t *xx;
if (SplitTrack(*trk,pos,*ep,&trk2,TRUE)) {
if (trk2) {
UndrawNewTrack( trk2 );
DeleteTrack(trk2,TRUE);
}
UndrawNewTrack( *trk );
- xx = GetTrkExtraData(*trk);
- SetTrkEndPoint( *trk, *ep, *ep?xx->bezierData.pos[3]:xx->bezierData.pos[0], *ep?xx->bezierData.a1:xx->bezierData.a0 );
+ xx = GET_EXTRA_DATA(*trk, T_NOTRACK, extraDataBezier_t);
+ SetTrkEndPoint( *trk, *ep, *ep?xx->pos[3]:xx->pos[0], *ep?xx->a1:xx->a0 );
DrawNewTrack( *trk );
return TRUE;
}
@@ -1259,106 +1379,108 @@ BOOL_T MoveBezierEndPt ( track_p *trk, EPINX_T *ep, coOrd pos, DIST_T d0 ) {
static wBool_t CompareBezier( track_cp trk1, track_cp trk2 )
{
- struct extraData *xx1 = GetTrkExtraData( trk1 );
- struct extraData *xx2 = GetTrkExtraData( trk2 );
+ struct extraDataBezier_t *xx1 = GET_EXTRA_DATA( trk1, T_NOTRACK,
+ extraDataBezier_t );
+ struct extraDataBezier_t *xx2 = GET_EXTRA_DATA( trk2, T_NOTRACK,
+ extraDataBezier_t );
char * cp = message + strlen(message);
- REGRESS_CHECK_POS( "Pos[0]", xx1, xx2, bezierData.pos[0] )
- REGRESS_CHECK_POS( "Pos[1]", xx1, xx2, bezierData.pos[1] )
- REGRESS_CHECK_POS( "Pos[2]", xx1, xx2, bezierData.pos[2] )
- REGRESS_CHECK_POS( "Pos[3]", xx1, xx2, bezierData.pos[3] )
- REGRESS_CHECK_DIST( "MinCurveRadius", xx1, xx2, bezierData.minCurveRadius )
- REGRESS_CHECK_ANGLE( "A0", xx1, xx2, bezierData.a0 )
- REGRESS_CHECK_ANGLE( "A1", xx1, xx2, bezierData.a1 )
+ REGRESS_CHECK_POS( "Pos[0]", xx1, xx2, pos[0] )
+ REGRESS_CHECK_POS( "Pos[1]", xx1, xx2, pos[1] )
+ REGRESS_CHECK_POS( "Pos[2]", xx1, xx2, pos[2] )
+ REGRESS_CHECK_POS( "Pos[3]", xx1, xx2, pos[3] )
+ REGRESS_CHECK_DIST( "MinCurveRadius", xx1, xx2, minCurveRadius )
+ REGRESS_CHECK_ANGLE( "A0", xx1, xx2, a0 )
+ REGRESS_CHECK_ANGLE( "A1", xx1, xx2, a1 )
// Check arcSegs
- REGRESS_CHECK_DIST( "Length", xx1, xx2, bezierData.length )
- REGRESS_CHECK_POS( "DescOff", xx1, xx2, bezierData.descriptionOff )
- REGRESS_CHECK_WIDTH( "SegsWidth", xx1, xx2, bezierData.segsWidth )
- REGRESS_CHECK_COLOR( "SegsColor", xx1, xx2, bezierData.segsColor )
- REGRESS_CHECK_INT( "LineType", xx1, xx2, bezierData.lineType )
+ REGRESS_CHECK_DIST( "Length", xx1, xx2, length )
+ REGRESS_CHECK_POS( "DescOff", xx1, xx2, descriptionOff )
+ REGRESS_CHECK_WIDTH( "SegsLineWidth", xx1, xx2, segsLineWidth )
+ REGRESS_CHECK_COLOR( "SegsColor", xx1, xx2, segsColor )
+ REGRESS_CHECK_INT( "LineType", xx1, xx2, lineType )
return TRUE;
}
static trackCmd_t bezlinCmds = {
- "BZRLIN",
- DrawBezier,
- DistanceBezier,
- DescribeBezier,
- DeleteBezier,
- WriteBezier,
- ReadBezier,
- MoveBezier,
- RotateBezier,
- RescaleBezier,
- NULL,
- GetAngleBezier,
- SplitBezier,
- NULL,
- NULL,
- NULL, /* redraw */
- NULL, /* trim */
- MergeBezier,
- NULL, /* modify */
- GetLengthBezier,
- GetParamsBezier,
- NULL, /* Move EndPt */
- QueryBezier,
- NULL, /* ungroup */
- FlipBezier,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- RebuildBezier,
- NULL,
- NULL,
- NULL,
- CompareBezier
- };
+ "BZRLIN",
+ DrawBezier,
+ DistanceBezier,
+ DescribeBezier,
+ DeleteBezier,
+ WriteBezier,
+ ReadBezier,
+ MoveBezier,
+ RotateBezier,
+ RescaleBezier,
+ NULL,
+ GetAngleBezier,
+ SplitBezier,
+ NULL,
+ NULL,
+ NULL, /* redraw */
+ NULL, /* trim */
+ MergeBezier,
+ NULL, /* modify */
+ GetLengthBezier,
+ GetParamsBezier,
+ NULL, /* Move EndPt */
+ QueryBezier,
+ NULL, /* ungroup */
+ FlipBezier,
+ NULL,
+ NULL,
+ NULL,
+ MakeParallelBezier,
+ NULL,
+ RebuildBezier,
+ NULL,
+ NULL,
+ NULL,
+ CompareBezier
+};
static trackCmd_t bezierCmds = {
- "BEZIER",
- DrawBezier,
- DistanceBezier,
- DescribeBezier,
- DeleteBezier,
- WriteBezier,
- ReadBezier,
- MoveBezier,
- RotateBezier,
- RescaleBezier,
- NULL,
- GetAngleBezier,
- SplitBezier,
- TraverseBezier,
- EnumerateBezier,
- NULL, /* redraw */
- TrimBezier, /* trim */
- MergeBezier,
- NULL, /* modify */
- GetLengthBezier,
- GetParamsBezier,
- MoveBezierEndPt, /* Move EndPt */
- QueryBezier,
- NULL, /* ungroup */
- FlipBezier,
- NULL,
- NULL,
- NULL,
- MakeParallelBezier,
- NULL,
- RebuildBezier,
- NULL,
- NULL,
- NULL,
- CompareBezier
- };
+ "BEZIER",
+ DrawBezier,
+ DistanceBezier,
+ DescribeBezier,
+ DeleteBezier,
+ WriteBezier,
+ ReadBezier,
+ MoveBezier,
+ RotateBezier,
+ RescaleBezier,
+ NULL,
+ GetAngleBezier,
+ SplitBezier,
+ TraverseBezier,
+ EnumerateBezier,
+ NULL, /* redraw */
+ TrimBezier, /* trim */
+ MergeBezier,
+ NULL, /* modify */
+ GetLengthBezier,
+ GetParamsBezier,
+ MoveBezierEndPt, /* Move EndPt */
+ QueryBezier,
+ NULL, /* ungroup */
+ FlipBezier,
+ NULL,
+ NULL,
+ NULL,
+ MakeParallelBezier,
+ NULL,
+ RebuildBezier,
+ NULL,
+ NULL,
+ NULL,
+ CompareBezier
+};
EXPORT void BezierSegProc(
- segProc_e cmd,
- trkSeg_p segPtr,
- segProcData_p data )
+ segProc_e cmd,
+ trkSeg_p segPtr,
+ segProcData_p data )
{
ANGLE_T a1, a2;
DIST_T d, dd;
@@ -1370,7 +1492,7 @@ EXPORT void BezierSegProc(
BOOL_T back, segs_backwards, neg;
#define bezSegs(N) DYNARR_N( trkSeg_t, segPtr->bezSegs, N )
- switch (cmd) {
+ switch (cmd) {
case SEGPROC_TRAVERSE1: //Work out how much extra dist and what direction
if (segPtr->type != SEG_BEZTRK) {
@@ -1379,8 +1501,10 @@ EXPORT void BezierSegProc(
}
d = data->traverse1.dist;
p0 = data->traverse1.pos;
-LOG( log_bezierSegments, 1, ( " BezTr1-Enter P[%0.3f %0.3f] A%0.3f\n", p0.x, p0.y, data->traverse1.angle ))
- a2 = GetAngleSegs(segPtr->bezSegs.cnt,segPtr->bezSegs.ptr,&p0,&segInx,&d,&back, NULL, &neg); //Find right seg and pos
+ LOG( log_bezierSegments, 1, ( " BezTr1-Enter P[%0.3f %0.3f] A%0.3f\n", p0.x,
+ p0.y, data->traverse1.angle ))
+ a2 = GetAngleSegs(segPtr->bezSegs.cnt,&DYNARR_N(trkSeg_t,segPtr->bezSegs,0),&p0,
+ &segInx,&d,&back, NULL, &neg); //Find right seg and pos
inx = segInx;
data->traverse1.BezSegInx = segInx;
data->traverse1.reverse_seg = FALSE;
@@ -1390,33 +1514,44 @@ LOG( log_bezierSegments, 1, ( " BezTr1-Enter P[%0.3f %0.3f] A%0.3f\n", p0.x,
return;
}
- if (back) a2 = NormalizeAngle(a2+180);
- a1 = NormalizeAngle(a2-data->traverse1.angle); //Establish if we are going fwds or backwards globally
- if (a1<270 && a1>90) { //Must add 180 if the seg is reversed or inverted (but not both)
+ if (back) { a2 = NormalizeAngle(a2+180); }
+ a1 = NormalizeAngle(a2
+ -data->traverse1.angle); //Establish if we are going fwds or backwards globally
+ if (a1<270
+ && a1>90) { //Must add 180 if the seg is reversed or inverted (but not both)
segs_backwards = TRUE;
- } else {
+ } else {
segs_backwards = FALSE;
- }
+ }
if ( neg ) {
segs_backwards = !segs_backwards; //neg implies all the segs are reversed
}
- segProcData.traverse1.pos = data->traverse1.pos = p0; //actual point on curve
- segProcData.traverse1.angle = data->traverse1.angle; //Angle of car
- LOG( log_bezierSegments, 1, ( " BezTr1-GSA I%d P[%0.3f %0.3f] N%d SB%d\n", segInx, p0.x, p0.y, neg, segs_backwards ))
- subSegsPtr = (trkSeg_p)segPtr->bezSegs.ptr+inx;
+ segProcData.traverse1.pos = data->traverse1.pos = p0; //actual point on curve
+ segProcData.traverse1.angle = data->traverse1.angle; //Angle of car
+ LOG( log_bezierSegments, 1, ( " BezTr1-GSA I%d P[%0.3f %0.3f] N%d SB%d\n",
+ segInx, p0.x, p0.y, neg, segs_backwards ))
+ subSegsPtr = &DYNARR_N(trkSeg_t,segPtr->bezSegs,inx);
SegProc( SEGPROC_TRAVERSE1, subSegsPtr, &segProcData );
- data->traverse1.reverse_seg = segProcData.traverse1.reverse_seg; //which way is curve (info)
- data->traverse1.backwards = segProcData.traverse1.backwards; //Pass through Train direction
- data->traverse1.dist = segProcData.traverse1.dist; //Get last seg partial dist
+ data->traverse1.reverse_seg =
+ segProcData.traverse1.reverse_seg; //which way is curve (info)
+ data->traverse1.backwards =
+ segProcData.traverse1.backwards; //Pass through Train direction
+ data->traverse1.dist =
+ segProcData.traverse1.dist; //Get last seg partial dist
data->traverse1.segs_backwards = segs_backwards; //Get last
- data->traverse1.negative = segProcData.traverse1.negative; //Is curve flipped (info)
+ data->traverse1.negative =
+ segProcData.traverse1.negative; //Is curve flipped (info)
data->traverse1.BezSegInx = inx; //Copy up Index
-LOG( log_bezierSegments, 1, ( " BezTr1-Exit -> A%0.3f B%d R%d N%d D%0.3f\n", a2, segProcData.traverse1.backwards, segProcData.traverse1.reverse_seg, segProcData.traverse1.negative, segProcData.traverse1.dist ))
+ LOG( log_bezierSegments, 1, ( " BezTr1-Exit -> A%0.3f B%d R%d N%d D%0.3f\n",
+ a2, segProcData.traverse1.backwards, segProcData.traverse1.reverse_seg,
+ segProcData.traverse1.negative, segProcData.traverse1.dist ))
break;
case SEGPROC_TRAVERSE2:
- if (segPtr->type != SEG_BEZTRK) return; //Not SEG_BEZLIN
-LOG( log_bezierSegments, 1, ( " BezTr2-Enter D%0.3f SD%d SI%d SB%d\n", data->traverse2.dist, data->traverse2.segDir, data->traverse2.BezSegInx, data->traverse2.segs_backwards))
+ if (segPtr->type != SEG_BEZTRK) { return; } //Not SEG_BEZLIN
+ LOG( log_bezierSegments, 1, ( " BezTr2-Enter D%0.3f SD%d SI%d SB%d\n",
+ data->traverse2.dist, data->traverse2.segDir, data->traverse2.BezSegInx,
+ data->traverse2.segs_backwards))
segProcData.traverse2.pos = data->traverse2.pos;
DIST_T dist = data->traverse2.dist;
segProcData.traverse2.dist = data->traverse2.dist;
@@ -1426,24 +1561,26 @@ LOG( log_bezierSegments, 1, ( " BezTr2-Enter D%0.3f SD%d SI%d SB%d\n", data->
BOOL_T backwards = data->traverse2.segDir;
inx = data->traverse2.BezSegInx; //Special from Traverse1
while (inx>=0 && inx<segPtr->bezSegs.cnt) {
- subSegsPtr = (trkSeg_p)segPtr->bezSegs.ptr+inx;
+ subSegsPtr = &DYNARR_N(trkSeg_t,segPtr->bezSegs,inx);
SegProc(SEGPROC_TRAVERSE2, subSegsPtr, &segProcData);
if (segProcData.traverse2.dist<=0) { //Done
data->traverse2.angle = segProcData.traverse2.angle;
data->traverse2.dist = 0;
data->traverse2.pos = segProcData.traverse2.pos;
-LOG( log_bezierSegments, 1, ( " BezTr2-Exit1 -> A%0.3f P[%0.3f %0.3f] \n", data->traverse2.angle, data->traverse2.pos.x, data->traverse2.pos.y ))
+ LOG( log_bezierSegments, 1, ( " BezTr2-Exit1 -> A%0.3f P[%0.3f %0.3f] \n",
+ data->traverse2.angle, data->traverse2.pos.x, data->traverse2.pos.y ))
return;
- } else dist = segProcData.traverse2.dist;
+ } else { dist = segProcData.traverse2.dist; }
p2 = segProcData.traverse2.pos;
a2 = segProcData.traverse2.angle;
-LOG( log_bezierSegments, 2, ( " BezTr2-Tr2 D%0.3f P[%0.3f %0.3f] A%0.3f\n", dist, p2.x, p2.y, a2 ))
+ LOG( log_bezierSegments, 2, ( " BezTr2-Tr2 D%0.3f P[%0.3f %0.3f] A%0.3f\n",
+ dist, p2.x, p2.y, a2 ))
segProcData.traverse1.pos = p2;
segProcData.traverse1.angle = a2 ;
inx = segs_backwards?inx-1:inx+1;
- if (inx<0 || inx>=segPtr->bezSegs.cnt) break;
- subSegsPtr = (trkSeg_p)segPtr->bezSegs.ptr+inx;
+ if (inx<0 || inx>=segPtr->bezSegs.cnt) { break; }
+ subSegsPtr = &DYNARR_N(trkSeg_t,segPtr->bezSegs,inx);
SegProc(SEGPROC_TRAVERSE1, subSegsPtr, &segProcData);
BOOL_T reverse_seg = segProcData.traverse1.reverse_seg; //For Info only
backwards = segProcData.traverse1.backwards;
@@ -1453,31 +1590,36 @@ LOG( log_bezierSegments, 2, ( " BezTr2-Tr2 D%0.3f P[%0.3f %0.3f] A%0.3f\n", d
segProcData.traverse2.segDir = backwards; //which way
segProcData.traverse2.pos = p2;
segProcData.traverse2.angle = NormalizeAngle(a2 + neg_seg?180:0);
-LOG( log_bezierSegments, 2, ( " BezTr2-Loop A%0.3f P[%0.3f %0.3f] D%0.3f SI%d B%d RS%d\n", a2, p2.x, p2.y, dist, inx, backwards, reverse_seg ))
+ LOG( log_bezierSegments, 2,
+ ( " BezTr2-Loop A%0.3f P[%0.3f %0.3f] D%0.3f SI%d B%d RS%d\n", a2, p2.x,
+ p2.y, dist, inx, backwards, reverse_seg ))
}
data->traverse2.dist = dist;
- if (segs_backwards) {
- data->traverse2.pos = segPtr->u.b.pos[0]; // Backwards so point 0
- data->traverse2.angle = segPtr->u.b.angle0;
- } else {
- data->traverse2.pos = segPtr->u.b.pos[3]; // Forwards so point 3
- data->traverse2.angle = segPtr->u.b.angle3;
- }
-LOG( log_bezierSegments, 1, ( " BezTr-Exit2 --> SI%d A%0.3f P[%0.3f %0.3f] D%0.3f\n", inx, data->traverse2.angle, data->traverse2.pos.x, data->traverse2.pos.y, data->traverse2.dist))
+ if (segs_backwards) {
+ data->traverse2.pos = segPtr->u.b.pos[0]; // Backwards so point 0
+ data->traverse2.angle = segPtr->u.b.angle0;
+ } else {
+ data->traverse2.pos = segPtr->u.b.pos[3]; // Forwards so point 3
+ data->traverse2.angle = segPtr->u.b.angle3;
+ }
+ LOG( log_bezierSegments, 1,
+ ( " BezTr-Exit2 --> SI%d A%0.3f P[%0.3f %0.3f] D%0.3f\n", inx,
+ data->traverse2.angle, data->traverse2.pos.x, data->traverse2.pos.y,
+ data->traverse2.dist))
break;
case SEGPROC_DRAWROADBEDSIDE:
- //TODO - needs parallel bezier problem solved...
+ //TODO - needs parallel bezier problem solved...
break;
case SEGPROC_DISTANCE:
- dd = 100000.00; //Just find one distance
+ dd = DIST_INF; //Just find one distance
p0 = data->distance.pos1;
- //initialize p2
+ //initialize p2
p2 = segPtr->u.b.pos[0];
- for(int i=0;i<segPtr->bezSegs.cnt;i++) {
+ for(int i=0; i<segPtr->bezSegs.cnt; i++) {
segProcData.distance.pos1 = p0;
SegProc(SEGPROC_DISTANCE,&(DYNARR_N(trkSeg_t,segPtr->bezSegs,i)),&segProcData);
d = segProcData.distance.dd;
@@ -1492,9 +1634,9 @@ LOG( log_bezierSegments, 1, ( " BezTr-Exit2 --> SI%d A%0.3f P[%0.3f %0.3f] D%
case SEGPROC_FLIP:
- temp0 = segPtr->u.b.pos[0];
- temp1 = segPtr->u.b.pos[1];
- temp2 = segPtr->u.b.pos[2];
+ temp0 = segPtr->u.b.pos[0];
+ temp1 = segPtr->u.b.pos[1];
+ temp2 = segPtr->u.b.pos[2];
temp3 = segPtr->u.b.pos[3];
segPtr->u.b.pos[0] = temp3;
segPtr->u.b.pos[1] = temp2;
@@ -1504,45 +1646,47 @@ LOG( log_bezierSegments, 1, ( " BezTr-Exit2 --> SI%d A%0.3f P[%0.3f %0.3f] D%
break;
case SEGPROC_NEWTRACK:
- data->newTrack.trk = NewBezierTrack( segPtr->u.b.pos, (trkSeg_t *)segPtr->bezSegs.ptr, segPtr->bezSegs.cnt);
+ data->newTrack.trk = NewBezierTrack( segPtr->u.b.pos,
+ &DYNARR_N(trkSeg_t,segPtr->bezSegs,0), segPtr->bezSegs.cnt);
data->newTrack.ep[0] = 0;
data->newTrack.ep[1] = 1;
break;
case SEGPROC_LENGTH:
data->length.length = 0;
- for(int i=0;i<segPtr->bezSegs.cnt;i++) {
+ for(int i=0; i<segPtr->bezSegs.cnt; i++) {
SegProc(cmd,&(DYNARR_N(trkSeg_t,segPtr->bezSegs,i)),&segProcData);
data->length.length += segProcData.length.length;
}
break;
case SEGPROC_SPLIT: ;
- wIndex_t subinx;
+// wIndex_t subinx;
double t;
- double dd;
+// double dd;
coOrd split_p = data->split.pos;
- ANGLE_T angle = GetAngleSegs(segPtr->bezSegs.cnt,(trkSeg_p)segPtr->bezSegs.ptr, &split_p, &inx, &dd, &back, &subinx, NULL);
- coOrd current[4];
+// ANGLE_T angle = GetAngleSegs(segPtr->bezSegs.cnt,&DYNARR_N(trkSeg_t,segPtr->bezSegs,0), &split_p, &inx, &dd, &back, &subinx, NULL);
+// coOrd current[4];
BezierMathDistance(&split_p, segPtr->u.b.pos, 500, &t); //Find t value
- for (int i=0;i<4;i++) {
- current[i] = segPtr->u.b.pos[i];
+// for (int i=0;i<4;i++) {
+// current[i] = segPtr->u.b.pos[i];
- }
- for (int i=0;i<2;i++) {
+// }
+ for (int i=0; i<2; i++) {
data->split.newSeg[i].type = segPtr->type;
data->split.newSeg[i].color = segPtr->color;
- data->split.newSeg[i].width = segPtr->width;
- data->split.newSeg[i].bezSegs.ptr = NULL;
- data->split.newSeg[i].bezSegs.cnt = 0;
- data->split.newSeg[i].bezSegs.max = 0;
+ data->split.newSeg[i].lineWidth = segPtr->lineWidth;
+ DYNARR_INIT( trkSeg_t, data->split.newSeg[i].bezSegs );
}
- BezierSplit(segPtr->u.b.pos, data->split.newSeg[0].u.b.pos, data->split.newSeg[1].u.b.pos, t);
+ BezierSplit(segPtr->u.b.pos, data->split.newSeg[0].u.b.pos,
+ data->split.newSeg[1].u.b.pos, t);
- FixUpBezierSeg(data->split.newSeg[0].u.b.pos,&data->split.newSeg[0],segPtr->type == SEG_BEZTRK);
- FixUpBezierSeg(data->split.newSeg[1].u.b.pos,&data->split.newSeg[1],segPtr->type == SEG_BEZTRK);
+ FixUpBezierSeg(data->split.newSeg[0].u.b.pos,&data->split.newSeg[0],
+ segPtr->type == SEG_BEZTRK);
+ FixUpBezierSeg(data->split.newSeg[1].u.b.pos,&data->split.newSeg[1],
+ segPtr->type == SEG_BEZTRK);
data->split.length[0] = data->split.newSeg[0].u.b.length;
data->split.length[1] = data->split.newSeg[1].u.b.length;
@@ -1554,11 +1698,12 @@ LOG( log_bezierSegments, 1, ( " BezTr-Exit2 --> SI%d A%0.3f P[%0.3f %0.3f] D%
case SEGPROC_GETANGLE:
inx = 0;
back = FALSE;
- subSegsPtr = (trkSeg_p) segPtr->bezSegs.ptr;
+ subSegsPtr = &DYNARR_N(trkSeg_t,segPtr->bezSegs,0);
coOrd pos = data->getAngle.pos;
-LOG( log_bezierSegments, 1, ( " BezGA-In P[%0.3f %0.3f] \n", pos.x, pos.y))
- data->getAngle.angle = GetAngleSegs(segPtr->bezSegs.cnt,subSegsPtr, &pos, &inx, NULL, &back, NULL, NULL);
- //Recurse for Bezier sub-segs (only straights and curves)
+ LOG( log_bezierSegments, 1, ( " BezGA-In P[%0.3f %0.3f] \n", pos.x, pos.y))
+ data->getAngle.angle = GetAngleSegs(segPtr->bezSegs.cnt,subSegsPtr, &pos, &inx,
+ NULL, &back, NULL, NULL);
+ //Recurse for Bezier sub-segs (only straights and curves)
data->getAngle.negative_radius = FALSE;
data->getAngle.backwards = back;
@@ -1567,13 +1712,13 @@ LOG( log_bezierSegments, 1, ( " BezGA-In P[%0.3f %0.3f] \n", pos.x, pos.y))
subSegsPtr +=inx;
if (subSegsPtr->type == SEG_CRVTRK || subSegsPtr->type == SEG_CRVLIN ) {
data->getAngle.radius = fabs(subSegsPtr->u.c.radius);
- if (subSegsPtr->u.c.radius<0 ) data->getAngle.negative_radius = TRUE;
+ if (subSegsPtr->u.c.radius<0 ) { data->getAngle.negative_radius = TRUE; }
data->getAngle.center = subSegsPtr->u.c.center;
- }
- else data->getAngle.radius = 0.0;
-LOG( log_bezierSegments, 1, ( " BezGA-Out SI%d A%0.3f P[%0.3f %0.3f] B%d\n", inx, data->getAngle.angle, pos.x, pos.y, back))
+ } else { data->getAngle.radius = 0.0; }
+ LOG( log_bezierSegments, 1, ( " BezGA-Out SI%d A%0.3f P[%0.3f %0.3f] B%d\n",
+ inx, data->getAngle.angle, pos.x, pos.y, back))
break;
-
+
}
}
@@ -1586,43 +1731,54 @@ LOG( log_bezierSegments, 1, ( " BezGA-Out SI%d A%0.3f P[%0.3f %0.3f] B%d\n",
*/
+EXPORT void SetBezierData( track_p p, coOrd pos[4], wDrawColor color,
+ LWIDTH_T lineWidth )
+{
+ BOOL_T bTrack = (GetTrkType(p) == T_BEZIER);
+ struct extraDataBezier_t *xx = GET_EXTRA_DATA(p, T_NOTRACK, extraDataBezier_t);
+ xx->pos[0] = pos[0];
+ xx->pos[1] = pos[1];
+ xx->pos[2] = pos[2];
+ xx->pos[3] = pos[3];
+ xx->a0 = FindAngle(pos[1],pos[0]);
+ xx->a1 = FindAngle(pos[2],pos[3]);
+ xx->segsColor = color;
+ xx->segsLineWidth = lineWidth;
+ FixUpBezier(pos, xx, bTrack);
+ ComputeBezierBoundingBox( p, xx );
+ if ( bTrack ) {
+ SetTrkEndPointSilent( p, 0, pos[0], xx->a0 );
+ SetTrkEndPointSilent( p, 1, pos[3], xx->a1 );
+ CheckTrackLength( p );
+ SetTrkBits( p, TB_HIDEDESC );
+ }
+}
+
+
track_p NewBezierTrack(coOrd pos[4], trkSeg_t * tempsegs, int count)
{
- struct extraData *xx;
track_p p;
- p = NewTrack( 0, T_BEZIER, 2, sizeof *xx );
- xx = GetTrkExtraData(p);
- xx->bezierData.pos[0] = pos[0];
- xx->bezierData.pos[1] = pos[1];
- xx->bezierData.pos[2] = pos[2];
- xx->bezierData.pos[3] = pos[3];
- xx->bezierData.segsColor = wDrawColorBlack;
- xx->bezierData.segsWidth = 0;
- FixUpBezier(pos, xx, TRUE);
-LOG( log_bezier, 1, ( "NewBezierTrack( EP1 %0.3f, %0.3f, CP1 %0.3f, %0.3f, CP2 %0.3f, %0.3f, EP2 %0.3f, %0.3f ) = %d\n", pos[0].x, pos[0].y, pos[1].x, pos[1].y, pos[2].x, pos[2].y, pos[3].x, pos[3].y, GetTrkIndex(p) ) )
- ComputeBezierBoundingBox( p, xx );
- SetTrkEndPoint( p, 0, pos[0], xx->bezierData.a0);
- SetTrkEndPoint( p, 1, pos[3], xx->bezierData.a1);
- CheckTrackLength( p );
- SetTrkBits( p, TB_HIDEDESC );
+ p = NewTrack( 0, T_BEZIER, 2, sizeof *(extraDataBezier_t*)NULL );
+ SetBezierData( p, pos, wDrawColorBlack, 0 );
+ LOG( log_bezier, 1,
+ ( "NewBezierTrack( EP1 %0.3f, %0.3f, CP1 %0.3f, %0.3f, CP2 %0.3f, %0.3f, EP2 %0.3f, %0.3f ) = %d\n",
+ pos[0].x, pos[0].y, pos[1].x, pos[1].y, pos[2].x, pos[2].y, pos[3].x, pos[3].y,
+ GetTrkIndex(p) ) )
return p;
}
-EXPORT track_p NewBezierLine( coOrd pos[4], trkSeg_t * tempsegs, int count, wDrawColor color, DIST_T width )
+
+EXPORT track_p NewBezierLine( coOrd pos[4], trkSeg_t * tempsegs, int count,
+ wDrawColor color, LWIDTH_T lineWidth )
{
- struct extraData *xx;
track_p p;
- p = NewTrack( 0, T_BZRLIN, 2, sizeof *xx );
- xx = GetTrkExtraData(p);
- xx->bezierData.pos[0] = pos[0];
- xx->bezierData.pos[1] = pos[1];
- xx->bezierData.pos[2] = pos[2];
- xx->bezierData.pos[3] = pos[3];
- xx->bezierData.segsColor = color;
- xx->bezierData.segsWidth = width;
- FixUpBezier(pos, xx, FALSE);
-LOG( log_bezier, 1, ( "NewBezierLine( EP1 %0.3f, %0.3f, CP1 %0.3f, %0.3f, CP2 %0.3f, %0.3f, EP2 %0.3f, %0.3f) = %d\n", pos[0].x, pos[0].y, pos[1].x, pos[1].y, pos[2].x, pos[2].y, pos[3].x, pos[3].y, GetTrkIndex(p) ) )
- ComputeBezierBoundingBox( p, xx );
+ p = NewTrack( 0, T_BZRLIN, 0,
+ sizeof *(extraDataBezier_t*)NULL ); //No endpoints
+ SetBezierData( p, pos, color, lineWidth );
+ LOG( log_bezier, 1,
+ ( "NewBezierLine( EP1 %0.3f, %0.3f, CP1 %0.3f, %0.3f, CP2 %0.3f, %0.3f, EP2 %0.3f, %0.3f) = %d\n",
+ pos[0].x, pos[0].y, pos[1].x, pos[1].y, pos[2].x, pos[2].y, pos[3].x, pos[3].y,
+ GetTrkIndex(p) ) )
return p;
}
@@ -1647,102 +1803,107 @@ EXPORT void InitTrkBezier( void )
/**
* Return point on Bezier using "t" (from 0 to 1)
*/
-extern coOrd BezierPointByParameter(coOrd p[4], double t)
+static coOrd BezierPointByParameter(coOrd p[4], double t)
{
- double a,b,c,d;
- double mt = 1-t;
- double mt2 = mt*mt;
- double t2 = t*t;
+ double a,b,c,d;
+ double mt = 1-t;
+ double mt2 = mt*mt;
+ double t2 = t*t;
- a = mt2*mt;
- b = mt2*t*3;
- c = mt*t2*3;
- d = t*t2;
+ a = mt2*mt;
+ b = mt2*t*3;
+ c = mt*t2*3;
+ d = t*t2;
- coOrd o;
- o.x = a*p[0].x+b*p[1].x+c*p[2].x+d*p[3].x;
- o.y = a*p[0].y+b*p[1].y+c*p[2].y+d*p[3].y;
+ coOrd o;
+ o.x = a*p[0].x+b*p[1].x+c*p[2].x+d*p[3].x;
+ o.y = a*p[0].y+b*p[1].y+c*p[2].y+d*p[3].y;
- return o;
+ return o;
}
/**
* Find distance from point to Bezier. Return also the "t" value of that closest point.
*/
-extern DIST_T BezierMathDistance( coOrd * pos, coOrd p[4], int segments, double * t_value)
+static DIST_T BezierMathDistance( coOrd * pos, coOrd p[4], int segments,
+ double * t_value)
{
- DIST_T dd = 10000.0;
- double t = 0.0;
- coOrd pt;
- coOrd save_pt = p[0];
- for (int i=0; i<=segments; i++) {
- pt = BezierPointByParameter(p, (double)i/segments);
- if (FindDistance(*pos,pt) < dd) {
- dd = FindDistance(*pos,pt);
- t = (double)i/segments;
- save_pt = pt;
- }
- }
- if (t_value) *t_value = t;
- * pos = save_pt;
- return dd;
+ DIST_T dd = DIST_INF;
+ double t = 0.0;
+ coOrd pt;
+ coOrd save_pt = p[0];
+ for (int i=0; i<=segments; i++) {
+ pt = BezierPointByParameter(p, (double)i/segments);
+ if (FindDistance(*pos,pt) < dd) {
+ dd = FindDistance(*pos,pt);
+ t = (double)i/segments;
+ save_pt = pt;
+ }
+ }
+ if (t_value) { *t_value = t; }
+ * pos = save_pt;
+ return dd;
}
-extern coOrd BezierMathFindNearestPoint(coOrd *pos, coOrd p[4], int segments) {
- double t = 0.0;
- BezierMathDistance(pos, p, segments, &t);
- return BezierPointByParameter(p, t);
+static coOrd BezierMathFindNearestPoint(coOrd *pos, coOrd p[4], int segments)
+{
+ double t = 0.0;
+ BezierMathDistance(pos, p, segments, &t);
+ return BezierPointByParameter(p, t);
}
-void BezierSlice(coOrd input[], coOrd output[], double t) {
+void BezierSlice(coOrd input[], coOrd output[], double t)
+{
coOrd p1,p12,p2,p23,p3,p34,p4;
coOrd p123, p234, p1234;
- p1 = input[0];
- p2 = input[1];
- p3 = input[2];
- p4 = input[3];
+ p1 = input[0];
+ p2 = input[1];
+ p3 = input[2];
+ p4 = input[3];
- p12.x = (p2.x-p1.x)*t+p1.x;
- p12.y = (p2.y-p1.y)*t+p1.y;
+ p12.x = (p2.x-p1.x)*t+p1.x;
+ p12.y = (p2.y-p1.y)*t+p1.y;
- p23.x = (p3.x-p2.x)*t+p2.x;
- p23.y = (p3.y-p2.y)*t+p2.y;
+ p23.x = (p3.x-p2.x)*t+p2.x;
+ p23.y = (p3.y-p2.y)*t+p2.y;
- p34.x = (p4.x-p3.x)*t+p3.x;
- p34.y = (p4.y-p3.y)*t+p3.y;
+ p34.x = (p4.x-p3.x)*t+p3.x;
+ p34.y = (p4.y-p3.y)*t+p3.y;
- p123.x = (p23.x-p12.x)*t+p12.x;
- p123.y = (p23.y-p12.y)*t+p12.y;
+ p123.x = (p23.x-p12.x)*t+p12.x;
+ p123.y = (p23.y-p12.y)*t+p12.y;
- p234.x = (p34.x-p23.x)*t+p23.x;
- p234.y = (p34.y-p23.y)*t+p23.y;
+ p234.x = (p34.x-p23.x)*t+p23.x;
+ p234.y = (p34.y-p23.y)*t+p23.y;
- p1234.x = (p234.x-p123.x)*t+p123.x;
- p1234.y = (p234.y-p123.y)*t+p123.y;
+ p1234.x = (p234.x-p123.x)*t+p123.x;
+ p1234.y = (p234.y-p123.y)*t+p123.y;
- output[0]= p1;
- output[1] = p12;
- output[2] = p123;
- output[3] = p1234;
+ output[0]= p1;
+ output[1] = p12;
+ output[2] = p123;
+ output[3] = p1234;
};
/**
* Split bezier into two parts
*/
-extern void BezierSplit(coOrd input[], coOrd left[], coOrd right[] , double t) {
+static void BezierSplit(coOrd input[4], coOrd left[4], coOrd right[4],
+ double t)
+{
BezierSlice(input,left,t);
coOrd back[4],backright[4];
- for (int i = 0;i<4;i++) {
+ for (int i = 0; i<4; i++) {
back[i] = input[3-i];
}
BezierSlice(back,backright,1-t);
- for (int i = 0;i<4;i++) {
+ for (int i = 0; i<4; i++) {
right[i] = backright[3-i];
}
@@ -1753,23 +1914,26 @@ extern void BezierSplit(coOrd input[], coOrd left[], coOrd right[] , double t) {
* If close enough (length of control polygon exceeds chord by < error) add length of polygon.
* Else split and recurse
*/
-double BezierAddLengthIfClose(coOrd start[4], double error) {
- coOrd left[4], right[4]; /* bez poly splits */
- double len = 0.0; /* arc length */
- double chord; /* chord length */
- int index; /* misc counter */
-
- for (index = 0; index <= 2; index++)
- len = len + FindDistance(start[index],start[index+1]); //add up control polygon
+double BezierAddLengthIfClose(coOrd start[4], double error)
+{
+ coOrd left[4], right[4]; /* bez poly splits */
+ double len = 0.0; /* arc length */
+ double chord; /* chord length */
+ int index; /* misc counter */
+
+ for (index = 0; index <= 2; index++) {
+ len = len + FindDistance(start[index],
+ start[index+1]); //add up control polygon
+ }
- chord = FindDistance(start[0],start[3]); //find chord length
+ chord = FindDistance(start[0],start[3]); //find chord length
- if((len-chord) > error) { // If error too large -
- BezierSplit(start,left,right,0.5); /* split in two */
- len = BezierAddLengthIfClose(left, error); /* recurse left side */
- len += BezierAddLengthIfClose(right, error); /* recurse right side */
- }
- return len; // Add length of this curve
+ if((len-chord) > error) { // If error too large -
+ BezierSplit(start,left,right,0.5); /* split in two */
+ len = BezierAddLengthIfClose(left, error); /* recurse left side */
+ len += BezierAddLengthIfClose(right, error); /* recurse right side */
+ }
+ return len; // Add length of this curve
}
@@ -1777,30 +1941,30 @@ double BezierAddLengthIfClose(coOrd start[4], double error) {
* Use recursive splitting to get close approximation ot length of bezier
*
*/
-extern double BezierMathLength(coOrd p[4], double error)
+static double BezierMathLength(coOrd p[4], double error)
{
- if (error == 0.0) error = 0.01;
- return BezierAddLengthIfClose(p, error); /* kick off recursion */
+ if (error == 0.0) { error = 0.01; }
+ return BezierAddLengthIfClose(p, error); /* kick off recursion */
}
coOrd BezierFirstDerivative(coOrd p[4], double t)
{
- //checkParameterT(t);
+ //checkParameterT(t);
- double tSquared = t * t;
- double s0 = -3 + 6 * t - 3 * tSquared;
- double s1 = 3 - 12 * t + 9 * tSquared;
- double s2 = 6 * t - 9 * tSquared;
- double s3 = 3 * tSquared;
- double resultX = p[0].x * s0 + p[1].x * s1 + p[2].x * s2 + p[3].x * s3;
- double resultY = p[0].y * s0 + p[1].y * s1 + p[2].y * s2 + p[3].y * s3;
+ double tSquared = t * t;
+ double s0 = -3 + 6 * t - 3 * tSquared;
+ double s1 = 3 - 12 * t + 9 * tSquared;
+ double s2 = 6 * t - 9 * tSquared;
+ double s3 = 3 * tSquared;
+ double resultX = p[0].x * s0 + p[1].x * s1 + p[2].x * s2 + p[3].x * s3;
+ double resultY = p[0].y * s0 + p[1].y * s1 + p[2].y * s2 + p[3].y * s3;
- coOrd v;
+ coOrd v;
- v.x = resultX;
- v.y = resultY;
- return v;
+ v.x = resultX;
+ v.y = resultY;
+ return v;
}
/**
@@ -1809,61 +1973,63 @@ coOrd BezierFirstDerivative(coOrd p[4], double t)
*/
coOrd BezierSecondDerivative(coOrd p[4], double t)
{
- //checkParameterT(t);
-
- double s0 = 6 - 6 * t;
- double s1 = -12 + 18 * t;
- double s2 = 6 - 18 * t;
- double s3 = 6 * t;
- double resultX = p[0].x * s0 + p[1].x * s1 + p[2].x * s2 + p[3].x * s3;
- double resultY = p[0].y * s0 + p[1].y * s1 + p[2].y * s2 + p[3].y * s3;
-
- coOrd v;
- v.x = resultX;
- v.y = resultY;
- return v;
+ //checkParameterT(t);
+
+ double s0 = 6 - 6 * t;
+ double s1 = -12 + 18 * t;
+ double s2 = 6 - 18 * t;
+ double s3 = 6 * t;
+ double resultX = p[0].x * s0 + p[1].x * s1 + p[2].x * s2 + p[3].x * s3;
+ double resultY = p[0].y * s0 + p[1].y * s1 + p[2].y * s2 + p[3].y * s3;
+
+ coOrd v;
+ v.x = resultX;
+ v.y = resultY;
+ return v;
}
/**
* Get curvature of a Bezier at a point
*/
-extern double BezierCurvature(coOrd p[4], double t, coOrd * center)
+static double BezierCurvature(coOrd p[4], double t, coOrd * center)
{
- //checkParameterT(t);
+ //checkParameterT(t);
- coOrd d1 = BezierFirstDerivative(p, t);
- coOrd d2 = BezierSecondDerivative(p, t);
+ coOrd d1 = BezierFirstDerivative(p, t);
+ coOrd d2 = BezierSecondDerivative(p, t);
- if (center) {
- double curvnorm = (d1.x * d1.x + d1.y* d1.y)/(d1.x * d2.y - d2.x * d1.y);
- coOrd p = BezierPointByParameter(&p, t);
- center->x = p.x-d1.y*curvnorm;
- center->y = p.y+d1.x*curvnorm;
- }
+ if (center) {
+ double curvnorm = (d1.x * d1.x + d1.y* d1.y)/(d1.x * d2.y - d2.x * d1.y);
+ coOrd p1 = BezierPointByParameter(p, t);
+ center->x = p1.x-d1.y*curvnorm;
+ center->y = p1.y+d1.x*curvnorm;
+ }
- double r1 = sqrt(pow(d1.x * d1.x + d1.y* d1.y, 3.0));
- double r2 = fabs(d1.x * d2.y - d2.x * d1.y);
- return r2 / r1;
+ double r1 = sqrt(pow(d1.x * d1.x + d1.y* d1.y, 3.0));
+ double r2 = fabs(d1.x * d2.y - d2.x * d1.y);
+ return r2 / r1;
}
/**
* Get Maximum Curvature
*/
-extern double BezierMaxCurve(coOrd p[4]) {
- double max = 0;
- for (int t = 0;t<100;t++) {
- double curv = BezierCurvature(p, t/100, NULL);
- if (max<curv) max = curv;
- }
- return max;
+static double BezierMaxCurve(coOrd p[4])
+{
+ double max = 0;
+ for (int t = 0; t<100; t++) {
+ double curv = BezierCurvature(p, t/100, NULL);
+ if (max<curv) { max = curv; }
+ }
+ return max;
}
/**
* Get Minimum Radius
*/
-extern double BezierMathMinRadius(coOrd p[4]) {
- double curv = BezierMaxCurve(p);
- if (curv >= 1000.0 || curv <= 0.001 ) return 0.0;
- return 1/curv;
+static double BezierMathMinRadius(coOrd p[4])
+{
+ double curv = BezierMaxCurve(p);
+ if (curv >= 1000.0 || curv <= 0.001 ) { return 0.0; }
+ return 1/curv;
}