summaryrefslogtreecommitdiff
path: root/app/bin/ccornu.c
diff options
context:
space:
mode:
Diffstat (limited to 'app/bin/ccornu.c')
-rw-r--r--app/bin/ccornu.c84
1 files changed, 55 insertions, 29 deletions
diff --git a/app/bin/ccornu.c b/app/bin/ccornu.c
index b67d245..5515d75 100644
--- a/app/bin/ccornu.c
+++ b/app/bin/ccornu.c
@@ -89,6 +89,7 @@ extern TRKTYP_T T_BEZIER;
extern TRKTYP_T T_CORNU;
+
/*
* STATE INFO
*/
@@ -129,6 +130,7 @@ static struct {
track_p selectTrack;
DIST_T minRadius;
BOOL_T circleorHelix[2];
+ DIST_T trackGauge;
bezctx * bezc;
} Da;
@@ -283,7 +285,7 @@ BOOL_T CallCornu(coOrd pos[2], track_p trk[2], EPINX_T ep[2], dynArr_t * array_p
if (trk[i]) {
if (!GetTrackParams(PARAMS_CORNU,trk[i],pos[i],&params)) return FALSE;
cp->pos[i] = pos[i];
- if (Da.ep[i]>=0) angle = GetTrkEndAngle(trk[i],ep[i]);
+ if (ep && ep[i]>=0) angle = GetTrkEndAngle(trk[i],ep[i]);
else angle = params.angle; //Turntable only
if (Da.circleorHelix[i]) { //Helix/Circle only
cp->radius[i] = params.arcR;
@@ -311,7 +313,7 @@ BOOL_T CallCornu(coOrd pos[2], track_p trk[2], EPINX_T ep[2], dynArr_t * array_p
}
}
- return CallCornu0(pos,cp->center,cp->angle,cp->radius,array_p,TRUE);
+ return CallCornu0(pos,cp->center,cp->angle,cp->radius,array_p,ep?TRUE:FALSE);
}
@@ -340,19 +342,19 @@ EXPORT void DrawCornuCurve(
tempD.orig = mainD.orig;
tempD.angle = mainD.angle;
if (first_trk)
- DrawSegs( &tempD, zero, 0.0, first_trk, 1, trackGauge, drawColorBlack );
+ DrawSegs( &tempD, zero, 0.0, first_trk, 1, Da.trackGauge, drawColorBlack );
if (crvSegs_cnt && curveSegs)
- DrawSegs( &tempD, zero, 0.0, curveSegs, crvSegs_cnt, trackGauge, color );
+ DrawSegs( &tempD, zero, 0.0, curveSegs, crvSegs_cnt, Da.trackGauge, color );
if (second_trk)
- DrawSegs( &tempD, zero, 0.0, second_trk, 1, trackGauge, drawColorBlack );
+ DrawSegs( &tempD, zero, 0.0, second_trk, 1, Da.trackGauge, drawColorBlack );
if (ep1Segs_cnt && point1)
- DrawSegs( &tempD, zero, 0.0, point1, ep1Segs_cnt, trackGauge, drawColorBlack );
+ DrawSegs( &tempD, zero, 0.0, point1, ep1Segs_cnt, Da.trackGauge, drawColorBlack );
if (ep2Segs_cnt && point2)
- DrawSegs( &tempD, zero, 0.0, point2, ep2Segs_cnt, trackGauge, drawColorBlack );
+ DrawSegs( &tempD, zero, 0.0, point2, ep2Segs_cnt, Da.trackGauge, drawColorBlack );
if (extend1_trk)
- DrawSegs( &tempD, zero, 0.0, extend1_trk, 1, trackGauge, drawColorBlack);
+ DrawSegs( &tempD, zero, 0.0, extend1_trk, 1, Da.trackGauge, drawColorBlack);
if (extend2_trk)
- DrawSegs( &tempD, zero, 0.0, extend2_trk, 1, trackGauge, drawColorBlack);
+ DrawSegs( &tempD, zero, 0.0, extend2_trk, 1, Da.trackGauge, drawColorBlack);
tempD.funcs->options = oldDrawOptions;
tempD.options = oldOptions;
@@ -709,9 +711,9 @@ EXPORT STATUS_T AdjustCornuCurve(
else Da.crvSegs_da_cnt = 0;
Da.minRadius = CornuMinRadius(Da.pos,Da.crvSegs_da);
DIST_T rin = Da.radius[0];
- InfoMessage( _("Cornu : Min Radius=%s Max Rate of Radius Change=%s Length=%s Winding Arc=%s"),
+ InfoMessage( _("Cornu : Min Radius=%s MaxRateofCurveChange/Scale=%s Length=%s Winding Arc=%s"),
FormatDistance(Da.minRadius),
- FormatDistance(CornuMaxRateofChangeofCurvature(Da.pos,Da.crvSegs_da,&rin)),
+ FormatFloat(CornuMaxRateofChangeofCurvature(Da.pos,Da.crvSegs_da,&rin)*GetScaleRatio(GetLayoutCurScale())),
FormatDistance(CornuLength(Da.pos,Da.crvSegs_da)),
FormatDistance(CornuTotalWindingArc(Da.pos,Da.crvSegs_da)));
DrawTempCornu();
@@ -745,10 +747,12 @@ EXPORT STATUS_T AdjustCornuCurve(
return C_CONTINUE;
}
for (int i=0;i<2;i++) {
- if (FindDistance(Da.pos[i],GetTrkEndPos(Da.trk[i],1-Da.ep[i])) < minLength) {
- wBeep();
- InfoMessage(_("Cornu end %d too close to other end of connect track - reposition it"),i+1);
- return C_CONTINUE;
+ if (!(QueryTrack(Da.trk[i],Q_CAN_ADD_ENDPOINTS))) { // Not Turntable
+ if (FindDistance(Da.pos[i],GetTrkEndPos(Da.trk[i],1-Da.ep[i])) < minLength) {
+ wBeep();
+ InfoMessage(_("Cornu end %d too close to other end of connect track - reposition it"),i+1);
+ return C_CONTINUE;
+ }
}
}
@@ -818,10 +822,12 @@ struct extraData {
* - C_CANCEL (Esc) sets the state to NONE and reshows the original track unchanged.
*
*/
-STATUS_T CmdCornuModify (track_p trk, wAction_t action, coOrd pos) {
+STATUS_T CmdCornuModify (track_p trk, wAction_t action, coOrd pos, DIST_T trackG ) {
track_p t;
struct extraData *xx = GetTrkExtraData(trk);
+ Da.trackGauge = trackG;
+
switch (action&0xFF) {
case C_START:
Da.state = NONE;
@@ -890,6 +896,15 @@ STATUS_T CmdCornuModify (track_p trk, wAction_t action, coOrd pos) {
wBeep();
return C_CONTINUE;
}
+ for (int i=0;i<2;i++) {
+ if (!(QueryTrack(Da.trk[i],Q_CAN_ADD_ENDPOINTS))) { // Not Turntable
+ if (FindDistance(Da.pos[i],GetTrkEndPos(Da.trk[i],1-Da.ep[i])) < minLength) {
+ wBeep();
+ InfoMessage(_("Cornu end %d too close to other end of connect track - reposition it"),i+1);
+ return C_CONTINUE;
+ }
+ }
+ }
UndoStart( _("Modify Cornu"), "newCornu - CR" );
for (int i=0;i<2;i++) {
if (!Da.trk[i] && Da.extend[i]) {
@@ -899,6 +914,7 @@ STATUS_T CmdCornuModify (track_p trk, wAction_t action, coOrd pos) {
} else {
Da.trk[i] = NewCurvedTrack(Da.extendSeg[i].u.c.center,fabs(Da.extendSeg[i].u.c.radius),
Da.extendSeg[i].u.c.a0,Da.extendSeg[i].u.c.a1,FALSE);
+
if (Da.angle[i]>180)
Da.ep[i] = (Da.extendSeg[i].u.c.a0>90 && Da.extendSeg[i].u.c.a0<270)?0:1;
else
@@ -930,6 +946,8 @@ STATUS_T CmdCornuModify (track_p trk, wAction_t action, coOrd pos) {
return C_TERMINATE;
}
+ CopyAttributes( trk, t );
+
DeleteTrack(trk, TRUE);
if (Da.trk[0]) UndoModify(Da.trk[0]);
@@ -937,14 +955,20 @@ STATUS_T CmdCornuModify (track_p trk, wAction_t action, coOrd pos) {
for (int i=0;i<2;i++) { //Attach new track
if (Da.trk[i] && Da.ep[i] != -1) { //Like the old track
- MoveEndPt(&Da.trk[i],&Da.ep[i],Da.pos[i],0);
- if (GetTrkType(Da.trk[i])==T_BEZIER) { //Bezier split position not precise, so readjust Cornu
- GetConnectedTrackParms(Da.trk[i],GetTrkEndPos(Da.trk[i],Da.ep[i]),i,Da.ep[i]);
- ANGLE_T endAngle = NormalizeAngle(GetTrkEndAngle(Da.trk[i],Da.ep[i])+180);
- SetCornuEndPt(t,i,GetTrkEndPos(Da.trk[i],Da.ep[i]),Da.center[i],endAngle,Da.radius[i]);
+ if (MoveEndPt(&Da.trk[i],&Da.ep[i],Da.pos[i],0)) {
+ if (GetTrkType(Da.trk[i])==T_BEZIER) { //Bezier split position not precise, so readjust Cornu
+ GetConnectedTrackParms(Da.trk[i],GetTrkEndPos(Da.trk[i],Da.ep[i]),i,Da.ep[i]);
+ ANGLE_T endAngle = NormalizeAngle(GetTrkEndAngle(Da.trk[i],Da.ep[i])+180);
+ SetCornuEndPt(t,i,GetTrkEndPos(Da.trk[i],Da.ep[i]),Da.center[i],endAngle,Da.radius[i]);
+ }
+ if (Da.ep[i]>= 0)
+ ConnectTracks(t,i,Da.trk[i],Da.ep[i]);
+ } else {
+ UndoUndo();
+ wBeep();
+ InfoMessage(_("Connected Track End Adjust for end %d failed"),i);
+ return C_TERMINATE;
}
- if (Da.ep[i]>= 0)
- ConnectTracks(t,i,Da.trk[i],Da.ep[i]);
}
}
UndoEnd();
@@ -1020,7 +1044,7 @@ DIST_T CornuTotalWindingArc(coOrd pos[4],dynArr_t segs) {
}
DIST_T CornuMaxRateofChangeofCurvature(coOrd pos[4], dynArr_t segs, DIST_T * last_c) {
- DIST_T r_max = 0.0, rc, lc = 0;
+ DIST_T r_max = 0.0, rc, lc = 0.0;
lc = * last_c;
segProcData_t segProcData;
if (segs.cnt == 0 ) return r_max;
@@ -1029,15 +1053,15 @@ DIST_T CornuMaxRateofChangeofCurvature(coOrd pos[4], dynArr_t segs, DIST_T * las
if (t.type == SEG_FILCRCL) continue;
SegProc(SEGPROC_LENGTH,&t,&segProcData);
if (t.type == SEG_CRVTRK || t.type == SEG_CRVLIN) {
- rc = fabs(1/t.u.c.radius - lc)/segProcData.length.length/2;
- lc = 1/t.u.c.radius;
+ rc = fabs(1/fabs(t.u.c.radius) - lc)/segProcData.length.length/2;
+ lc = 1/fabs(t.u.c.radius);
} else if (t.type == SEG_BEZLIN || t.type == SEG_BEZTRK) {
rc = CornuMaxRateofChangeofCurvature(t.u.b.pos, t.bezSegs,&lc); //recurse
} else {
- rc = fabs(0-lc)/segProcData.length.length/2;
- lc = 0;
+ rc = fabs(0.0-lc)/segProcData.length.length/2;
+ lc = 0.0;
}
- if (rc>r_max) r_max = rc;
+ if (rc > r_max) r_max = rc;
}
* last_c = lc;
return r_max;
@@ -1059,6 +1083,8 @@ STATUS_T CmdCornu( wAction_t action, coOrd pos )
Da.color = lineColor;
Da.width = (double)lineWidth/mainD.dpi;
+ Da.trackGauge = trackGauge;
+
switch (action&0xFF) {
case C_START: