CURVES.C 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498
  1. /*
  2. * $Source: f:/miner/source/main/editor/rcs/curves.c $
  3. * $Revision: 2.0 $
  4. * $Author: john $
  5. * $Date: 1995/02/27 11:35:50 $
  6. *
  7. * curve generation stuff
  8. *
  9. *
  10. *
  11. */
  12. #pragma off (unreferenced)
  13. static char rcsid[] = "$Id: curves.c 2.0 1995/02/27 11:35:50 john Exp $";
  14. #pragma on (unreferenced)
  15. #include <time.h>
  16. #include <stdio.h>
  17. #include <stdlib.h>
  18. #include <string.h>
  19. #include <ctype.h>
  20. #include <stdarg.h>
  21. #include <conio.h>
  22. #include <dos.h>
  23. #include "inferno.h"
  24. #include "mono.h"
  25. #include "vecmat.h"
  26. #include "gr.h"
  27. #include "key.h"
  28. #include "editor.h"
  29. #include "gameseg.h"
  30. #define ONE_OVER_SQRT2 F1_0 * 0.707106781
  31. #define CURVE_RIGHT 1
  32. #define CURVE_UP 2
  33. segment *OriginalSeg;
  34. segment *OriginalMarkedSeg;
  35. int OriginalSide;
  36. int OriginalMarkedSide;
  37. segment *CurveSegs[MAX_SEGMENTS];
  38. int CurveNumSegs;
  39. const fix Mh[4][4] = { { 2*F1_0, -2*F1_0, 1*F1_0, 1*F1_0 },
  40. {-3*F1_0, 3*F1_0, -2*F1_0, -1*F1_0 },
  41. { 0*F1_0, 0*F1_0, 1*F1_0, 0*F1_0 },
  42. { 1*F1_0, 0*F1_0, 0*F1_0, 0*F1_0 } };
  43. void create_curve(vms_vector *p1, vms_vector *p4, vms_vector *r1, vms_vector *r4, vms_equation *coeffs) {
  44. // Q(t) = (2t^3 - 3t^2 + 1) p1 + (-2t^3 + 3t^2) p4 + (t~3 - 2t^2 + t) r1 + (t^3 - t^2 ) r4
  45. coeffs->x3 = fixmul(2*F1_0,p1->x) - fixmul(2*F1_0,p4->x) + r1->x + r4->x;
  46. coeffs->x2 = fixmul(-3*F1_0,p1->x) + fixmul(3*F1_0,p4->x) - fixmul(2*F1_0,r1->x) - fixmul(1*F1_0,r4->x);
  47. coeffs->x1 = r1->x;
  48. coeffs->x0 = p1->x;
  49. coeffs->y3 = fixmul(2*F1_0,p1->y) - fixmul(2*F1_0,p4->y) + r1->y + r4->y;
  50. coeffs->y2 = fixmul(-3*F1_0,p1->y) + fixmul(3*F1_0,p4->y) - fixmul(2*F1_0,r1->y) - fixmul(1*F1_0,r4->y);
  51. coeffs->y1 = r1->y;
  52. coeffs->y0 = p1->y;
  53. coeffs->z3 = fixmul(2*F1_0,p1->z) - fixmul(2*F1_0,p4->z) + r1->z + r4->z;
  54. coeffs->z2 = fixmul(-3*F1_0,p1->z) + fixmul(3*F1_0,p4->z) - fixmul(2*F1_0,r1->z) - fixmul(1*F1_0,r4->z);
  55. coeffs->z1 = r1->z;
  56. coeffs->z0 = p1->z;
  57. }
  58. vms_vector evaluate_curve(vms_equation *coeffs, int degree, fix t) {
  59. fix t2, t3;
  60. vms_vector coord;
  61. if (degree!=3) printf("ERROR: for Hermite Curves degree must be 3\n");
  62. t2 = fixmul(t,t); t3 = fixmul(t2,t);
  63. coord.x = fixmul(coeffs->x3,t3) + fixmul(coeffs->x2,t2) + fixmul(coeffs->x1,t) + coeffs->x0;
  64. coord.y = fixmul(coeffs->y3,t3) + fixmul(coeffs->y2,t2) + fixmul(coeffs->y1,t) + coeffs->y0;
  65. coord.z = fixmul(coeffs->z3,t3) + fixmul(coeffs->z2,t2) + fixmul(coeffs->z1,t) + coeffs->z0;
  66. return coord;
  67. }
  68. fix curve_dist(vms_equation *coeffs, int degree, fix t0, vms_vector *p0, fix dist) {
  69. vms_vector coord;
  70. fix t, diff;
  71. if (degree!=3) printf("ERROR: for Hermite Curves degree must be 3\n");
  72. for (t=t0;t<1*F1_0;t+=0.001*F1_0) {
  73. coord = evaluate_curve(coeffs, 3, t);
  74. diff = dist - vm_vec_dist(&coord, p0);
  75. if (diff<ACCURACY) //&&(diff>-ACCURACY))
  76. return t;
  77. }
  78. return -1*F1_0;
  79. }
  80. void curve_dir(vms_equation *coeffs, int degree, fix t0, vms_vector *dir) {
  81. fix t2;
  82. if (degree!=3) printf("ERROR: for Hermite Curves degree must be 3\n");
  83. t2 = fixmul(t0,t0);
  84. dir->x = fixmul(3*F1_0,fixmul(coeffs->x3,t2)) + fixmul(2*F1_0,fixmul(coeffs->x2,t0)) + coeffs->x1;
  85. dir->y = fixmul(3*F1_0,fixmul(coeffs->y3,t2)) + fixmul(2*F1_0,fixmul(coeffs->y2,t0)) + coeffs->y1;
  86. dir->z = fixmul(3*F1_0,fixmul(coeffs->z3,t2)) + fixmul(2*F1_0,fixmul(coeffs->z2,t0)) + coeffs->z1;
  87. vm_vec_normalize( dir );
  88. }
  89. void plot_parametric(vms_equation *coeffs, fix min_t, fix max_t, fix del_t) {
  90. vms_vector coord, dcoord;
  91. fix t, dt;
  92. gr_setcolor(15);
  93. gr_box( 75, 40, 325, 290 );
  94. gr_box( 75, 310, 325, 560 );
  95. gr_box( 475, 310, 725, 560 );
  96. //gr_pal_fade_in( grd_curscreen->pal );
  97. for (t=min_t;t<max_t-del_t;t+=del_t) {
  98. dt = t+del_t;
  99. coord = evaluate_curve(coeffs, 3, t);
  100. dcoord = evaluate_curve(coeffs, 3, dt);
  101. gr_setcolor(9);
  102. gr_line ( 75*F1_0 + coord.x, 290*F1_0 - coord.z, 75*F1_0 + dcoord.x, 290*F1_0 - dcoord.z );
  103. gr_setcolor(10);
  104. gr_line ( 75*F1_0 + coord.x, 560*F1_0 - coord.y, 75*F1_0 + dcoord.x, 560*F1_0 - dcoord.y );
  105. gr_setcolor(12);
  106. gr_line ( 475*F1_0 + coord.z, 560*F1_0 - coord.y, 475*F1_0 + dcoord.z, 560*F1_0 - dcoord.y );
  107. }
  108. }
  109. vms_vector *vm_vec_interp(vms_vector *result, vms_vector *v0, vms_vector *v1, fix scale) {
  110. vms_vector tvec;
  111. vm_vec_sub(&tvec, v1, v0);
  112. vm_vec_scale_add(result, v0, &tvec, scale);
  113. vm_vec_normalize(result);
  114. return result;
  115. }
  116. vms_vector p1, p4, r1, r4;
  117. vms_vector r4t, r1save;
  118. int generate_curve( fix r1scale, fix r4scale ) {
  119. vms_vector vec_dir, tvec;
  120. vms_vector coord,prev_point;
  121. vms_equation coeffs;
  122. fix enddist, nextdist;
  123. int firstsegflag;
  124. fix t, maxscale;
  125. fixang rangle, uangle;
  126. compute_center_point_on_side( &p1, Cursegp, Curside );
  127. switch( Curside ) {
  128. case WLEFT:
  129. extract_right_vector_from_segment(Cursegp, &r1);
  130. vm_vec_scale( &r1, -F1_0 );
  131. break;
  132. case WTOP:
  133. extract_up_vector_from_segment(Cursegp, &r1);
  134. break;
  135. case WRIGHT:
  136. extract_right_vector_from_segment(Cursegp, &r1);
  137. break;
  138. case WBOTTOM:
  139. extract_up_vector_from_segment(Cursegp, &r1);
  140. vm_vec_scale( &r1, -F1_0 );
  141. break;
  142. case WBACK:
  143. extract_forward_vector_from_segment(Cursegp, &r1);
  144. break;
  145. case WFRONT:
  146. extract_forward_vector_from_segment(Cursegp, &r1);
  147. vm_vec_scale( &r1, -F1_0 );
  148. break;
  149. }
  150. compute_center_point_on_side( &p4, Markedsegp, Markedside );
  151. switch( Markedside ) {
  152. case WLEFT:
  153. extract_right_vector_from_segment(Markedsegp, &r4);
  154. extract_up_vector_from_segment(Markedsegp, &r4t);
  155. break;
  156. case WTOP:
  157. extract_up_vector_from_segment(Markedsegp, &r4);
  158. vm_vec_scale( &r4, -F1_0 );
  159. extract_forward_vector_from_segment(Markedsegp, &r4t);
  160. vm_vec_scale( &r4t, -F1_0 );
  161. break;
  162. case WRIGHT:
  163. extract_right_vector_from_segment(Markedsegp, &r4);
  164. vm_vec_scale( &r4, -F1_0 );
  165. extract_up_vector_from_segment(Markedsegp, &r4t);
  166. break;
  167. case WBOTTOM:
  168. extract_up_vector_from_segment(Markedsegp, &r4);
  169. extract_forward_vector_from_segment(Markedsegp, &r4t);
  170. break;
  171. case WBACK:
  172. extract_forward_vector_from_segment(Markedsegp, &r4);
  173. vm_vec_scale( &r4, -F1_0 );
  174. extract_up_vector_from_segment(Markedsegp, &r4t);
  175. break;
  176. case WFRONT:
  177. extract_forward_vector_from_segment(Markedsegp, &r4);
  178. extract_up_vector_from_segment(Markedsegp, &r4t);
  179. break;
  180. }
  181. r1save = r1;
  182. tvec = r1;
  183. vm_vec_scale(&r1,r1scale);
  184. vm_vec_scale(&r4,r4scale);
  185. create_curve( &p1, &p4, &r1, &r4, &coeffs );
  186. OriginalSeg = Cursegp;
  187. OriginalMarkedSeg = Markedsegp;
  188. OriginalSide = Curside;
  189. OriginalMarkedSide = Markedside;
  190. CurveNumSegs = 0;
  191. coord = prev_point = p1;
  192. t=0;
  193. firstsegflag = 1;
  194. enddist = F1_0; nextdist = 0;
  195. while ( enddist > fixmul( nextdist, 1.5*F1_0 )) {
  196. vms_matrix rotmat,rotmat2;
  197. vms_vector tdest;
  198. if (firstsegflag==1)
  199. firstsegflag=0;
  200. else
  201. extract_forward_vector_from_segment(Cursegp, &tvec);
  202. nextdist = vm_vec_mag(&tvec); // nextdist := distance to next point
  203. t = curve_dist(&coeffs, 3, t, &prev_point, nextdist); // t = argument at which function is forward vector magnitude units away from prev_point (in 3-space, not along curve)
  204. coord = evaluate_curve(&coeffs, 3, t); // coord := point about forward vector magnitude units away from prev_point
  205. enddist = vm_vec_dist(&coord, &p4); // enddist := distance from current to end point, vec_dir used as a temporary variable
  206. //vm_vec_normalize(vm_vec_sub(&vec_dir, &coord, &prev_point));
  207. vm_vec_normalized_dir(&vec_dir, &coord, &prev_point);
  208. if (!med_attach_segment( Cursegp, &New_segment, Curside, AttachSide )) {
  209. med_extract_matrix_from_segment( Cursegp,&rotmat ); // rotmat := matrix describing orientation of Cursegp
  210. vm_vec_rotate(&tdest,&vec_dir,&rotmat); // tdest := vec_dir in reference frame of Cursegp
  211. vec_dir = tdest;
  212. vm_vector_2_matrix(&rotmat2,&vec_dir,NULL,NULL);
  213. // mprintf(0, "[ [%6.2f %6.2f %6.2f]", f2fl(rotmat2.m1), f2fl(rotmat2.m2), f2fl(rotmat2.m3));
  214. // mprintf(0, " [%6.2f %6.2f %6.2f]", f2fl(rotmat2.m4), f2fl(rotmat2.m5), f2fl(rotmat2.m6));
  215. // mprintf(0, " [%6.2f %6.2f %6.2f] ]\n", f2fl(rotmat2.m7), f2fl(rotmat2.m8), f2fl(rotmat2.m9));
  216. med_rotate_segment( Cursegp, &rotmat2 );
  217. prev_point = coord;
  218. Curside = Side_opposite[AttachSide];
  219. CurveSegs[CurveNumSegs]=Cursegp;
  220. CurveNumSegs++;
  221. } else return 0;
  222. }
  223. extract_up_vector_from_segment( Cursegp,&tvec );
  224. uangle = vm_vec_delta_ang( &tvec, &r4t, &r4 );
  225. if (uangle >= F1_0 * 1/8) uangle -= F1_0 * 1/4;
  226. if (uangle >= F1_0 * 1/8) uangle -= F1_0 * 1/4;
  227. if (uangle <= -F1_0 * 1/8) uangle += F1_0 * 1/4;
  228. if (uangle <= -F1_0 * 1/8) uangle += F1_0 * 1/4;
  229. extract_right_vector_from_segment( Cursegp,&tvec );
  230. rangle = vm_vec_delta_ang( &tvec, &r4t, &r4 );
  231. if (rangle >= F1_0/8) rangle -= F1_0/4;
  232. if (rangle >= F1_0/8) rangle -= F1_0/4;
  233. if (rangle <= -F1_0/8) rangle += F1_0/4;
  234. if (rangle <= -F1_0/8) rangle += F1_0/4;
  235. if ((uangle != 0) && (rangle != 0)) {
  236. maxscale = CurveNumSegs*F1_0;
  237. // mprintf(0, "Banked Curve Generation.. %f.\n", f2fl(maxscale));
  238. generate_banked_curve(maxscale, coeffs);
  239. }
  240. if (CurveNumSegs) {
  241. med_form_bridge_segment( Cursegp, Side_opposite[AttachSide], Markedsegp, Markedside );
  242. CurveSegs[CurveNumSegs] = &Segments[ Markedsegp->children[Markedside] ];
  243. CurveNumSegs++;
  244. }
  245. Cursegp = OriginalSeg;
  246. Curside = OriginalSide;
  247. med_create_new_segment_from_cursegp();
  248. //warn_if_concave_segments();
  249. if (CurveNumSegs) return 1;
  250. else return 0;
  251. }
  252. void generate_banked_curve(fix maxscale, vms_equation coeffs) {
  253. vms_vector vec_dir, tvec, b4r4t;
  254. vms_vector coord,prev_point;
  255. fix enddist, nextdist;
  256. int firstsegflag;
  257. fixang rangle, uangle, angle, scaled_ang;
  258. fix t;
  259. if (CurveNumSegs) {
  260. extract_up_vector_from_segment( Cursegp,&b4r4t );
  261. uangle = vm_vec_delta_ang( &b4r4t, &r4t, &r4 );
  262. if (uangle >= F1_0 * 1/8) uangle -= F1_0 * 1/4;
  263. if (uangle >= F1_0 * 1/8) uangle -= F1_0 * 1/4;
  264. if (uangle <= -F1_0 * 1/8) uangle += F1_0 * 1/4;
  265. if (uangle <= -F1_0 * 1/8) uangle += F1_0 * 1/4;
  266. // mprintf(0, "up angle %f\n", f2fl(uangle)*360);
  267. extract_right_vector_from_segment( Cursegp,&b4r4t );
  268. rangle = vm_vec_delta_ang( &b4r4t, &r4t, &r4 );
  269. if (rangle >= F1_0/8) rangle -= F1_0/4;
  270. if (rangle >= F1_0/8) rangle -= F1_0/4;
  271. if (rangle <= -F1_0/8) rangle += F1_0/4;
  272. if (rangle <= -F1_0/8) rangle += F1_0/4;
  273. // mprintf(0, "right angle %f\n", f2fl(rangle)*360);
  274. angle = uangle;
  275. if (abs(rangle) < abs(uangle)) angle = rangle;
  276. delete_curve();
  277. coord = prev_point = p1;
  278. #define MAGIC_NUM 0.707*F1_0
  279. if (maxscale)
  280. scaled_ang = fixdiv(angle,fixmul(maxscale,MAGIC_NUM));
  281. mprintf((0, "scaled angle = %f\n", f2fl(scaled_ang)));
  282. t=0;
  283. tvec = r1save;
  284. firstsegflag = 1;
  285. enddist = F1_0; nextdist = 0;
  286. while ( enddist > fixmul( nextdist, 1.5*F1_0 )) {
  287. vms_matrix rotmat,rotmat2;
  288. vms_vector tdest;
  289. if (firstsegflag==1)
  290. firstsegflag=0;
  291. else
  292. extract_forward_vector_from_segment(Cursegp, &tvec);
  293. nextdist = vm_vec_mag(&tvec); // nextdist := distance to next point
  294. t = curve_dist(&coeffs, 3, t, &prev_point, nextdist); // t = argument at which function is forward vector magnitude units away from prev_point (in 3-space, not along curve)
  295. coord = evaluate_curve(&coeffs, 3, t); // coord := point about forward vector magnitude units away from prev_point
  296. enddist = vm_vec_dist(&coord, &p4); // enddist := distance from current to end point, vec_dir used as a temporary variable
  297. //vm_vec_normalize(vm_vec_sub(&vec_dir, &coord, &prev_point));
  298. vm_vec_normalized_dir(&vec_dir, &coord, &prev_point);
  299. if (!med_attach_segment( Cursegp, &New_segment, Curside, AttachSide )) {
  300. med_extract_matrix_from_segment( Cursegp,&rotmat ); // rotmat := matrix describing orientation of Cursegp
  301. vm_vec_rotate(&tdest,&vec_dir,&rotmat); // tdest := vec_dir in reference frame of Cursegp
  302. vec_dir = tdest;
  303. vm_vec_ang_2_matrix(&rotmat2,&vec_dir,scaled_ang);
  304. // mprintf((0, "[ [%6.2f %6.2f %6.2f]", f2fl(rotmat2.m1), f2fl(rotmat2.m2), f2fl(rotmat2.m3)));
  305. // mprintf((0, " [%6.2f %6.2f %6.2f]", f2fl(rotmat2.m4), f2fl(rotmat2.m5), f2fl(rotmat2.m6)));
  306. // mprintf((0, " [%6.2f %6.2f %6.2f] ]\n", f2fl(rotmat2.m7), f2fl(rotmat2.m8), f2fl(rotmat2.m9)));
  307. med_rotate_segment( Cursegp, &rotmat2 );
  308. prev_point = coord;
  309. Curside = Side_opposite[AttachSide];
  310. CurveSegs[CurveNumSegs]=Cursegp;
  311. CurveNumSegs++;
  312. }
  313. }
  314. }
  315. }
  316. void delete_curve() {
  317. int i;
  318. for (i=0; i<CurveNumSegs; i++) {
  319. // mprintf((0, "[%d] %d\n", i, CurveSegs[i]->segnum ));
  320. if (CurveSegs[i]->segnum != -1)
  321. med_delete_segment(CurveSegs[i]);
  322. }
  323. Markedsegp = OriginalMarkedSeg;
  324. Markedside = OriginalMarkedSide;
  325. Cursegp = OriginalSeg;
  326. Curside = OriginalSide;
  327. med_create_new_segment_from_cursegp();
  328. CurveNumSegs = 0;
  329. // mprintf((0, "Num_segments %d\n", Num_segments));
  330. //editor_status("");
  331. //warn_if_concave_segments();
  332. }
  333. /*
  334. void main() {
  335. vms_vector p1;
  336. vms_vector p4;
  337. vms_vector r1;
  338. vms_vector r4;
  339. vms_equation coeffs;
  340. float x, y, z;
  341. vms_vector test, test2, tvec;
  342. fix t, t0;
  343. fix distance, dist;
  344. int key;
  345. key_init();
  346. printf("Enter p1 (x,y,z): ");
  347. scanf("%f %f %f", &x, &y, &z);
  348. p1.x = x*F1_0; p1.y = y*F1_0; p1.z = z*F1_0;
  349. printf("Enter p4 (x,y,z): ");
  350. scanf("%f %f %f", &x, &y, &z);
  351. p4.x = x*F1_0; p4.y = y*F1_0; p4.z = z*F1_0;
  352. printf("Enter r1 <x,y,z>: ");
  353. scanf("%f %f %f", &x, &y, &z);
  354. r1.x = x*F1_0; r1.y = y*F1_0; r1.z = z*F1_0;
  355. printf("Enter r4 <x,y,z>: ");
  356. scanf("%f %f %f", &x, &y, &z);
  357. r4.x = x*F1_0; r4.y = y*F1_0; r4.z = z*F1_0;
  358. create_curve( &p1, &p4, &r1, &r4, &coeffs );
  359. printf("\nQ(t) = ");
  360. printf("x [%6.3f %6.3f %6.3f %6.3f]\n", f2fl(coeffs.x3), f2fl(coeffs.x2), f2fl(coeffs.x1), f2fl(coeffs.x0));
  361. printf(" y [%6.3f %6.3f %6.3f %6.3f]\n", f2fl(coeffs.y3), f2fl(coeffs.y2), f2fl(coeffs.y1), f2fl(coeffs.y0));
  362. printf(" z [%6.3f %6.3f %6.3f %6.3f]\n", f2fl(coeffs.z3), f2fl(coeffs.z2), f2fl(coeffs.z1), f2fl(coeffs.z0));
  363. printf("\nChecking direction vectors.\n");
  364. for (t=0*F1_0;t<1*F1_0;t+=0.1*F1_0) {
  365. curve_dir(&coeffs, 3, t, &test);
  366. printf(" t = %.3f dir = <%6.3f, %6.3f, %6.3f >\n", f2fl(t), f2fl(test.x), f2fl(test.y), f2fl(test.z) );
  367. }
  368. printf("\nChecking distance function.\n");
  369. printf("Enter a distance: ");
  370. scanf("%f", &x);
  371. distance = x*F1_0;
  372. printf("Enter a (0<t<1) value: ");
  373. scanf("%f", &y);
  374. t0 = y*F1_0;
  375. gr_init(15); // 800x600 mode
  376. plot_parametric(&coeffs, 0*F1_0, 1*F1_0, 0.05*F1_0);
  377. test = evaluate_curve(&coeffs, 3, t0);
  378. t = curve_dist(&coeffs, 3, t0, &test, distance);
  379. test2 = evaluate_curve(&coeffs, 3, t);
  380. dist = vm_vec_mag(vm_vec_sub(&tvec, &test, &test2));
  381. if (t != -1*F1_0) {
  382. gr_setcolor(14);
  383. gr_rect( 74+f2fl(test.x), 289-f2fl(test.z), 76+f2fl(test.x), 291-f2fl(test.z) );
  384. gr_rect( 74+f2fl(test.x), 559-f2fl(test.y), 76+f2fl(test.x), 561-f2fl(test.y) );
  385. gr_rect( 474+f2fl(test.z), 559-f2fl(test.y), 476+f2fl(test.z), 561-f2fl(test.y) );
  386. gr_setcolor(13);
  387. gr_rect( 74+f2fl(test2.x), 289-f2fl(test2.z), 76+f2fl(test2.x), 291-f2fl(test2.z) );
  388. gr_rect( 74+f2fl(test2.x), 559-f2fl(test2.y), 76+f2fl(test2.x), 561-f2fl(test2.y) );
  389. gr_rect( 474+f2fl(test2.z), 559-f2fl(test2.y), 476+f2fl(test2.z), 561-f2fl(test2.y) );
  390. }
  391. key = -1;
  392. while (1)
  393. if (key == KEY_ESC) break;
  394. else key = key_getch();
  395. gr_close();
  396. key_close();
  397. if (t == -1*F1_0) {
  398. printf("From t=%.3f to t=1.000, ", f2fl(t0));
  399. printf("two points separated by the distance %.3f\n do not exist on this curve.\n", x);
  400. }
  401. else {
  402. printf("\nThe distance between points at:\n");
  403. printf(" t0 = %.3f ( %6.3f,%6.3f,%6.3f ) and\n", f2fl(t0), f2fl(test.x), f2fl(test.y), f2fl(test.z));
  404. printf(" t = %.3f ( %6.3f,%6.3f,%6.3f ) is:\n", f2fl(t), f2fl(test2.x), f2fl(test2.y), f2fl(test2.z));
  405. printf(" expected: %.3f\n", x);
  406. printf(" actual : %.3f\n", f2fl(dist) );
  407. }
  408. }
  409. */