diff options
Diffstat (limited to 'app/bin/tcornu.c')
-rw-r--r-- | app/bin/tcornu.c | 377 |
1 files changed, 287 insertions, 90 deletions
diff --git a/app/bin/tcornu.c b/app/bin/tcornu.c index 74a7a5e..dd09cfa 100644 --- a/app/bin/tcornu.c +++ b/app/bin/tcornu.c @@ -136,8 +136,8 @@ EXPORT char * CreateSegPathList(track_p trk) { char * cp = "\0\0"; if (GetTrkType(trk) != T_CORNU) return cp; struct extraData *xx = GetTrkExtraData(trk); - if (xx->cornuData.cornuPath) free(xx->cornuData.cornuPath); - xx->cornuData.cornuPath = malloc(xx->cornuData.arcSegs.cnt+2); + if (xx->cornuData.cornuPath) MyFree(xx->cornuData.cornuPath); + xx->cornuData.cornuPath = MyMalloc(xx->cornuData.arcSegs.cnt+2); int j= 0; for (int i = 0;i<xx->cornuData.arcSegs.cnt;i++,j++) { xx->cornuData.cornuPath[j] = i+1; @@ -178,17 +178,24 @@ static void ComputeCornuBoundingBox( track_p trk, struct extraData * xx ) DIST_T CornuDescriptionDistance( coOrd pos, - track_p trk ) + track_p trk, + coOrd * dpos, + BOOL_T show_hidden, + BOOL_T * hidden) { struct extraData *xx = GetTrkExtraData(trk); coOrd p1; - - if ( GetTrkType( trk ) != T_CORNU || ( GetTrkBits( trk ) & TB_HIDEDESC ) != 0 ) + if (hidden) *hidden = FALSE; + if ( GetTrkType( trk ) != T_CORNU || ((( GetTrkBits( trk ) & TB_HIDEDESC ) != 0) && !show_hidden) ) return 100000; - p1.x = xx->cornuData.pos[0].x + ((xx->cornuData.pos[1].x-xx->cornuData.pos[0].x)/2) + xx->cornuData.descriptionOff.x; - p1.y = xx->cornuData.pos[0].y + ((xx->cornuData.pos[1].y-xx->cornuData.pos[0].y)/2) + xx->cornuData.descriptionOff.y; - + coOrd offset = xx->cornuData.descriptionOff; + + if (( GetTrkBits( trk ) & TB_HIDEDESC ) != 0) offset = zero; + p1.x = xx->cornuData.pos[0].x + ((xx->cornuData.pos[1].x-xx->cornuData.pos[0].x)/2) + offset.x; + p1.y = xx->cornuData.pos[0].y + ((xx->cornuData.pos[1].y-xx->cornuData.pos[0].y)/2) + offset.y; + if (hidden) *hidden = (GetTrkBits( trk ) & TB_HIDEDESC); + *dpos = p1; return FindDistance( p1, pos ); } @@ -211,8 +218,9 @@ static void DrawCornuDescription( pos.x += xx->cornuData.descriptionOff.x; pos.y += xx->cornuData.descriptionOff.y; fp = wStandardFont( F_TIMES, FALSE, FALSE ); - sprintf( message, _("Cornu Curve: length=%0.3f min radius=%0.3f"), - xx->cornuData.length, xx->cornuData.minCurveRadius); + + sprintf( message, _("Cornu: len=%0.2f min_rad=%0.2f"), + xx->cornuData.length, (xx->cornuData.minCurveRadius>=10000.00)?0.0:xx->cornuData.minCurveRadius); DrawBoxedString( BOX_BOX, d, pos, message, fp, (wFontSize_t)descriptionFontSize, color, 0.0 ); } @@ -225,7 +233,6 @@ STATUS_T CornuDescriptionMove( struct extraData *xx = GetTrkExtraData(trk); static coOrd p0,p1; static BOOL_T editState; - wDrawColor color; if (GetTrkType(trk) != T_CORNU) return C_TERMINATE; @@ -234,24 +241,25 @@ STATUS_T CornuDescriptionMove( switch (action) { case C_DOWN: + DrawCornuDescription( trk, &mainD, wDrawColorWhite ); case C_MOVE: case C_UP: editState = TRUE; p1 = pos; - color = GetTrkColor( trk, &mainD ); xx->cornuData.descriptionOff.x = pos.x - p0.x; xx->cornuData.descriptionOff.y = pos.y - p0.y; - DrawCornuDescription( trk, &mainD, color ); if (action == C_UP) { editState = FALSE; + wDrawColor color = GetTrkColor( trk, &mainD ); + DrawCornuDescription( trk, &mainD, color ); } - MainRedraw(); - MapRedraw(); return action==C_UP?C_TERMINATE:C_CONTINUE; case C_REDRAW: - if (editState) - DrawLine( &mainD, p1, p0, 0, wDrawColorBlack ); + if (editState) { + DrawCornuDescription( trk, &tempD, wDrawColorBlue ); + DrawLine( &tempD, p1, p0, 0, wDrawColorBlue ); + } break; } @@ -365,18 +373,20 @@ static void UpdateCornu( track_p trk, int inx, descData_p descUpd, BOOL_T final case R0: if (GetTrkEndTrk(trk,0)) break; updateEndPts = TRUE; - xx->cornuData.r[0] = cornData.radius[0]; - Translate(&xx->cornuData.c[0],xx->cornuData.pos[0],NormalizeAngle(xx->cornuData.a[0]+90),xx->cornuData.r[0]); + xx->cornuData.r[0] = fabs(cornData.radius[0]); + Translate(&xx->cornuData.c[0],xx->cornuData.pos[0],NormalizeAngle(xx->cornuData.a[0]+90),cornData.radius[0]); cornData.center[0] = xx->cornuData.c[0]; + cornData.radius[0] = fabs(cornData.radius[0]); cornuDesc[R0].mode |= DESC_CHANGE; cornuDesc[C0].mode |= DESC_CHANGE; break; case R1: if (GetTrkEndTrk(trk,1)) break; updateEndPts = TRUE; - xx->cornuData.r[1]= cornData.radius[1]; - Translate(&xx->cornuData.c[1],xx->cornuData.pos[1],NormalizeAngle(xx->cornuData.a[1]-90),xx->cornuData.r[1]); + xx->cornuData.r[1]= fabs(cornData.radius[1]); + Translate(&xx->cornuData.c[1],xx->cornuData.pos[1],NormalizeAngle(xx->cornuData.a[1]-90),cornData.radius[1]); cornData.center[1] = xx->cornuData.c[1]; + cornData.radius[1] = fabs(cornData.radius[1]); cornuDesc[R1].mode |= DESC_CHANGE; cornuDesc[C1].mode |= DESC_CHANGE; break; @@ -384,7 +394,7 @@ static void UpdateCornu( track_p trk, int inx, descData_p descUpd, BOOL_T final case Z1: ep = (inx==Z0?0:1); UpdateTrkEndElev( trk, ep, GetTrkEndElevUnmaskedMode(trk,ep), cornData.elev[ep], NULL ); - ComputeElev( trk, 1-ep, FALSE, &cornData.elev[1-ep], NULL ); + ComputeElev( trk, 1-ep, FALSE, &cornData.elev[1-ep], NULL, TRUE ); if ( cornData.length > minLength ) cornData.grade = fabs( (cornData.elev[0]-cornData.elev[1])/cornData.length )*100.0; else @@ -417,7 +427,7 @@ static void UpdateCornu( track_p trk, int inx, descData_p descUpd, BOOL_T final ts[0] = GetTrkEndTrk(trk,0); ts[1] = GetTrkEndTrk(trk,1); SetUpCornuParmFromTracks(ts,&cp,xx); - CallCornu(xx->cornuData.pos, tracks, NULL, &xx->cornuData.arcSegs, &cp); + CallCornu0(xx->cornuData.pos, xx->cornuData.c, xx->cornuData.a, xx->cornuData.r, &xx->cornuData.arcSegs, FALSE); //FixUpCornu(xx->bezierData.pos, xx, IsTrack(trk)); ComputeCornuBoundingBox(trk, xx); @@ -454,8 +464,8 @@ static void DescribeCornu( track_p trk, char * str, CSIZE_T len ) cornData.radius[0] = xx->cornuData.r[0]; cornData.radius[1] = xx->cornuData.r[1]; if (GetTrkType(trk) == T_CORNU) { - ComputeElev( trk, 0, FALSE, &cornData.elev[0], NULL ); - ComputeElev( trk, 1, FALSE, &cornData.elev[1], NULL ); + ComputeElev( trk, 0, FALSE, &cornData.elev[0], NULL, FALSE ); + ComputeElev( trk, 1, FALSE, &cornData.elev[1], NULL, FALSE ); if ( cornData.length > minLength ) cornData.grade = fabs( (cornData.elev[0]-cornData.elev[1])/cornData.length )*100.0; @@ -517,30 +527,16 @@ static void DrawCornu( track_p t, drawCmd_p d, wDrawColor color ) struct extraData *xx = GetTrkExtraData(t); long widthOptions = DTS_LEFT|DTS_RIGHT; - if (GetTrkWidth(t) == 2) - widthOptions |= DTS_THICK2; - if (GetTrkWidth(t) == 3) - widthOptions |= DTS_THICK3; - - - if ( ((d->funcs->options&wDrawOptTemp)==0) && + if ( ((d->options&DC_SIMPLE)==0) && (labelWhen == 2 || (labelWhen == 1 && (d->options&DC_PRINT))) && labelScale >= d->scale && ( GetTrkBits( t ) & TB_HIDEDESC ) == 0 ) { DrawCornuDescription( t, d, color ); } DIST_T scale2rail = (d->options&DC_PRINT)?(twoRailScale*2+1):twoRailScale; - if ( tieDrawMode!=TIEDRAWMODE_NONE && - d!=&mapD && - (d->options&DC_TIES)!=0 && - d->scale<scale2rail/2 ) - DrawSegsO(d,t,zero,0.0,xx->cornuData.arcSegs.ptr,xx->cornuData.arcSegs.cnt, GetTrkGauge(t), color, widthOptions|DTS_TIES); DrawSegsO(d,t,zero,0.0,xx->cornuData.arcSegs.ptr,xx->cornuData.arcSegs.cnt, GetTrkGauge(t), color, widthOptions); - if ( (d->funcs->options & wDrawOptTemp) == 0 && - (d->options&DC_QUICK) == 0 ) { - DrawEndPt( d, t, 0, color ); - DrawEndPt( d, t, 1, color ); - } + DrawEndPt( d, t, 0, color ); + DrawEndPt( d, t, 1, color ); } void FreeSubSegs(trkSeg_t* s) { @@ -579,7 +575,7 @@ static BOOL_T WriteCornu( track_p t, FILE * f ) if ( ( GetTrkBits(t) & TB_HIDEDESC ) == 0 ) options |= 0x80; rc &= fprintf(f, "%s %d %d %ld 0 0 %s %d %0.6f %0.6f %0.6f %0.6f %0.6f %0.6f %0.6f %0.6f %0.6f %0.6f %0.6f %0.6f \n", "CORNU",GetTrkIndex(t), GetTrkLayer(t), (long)options, - GetTrkScaleName(t), GetTrkVisible(t), + GetTrkScaleName(t), GetTrkVisible(t)|(GetTrkNoTies(t)?1<<2:0)|(GetTrkBridge(t)?1<<3:0), xx->cornuData.pos[0].x, xx->cornuData.pos[0].y, xx->cornuData.a[0], xx->cornuData.r[0], @@ -593,11 +589,10 @@ static BOOL_T WriteCornu( track_p t, FILE * f ) rc &= WriteEndPt( f, t, 1 ); } rc &= WriteSegs( f, xx->cornuData.arcSegs.cnt, xx->cornuData.arcSegs.ptr ); - //rc &= fprintf(f, "\tEND\n" )>0; return rc; } -static void ReadCornu( char * line ) +static BOOL_T ReadCornu( char * line ) { struct extraData *xx; track_p t; @@ -613,12 +608,16 @@ static void ReadCornu( char * line ) if (!GetArgs( line+6, "dLl00sdpffppffp", &index, &layer, &options, scale, &visible, &p0, &a0, &r0, &c0, &p1, &a1, &r1, &c1 ) ) { - return; + return FALSE; } + if ( !ReadSegs() ) + return FALSE; t = NewTrack( index, T_CORNU, 0, sizeof *xx ); xx = GetTrkExtraData(t); - SetTrkVisible(t, visible); + SetTrkVisible(t, visible&2); + SetTrkNoTies(t, visible&4); + SetTrkBridge(t, visible&8); SetTrkScale(t, LookupScale(scale)); SetTrkLayer(t, layer ); SetTrkWidth(t, (int)(options&0x0F)); @@ -632,10 +631,10 @@ static void ReadCornu( char * line ) xx->cornuData.c[1] = c1; xx->cornuData.r[1] = r1; xx->cornuData.descriptionOff.x = xx->cornuData.descriptionOff.y = 0.0; - ReadSegs(); FixUpCornu0(xx->cornuData.pos,xx->cornuData.c,xx->cornuData.a, xx->cornuData.r, xx); ComputeCornuBoundingBox(t,xx); SetEndPts(t,2); + return TRUE; } static void MoveCornu( track_p trk, coOrd orig ) @@ -667,6 +666,9 @@ static void RescaleCornu( track_p trk, FLOAT_T ratio ) for (int i=0;i<2;i++) { xx->cornuData.pos[i].x *= ratio; xx->cornuData.pos[i].y *= ratio; + xx->cornuData.c[i].x *= ratio; + xx->cornuData.c[i].y *= ratio; + xx->cornuData.r[i] *= ratio; } RebuildCornu(trk); @@ -689,13 +691,63 @@ void GetCornuParmsNear(track_p t, int sel, coOrd * pos2, coOrd * center, ANGLE_T coOrd pos = *pos2; double dd = DistanceCornu(t, &pos); //Pos adjusted to be on curve int inx; + *radius = 0.0; + *angle2 = 0.0; + *center = zero; wBool_t back,neg; ANGLE_T angle = GetAngleSegs(xx->cornuData.arcSegs.cnt,(trkSeg_t *)(xx->cornuData.arcSegs.ptr),&pos,&inx,NULL,&back,NULL,&neg); + if (inx == -1) { + return; //Error in GetAngle + } + trkSeg_p segPtr = &DYNARR_N(trkSeg_t, xx->cornuData.arcSegs, inx); - GetAngleSegs(segPtr->bezSegs.cnt,(trkSeg_t *)(segPtr->bezSegs.ptr),&pos,&inx,NULL,&back,NULL,&neg); - segPtr = &DYNARR_N(trkSeg_t, segPtr->bezSegs, inx); + if (segPtr->type == SEG_BEZTRK) { + GetAngleSegs(segPtr->bezSegs.cnt,(trkSeg_t *)(segPtr->bezSegs.ptr),&pos,&inx,NULL,&back,NULL,&neg); + if (inx ==-1) return; + segPtr = &DYNARR_N(trkSeg_t, segPtr->bezSegs, inx); + } + + if (segPtr->type == SEG_STRTRK) { + *radius = 0.0; + *center = zero; + } else if (segPtr->type == SEG_CRVTRK) { + *center = segPtr->u.c.center; + *radius = fabs(segPtr->u.c.radius); + } + if (sel) + angle = NormalizeAngle(angle+(neg==back?0:180)); + else + angle = NormalizeAngle(angle+(neg==back?180:0)); + *angle2 = angle; + *pos2 = pos; +} + +void GetCornuParmsTemp(dynArr_t * array_p, int sel, coOrd * pos2, coOrd * center, ANGLE_T * angle2, DIST_T * radius ) { + + coOrd pos = *pos2; + int inx; + wBool_t back,neg; + *radius = 0.0; + *center = zero; + *angle2 = 0.0; + + ANGLE_T angle = GetAngleSegs(array_p->cnt,(trkSeg_p)array_p->ptr,&pos,&inx,NULL,&back,NULL,&neg); + + if (inx==-1) return; + + trkSeg_p segPtr = &DYNARR_N(trkSeg_t, *array_p, inx); + + if (segPtr->type == SEG_BEZTRK) { + + GetAngleSegs(segPtr->bezSegs.cnt,(trkSeg_t *)(segPtr->bezSegs.ptr),&pos,&inx,NULL,&back,NULL,&neg); + + if (inx ==-1) return; + + segPtr = &DYNARR_N(trkSeg_t, segPtr->bezSegs, inx); + + } if (segPtr->type == SEG_STRTRK) { *radius = 0.0; @@ -734,9 +786,14 @@ static BOOL_T SplitCornu( track_p trk, coOrd pos, EPINX_T ep, track_p *leftover, ANGLE_T angle = GetAngleSegs(xx->cornuData.arcSegs.cnt,(trkSeg_t *)(xx->cornuData.arcSegs.ptr),&pos,&inx,NULL,&back,NULL,&neg); + if (inx == -1) return FALSE; + trkSeg_p segPtr = &DYNARR_N(trkSeg_t, xx->cornuData.arcSegs, inx); GetAngleSegs(segPtr->bezSegs.cnt,(trkSeg_t *)(segPtr->bezSegs.ptr),&pos,&inx,NULL,&back,NULL,&neg); + + if (inx == -1) return FALSE; + segPtr = &DYNARR_N(trkSeg_t, segPtr->bezSegs, inx); if (segPtr->type == SEG_STRTRK) { @@ -767,6 +824,7 @@ static BOOL_T SplitCornu( track_p trk, coOrd pos, EPINX_T ep, track_p *leftover, } trk1 = NewCornuTrack(new.pos,new.center,new.angle,new.radius,NULL,0); + //Copy elevation details from old ep to new ep 0/1 if (trk1==NULL) { wBeep(); InfoMessage(_("Cornu Create Failed for p1[%0.3f,%0.3f] p2[%0.3f,%0.3f], c1[%0.3f,%0.3f] c2[%0.3f,%0.3f], a1=%0.3f a2=%0.3f, r1=%s r2=%s"), @@ -779,20 +837,26 @@ static BOOL_T SplitCornu( track_p trk, coOrd pos, EPINX_T ep, track_p *leftover, UndoEnd(); return FALSE; } + DIST_T height; + int opt; + GetTrkEndElev(trk,ep,&opt,&height); + UpdateTrkEndElev( trk1, ep, opt, height, (opt==ELEV_STATION)?GetTrkEndElevStation(trk,ep):NULL ); UndoModify(trk); xx->cornuData.pos[ep] = pos; xx->cornuData.a[ep] = NormalizeAngle(new.angle[1-ep]+180); xx->cornuData.r[ep] = new.radius[1-ep]; xx->cornuData.c[ep] = new.center[1-ep]; + //Wipe out old elevation for ep1 RebuildCornu(trk); SetTrkEndPoint(trk, ep, xx->cornuData.pos[ep], xx->cornuData.a[ep]); + UpdateTrkEndElev( trk, ep, ELEV_NONE, 0, NULL); *leftover = trk1; - *ep0 = 1-ep; - *ep1 = ep; + *ep0 = 1-ep; //Which end is for new on pos? + *ep1 = ep; //Which end is for old trk? return TRUE; } @@ -801,8 +865,12 @@ BOOL_T MoveCornuEndPt ( track_p *trk, EPINX_T *ep, coOrd pos, DIST_T d0 ) { track_p trk2; if (SplitTrack(*trk,pos,*ep,&trk2,TRUE)) { struct extraData *xx = GetTrkExtraData(*trk); - if (trk2) DeleteTrack(trk2,TRUE); + if (trk2) { + UndrawNewTrack( trk2 ); + DeleteTrack(trk2,TRUE); + } SetTrkEndPoint( *trk, *ep, *ep?xx->cornuData.pos[1]:xx->cornuData.pos[0], *ep?xx->cornuData.a[1]:xx->cornuData.a[0] ); + DrawNewTrack( *trk ); return TRUE; } return FALSE; @@ -923,7 +991,8 @@ static BOOL_T EnumerateCornu( track_p trk ) if (trk != NULL) { struct extraData *xx = GetTrkExtraData(trk); DIST_T d; - d = xx->cornuData.length; + d = max(CornuOffsetLength(xx->cornuData.arcSegs,-GetTrkGauge(trk)/2.0), + CornuOffsetLength(xx->cornuData.arcSegs,GetTrkGauge(trk)/2.0)); ScaleLengthIncrement( GetTrkScale(trk), d ); } return TRUE; @@ -1004,29 +1073,63 @@ static BOOL_T MergeCornu( DrawNewTrack( trk3 ); UndoEnd(); - return TRUE; } -BOOL_T GetBezierSegmentsFromCornu(track_p trk, dynArr_t * segs) { +BOOL_T GetBezierSegmentsFromCornu(track_p trk, dynArr_t * segs, BOOL_T track) { struct extraData * xx = GetTrkExtraData(trk); for (int i=0;i<xx->cornuData.arcSegs.cnt;i++) { - DYNARR_APPEND(trkSeg_t, * segs, 10); + trkSeg_p p = (trkSeg_t *) xx->cornuData.arcSegs.ptr+i; + if (p->type == SEG_BEZTRK) { + if (track) { + DYNARR_APPEND(trkSeg_t, * segs, 10); + trkSeg_p segPtr = &DYNARR_N(trkSeg_t,* segs,segs->cnt-1); + segPtr->type = SEG_BEZTRK; + segPtr->color = wDrawColorBlack; + segPtr->width = 0; + if (segPtr->bezSegs.ptr) MyFree(segPtr->bezSegs.ptr); + segPtr->bezSegs.cnt = 0; + segPtr->bezSegs.max = 0; + segPtr->bezSegs.ptr = NULL; + for (int j=0;j<4;j++) segPtr->u.b.pos[j] = p->u.b.pos[j]; + FixUpBezierSeg(segPtr->u.b.pos,segPtr,TRUE); + } else { + for (int j=0;j<p->bezSegs.cnt;j++) { + trkSeg_p bez_p = &DYNARR_N(trkSeg_t,p->bezSegs,j); + DYNARR_APPEND(trkSeg_t, * segs, 10); + trkSeg_p segPtr = &DYNARR_LAST(trkSeg_t,* segs); + if (bez_p->type == SEG_CRVTRK) segPtr->type = SEG_CRVLIN; + if (bez_p->type == SEG_STRTRK) segPtr->type = SEG_STRLIN; + segPtr->u = bez_p->u; + segPtr->width = bez_p->width; + segPtr->color = bez_p->color; + } + } + } else if (p->type == SEG_STRTRK) { + DYNARR_APPEND(trkSeg_t, * segs, 1); + trkSeg_p segPtr = &DYNARR_N(trkSeg_t,* segs,segs->cnt-1); + segPtr->type = track?SEG_STRTRK:SEG_STRLIN; + segPtr->color = wDrawColorBlack; + segPtr->width = 0; + for (int j=0;j<2;j++) segPtr->u.l.pos[i] = p->u.l.pos[i]; + segPtr->u.l.angle = p->u.l.angle; + segPtr->u.l.option = 0; + } else if (p->type == SEG_CRVTRK) { + DYNARR_APPEND(trkSeg_t, * segs, 1); trkSeg_p segPtr = &DYNARR_N(trkSeg_t,* segs,segs->cnt-1); - segPtr->type = SEG_BEZTRK; + segPtr->type = track?SEG_CRVTRK:SEG_CRVLIN; segPtr->color = wDrawColorBlack; segPtr->width = 0; - if (segPtr->bezSegs.ptr) MyFree(segPtr->bezSegs.ptr); - segPtr->bezSegs.cnt = 0; - segPtr->bezSegs.max = 0; - segPtr->bezSegs.ptr = NULL; - trkSeg_p p = (trkSeg_t *) xx->cornuData.arcSegs.ptr+i; - for (int j=0;j<4;j++) segPtr->u.b.pos[j] = p->u.b.pos[j]; - FixUpBezierSeg(segPtr->u.b.pos,segPtr,TRUE); + segPtr->u.c.a0 = p->u.c.a0; + segPtr->u.c.a1 = p->u.c.a1; + segPtr->u.c.center = p->u.c.center; + segPtr->u.c.radius = p->u.c.radius; + } } return TRUE; } + static DIST_T GetLengthCornu( track_p trk ) { struct extraData *xx = GetTrkExtraData(trk); @@ -1052,6 +1155,7 @@ static BOOL_T GetParamsCornu( int inx, track_p trk, coOrd pos, trackParams_t * p params->track_angle = GetAngleSegs( //Find correct Segment and nearest point in it xx->cornuData.arcSegs.cnt,xx->cornuData.arcSegs.ptr, &pos, &segInx, &d , &back, &segInx2, &negative ); + if (segInx ==-1) return FALSE; trkSeg_p segPtr = &DYNARR_N(trkSeg_t,xx->cornuData.arcSegs,segInx); if (negative != back) params->track_angle = NormalizeAngle(params->track_angle+180); //Cornu is in reverse if (segPtr->type == SEG_STRTRK) { @@ -1079,13 +1183,16 @@ static BOOL_T GetParamsCornu( int inx, track_p trk, coOrd pos, trackParams_t * p params->cornuCenter[i] = xx->cornuData.c[i]; } params->len = xx->cornuData.length; - if ( inx == PARAMS_PARALLEL ) { - params->ep = 0; - } else if (inx == PARAMS_CORNU) { + if ( inx == PARAMS_NODES ) { + return FALSE; + } 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 == -1) return FALSE; + if (params->ep>=0) { params->angle = GetTrkEndAngle(trk,params->ep); } @@ -1108,7 +1215,7 @@ static BOOL_T QueryCornu( track_p trk, int query ) return TRUE; break; case Q_EXCEPTION: - return xx->cornuData.minCurveRadius < (GetLayoutMinTrackRadius()-EPSILON); + return fabs(xx->cornuData.minCurveRadius) < (GetLayoutMinTrackRadius()-EPSILON); break; case Q_IS_CORNU: return TRUE; @@ -1122,13 +1229,12 @@ static BOOL_T QueryCornu( track_p trk, int query ) // case Q_MODIFY_CANT_SPLIT: Remove Split Restriction // case Q_CANNOT_BE_ON_END: Remove Restriction - Can have Cornu with no ends case Q_CANNOT_PLACE_TURNOUT: - return TRUE; + return FALSE; break; case Q_IGNORE_EASEMENT_ON_EXTEND: return TRUE; break; case Q_MODIFY_CAN_SPLIT: - case Q_CAN_EXTEND: return TRUE; default: return FALSE; @@ -1178,8 +1284,9 @@ static ANGLE_T GetAngleCornu( BOOL_T back, neg; int indx; angle = GetAngleSegs( xx->cornuData.arcSegs.cnt, (trkSeg_p)xx->cornuData.arcSegs.ptr, &pos, &indx, NULL, &back, NULL, &neg ); - if ( ep0 ) *ep0 = -1; - if ( ep1 ) *ep1 = -1; + if (!back) angle = NormalizeAngle(angle+180); + if ( ep0 ) *ep0 = neg?1:0; + if ( ep1 ) *ep1 = neg?0:1; return angle; } @@ -1188,14 +1295,17 @@ BOOL_T GetCornuSegmentFromTrack(track_p trk, trkSeg_p seg_p) { return TRUE; } +static dynArr_t cornuSegs_da; static BOOL_T MakeParallelCornu( track_p trk, coOrd pos, DIST_T sep, + DIST_T factor, track_p * newTrkR, coOrd * p0R, - coOrd * p1R ) + coOrd * p1R, + BOOL_T track ) { struct extraData * xx = GetTrkExtraData(trk); coOrd np[4], p, nc[2]; @@ -1216,40 +1326,41 @@ static BOOL_T MakeParallelCornu( BOOL_T above = FALSE; if ( diff_a < 180 ) above = TRUE; //Above track if (xx->cornuData.a[0] <180) above = !above; - Translate(&np[0],xx->cornuData.pos[0],xx->cornuData.a[0]+(above?90:-90),sep); - Translate(&np[1],xx->cornuData.pos[1],xx->cornuData.a[1]+(above?-90:90),sep); + DIST_T sep0 = sep+((xx->cornuData.r[0]!=0.0)?fabs(factor/xx->cornuData.r[0]):0); + DIST_T sep1 = sep+((xx->cornuData.r[1]!=0.0)?fabs(factor/xx->cornuData.r[1]):0); + Translate(&np[0],xx->cornuData.pos[0],xx->cornuData.a[0]+(above?90:-90),sep0); + Translate(&np[1],xx->cornuData.pos[1],xx->cornuData.a[1]+(above?-90:90),sep1); na[0]=xx->cornuData.a[0]; na[1]=xx->cornuData.a[1]; - if (xx->cornuData.r[0]) { + if (xx->cornuData.r[0] != 0.0) { //Find angle between center and end angle of track ANGLE_T ea0 = NormalizeAngle(FindAngle(xx->cornuData.c[0],xx->cornuData.pos[0])-xx->cornuData.a[0]); - DIST_T sep0 = sep; - if (ea0>180) sep0 = -sep; + if (ea0>180) sep0 = -sep0; nr[0]=xx->cornuData.r[0]+(above?sep0:-sep0); //Needs adjustment nc[0]=xx->cornuData.c[0]; } else { - nr[0] = 0; + nr[0] = 0.0; nc[0] = zero; } - if (xx->cornuData.r[1]) { + if (xx->cornuData.r[1] != 0.0) { ANGLE_T ea1 = NormalizeAngle(FindAngle(xx->cornuData.c[1],xx->cornuData.pos[1])-xx->cornuData.a[1]); - DIST_T sep1 = sep; - if (ea1<180) sep1 = -sep; + if (ea1<180) sep1 = -sep1; nr[1]=xx->cornuData.r[1]+(above?sep1:-sep1); //Needs adjustment nc[1]=xx->cornuData.c[1]; } else { - nr[1] = 0; + nr[1] = 0.0; nc[1] = zero; } if ( newTrkR ) { - *newTrkR = NewCornuTrack( np, nc, na, nr, NULL, 0); - if (*newTrkR==NULL) { - wBeep(); - InfoMessage(_("Cornu Create Failed for p1[%0.3f,%0.3f] p2[%0.3f,%0.3f], c1[%0.3f,%0.3f] c2[%0.3f,%0.3f], a1=%0.3f a2=%0.3f, r1=%s r2=%s"), + if (track) { + *newTrkR = NewCornuTrack( np, nc, na, nr, NULL, 0); + if (*newTrkR==NULL) { + wBeep(); + InfoMessage(_("Cornu Create Failed for p1[%0.3f,%0.3f] p2[%0.3f,%0.3f], c1[%0.3f,%0.3f] c2[%0.3f,%0.3f], a1=%0.3f a2=%0.3f, r1=%s r2=%s"), np[0].x,np[0].y, np[1].x,np[1].y, nc[0].x,nc[0].y, @@ -1258,16 +1369,75 @@ static BOOL_T MakeParallelCornu( FormatDistance(nr[0]),FormatDistance(nr[1])); return FALSE; } + } else { + tempSegs_da.cnt = 0; + CallCornu0(np,nc,na,nr,&tempSegs_da,FALSE); + *newTrkR = MakePolyLineFromSegs( zero, 0.0, &tempSegs_da ); + } } else { tempSegs_da.cnt = 0; CallCornu0(np,nc,na,nr,&tempSegs_da,FALSE); + if (!track) { + for (int i=0;i<tempSegs_da.cnt;i++) { + trkSeg_p seg = &tempSegs(i); + if (seg->type == SEG_STRTRK) { + seg->type = SEG_STRLIN; + seg->color = wDrawColorBlack; + seg->width = 0; + } + if (seg->type == SEG_CRVTRK) { + seg->type = SEG_CRVLIN; + seg->color = wDrawColorBlack; + seg->width = 0; + } + if (seg->type == SEG_BEZTRK) { + for (int j=0;j<seg->bezSegs.cnt;j++) { + trkSeg_p bseg = &(((trkSeg_t *)seg->bezSegs.ptr)[j]); + if (bseg->type == SEG_STRTRK) { + bseg->type = SEG_STRLIN; + bseg->color = wDrawColorBlack; + bseg->width = 0; + } + if (bseg->type == SEG_CRVTRK) { + bseg->type = SEG_CRVLIN; + bseg->color = wDrawColorBlack; + bseg->width = 0; + } + } + seg->type = SEG_BEZLIN; + seg->color = wDrawColorBlack; + seg->width = 0; + } + } + } } if ( p0R ) *p0R = np[0]; if ( p1R ) *p1R = np[1]; return TRUE; } +static BOOL_T TrimCornu( track_p trk, EPINX_T ep, DIST_T dist, coOrd endpos, ANGLE_T angle, DIST_T radius, coOrd center ) { + UndoModify(trk); + if (dist>0.0 && dist<minLength) { + UndrawNewTrack( trk ); + DeleteTrack(trk, TRUE); + return FALSE; + } else { + struct extraData *xx; + UndrawNewTrack( trk ); + xx = GetTrkExtraData(trk); + xx->cornuData.a[ep] = angle; + xx->cornuData.c[ep] = center; + xx->cornuData.r[ep] = radius; + xx->cornuData.pos[ep] = endpos; + RebuildCornu(trk); + SetTrkEndPoint(trk, ep, xx->cornuData.pos[ep], xx->cornuData.a[ep]); + DrawNewTrack( trk ); + } + return TRUE; +} + /* * When an undo is run, the array of segs is missing - they are not saved to the Undo log. So Undo calls this routine to * ensure @@ -1288,6 +1458,29 @@ EXPORT BOOL_T RebuildCornu (track_p trk) } +static wBool_t CompareCornu( track_cp trk1, track_cp trk2 ) +{ + struct extraData *xx1 = GetTrkExtraData( trk1 ); + struct extraData *xx2 = GetTrkExtraData( trk2 ); + char * cp = message + strlen(message); + REGRESS_CHECK_POS( "Pos[0]", xx1, xx2, cornuData.pos[0] ) + REGRESS_CHECK_POS( "Pos[1]", xx1, xx2, cornuData.pos[1] ) + REGRESS_CHECK_POS( "C[0]", xx1, xx2, cornuData.c[0] ) + REGRESS_CHECK_POS( "C[1]", xx1, xx2, cornuData.c[1] ) + REGRESS_CHECK_ANGLE( "A[0]", xx1, xx2, cornuData.a[0] ) + REGRESS_CHECK_ANGLE( "A[1]", xx1, xx2, cornuData.a[1] ) + REGRESS_CHECK_DIST( "R[0]", xx1, xx2, cornuData.r[0] ) + REGRESS_CHECK_DIST( "R[1]", xx1, xx2, cornuData.r[1] ) + REGRESS_CHECK_DIST( "MinCurveRadius", xx1, xx2, cornuData.minCurveRadius ) + REGRESS_CHECK_DIST( "MaxRateofChange", xx1, xx2, cornuData.maxRateofChange ) + REGRESS_CHECK_DIST( "Length", xx1, xx2, cornuData.length ) + REGRESS_CHECK_ANGLE( "WindingAngle", xx1, xx2, cornuData.windingAngle ) + // CHECK arcSegs + REGRESS_CHECK_POS( "DescOff", xx1, xx2, cornuData.descriptionOff ) + // CHECK cornuPath + return TRUE; +} + static trackCmd_t cornuCmds = { "CORNU", DrawCornu, @@ -1305,7 +1498,7 @@ static trackCmd_t cornuCmds = { TraverseCornu, EnumerateCornu, NULL, /* redraw */ - NULL, /* trim */ + TrimCornu, /* trim */ MergeCornu, NULL, /* modify */ GetLengthCornu, @@ -1319,7 +1512,11 @@ static trackCmd_t cornuCmds = { NULL, MakeParallelCornu, NULL, - RebuildCornu + RebuildCornu, + NULL, + NULL, + NULL, + CompareCornu }; |