home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-04-28 | 40.9 KB | 1,662 lines |
- Newsgroups: comp.sources.x
- From: dmd@gradient.cis.upenn.edu (Douglas DeCarlo)
- Subject: v19i056: xspringies - it's a spring simulator...no, it's a game, Part04/16
- Message-ID: <1993Mar26.161219.9691@sparky.imd.sterling.com>
- X-Md4-Signature: 85451a3e15a4c718bfe01bf641f610eb
- Date: Fri, 26 Mar 1993 16:12:19 GMT
- Approved: chris@sparky.imd.sterling.com
-
- Submitted-by: dmd@gradient.cis.upenn.edu (Douglas DeCarlo)
- Posting-number: Volume 19, Issue 56
- Archive-name: xspringies/part04
- Environment: X11
- Supersedes: xspringies: Volume 14, Issue 25-30
-
- #!/bin/sh
- # to extract, remove the header and type "sh filename"
- if `test ! -d ./lib`
- then
- mkdir ./lib
- echo "mkdir ./lib"
- fi
- if `test ! -s ./lib/zingy.xsp`
- then
- echo "writting ./lib/zingy.xsp"
- cat > ./lib/zingy.xsp << '\BARFOO\'
- #1.0 *** XSpringies data file
- cmas 1
- elas 1
- kspr 10
- kdmp 1
- fixm 1
- shws 1
- cent -1
- frce 0 0 10 0
- frce 1 0 5 2
- frce 2 0 10 0
- frce 3 0 10000 1
- visc 0
- stck 0
- step 0.025
- prec 1
- adpt 0
- gsnp 20 0
- wall 1 1 1 1
- mass 1 171.935289037 308.205975009 -32.3569475661 -11.1228790452 1 1
- mass 2 184.344717499 319.761393874 -33.9275114697 -9.32414881597 1 1
- mass 3 199.652059239 329.255781513 -34.1569967299 -8.50938001294 1 1
- mass 4 215.756366128 332.754910417 -33.7557679284 -8.85344594067 1 1
- mass 5 232.636046245 329.179539271 -33.7944219518 -10.483547665 1 1
- mass 6 247.27317969 319.57188562 -34.1578742598 -10.4650492354 1 1
- mass 7 258.4947709 304.027351791 -33.6341992102 -10.5242309965 1 1
- mass 8 269.901010184 286.897041567 -19.8119971656 -1.50878323362 1 1
- mass 9 281.237342589 275.250479271 -17.223309771 0.760714273218 1 1
- mass 10 295.842676388 264.65162579 -17.3397948693 1.26456227504 1 1
- mass 11 311.902346148 266.100747153 -17.3316231365 -0.118343196776 1 1
- mass 12 327.141125787 274.688346675 -16.2094197998 -1.8325047945 1 1
- mass 13 337.343768574 284.456765366 -13.8181100654 -4.09258266147 1 1
- mass 14 348.539137599 296.239213714 -15.6027386294 -1.98672964671 1 1
- mass 15 268.80967555 440.790258556 -33.7795989133 -7.93987110031 1 1
- mass 16 257.899232823 162.277289195 -14.772834743 -2.80664196866 1 1
- mass 17 258 478 0 0 -1 1
- mass 18 259 123 0 0 -1 1
- spng 1 7 15 30 1 137.091210513
- spng 2 15 6 30 1 123.17873193
- spng 3 5 15 30 1 117.443603487
- spng 4 15 4 30 1 120.42009799
- spng 5 3 15 30 1 131.228807813
- spng 6 15 2 30 1 147.566933966
- spng 7 1 15 30 1 164.195006014
- spng 8 15 8 30 1 153.209007568
- spng 9 9 15 30 1 165.215011425
- spng 10 15 10 30 1 177.485210651
- spng 11 11 15 30 1 179.401783715
- spng 12 15 12 30 1 175.855053951
- spng 13 13 15 30 1 170.836178838
- spng 14 15 14 30 1 165.680415258
- spng 15 1 16 30 1 169.743924781
- spng 16 16 2 30 1 174.002873539
- spng 17 3 16 30 1 176.78235206
- spng 18 16 4 30 1 175.282628917
- spng 19 5 16 30 1 168.267643949
- spng 20 16 6 30 1 157.03502794
- spng 21 7 16 30 1 141.127601836
- spng 22 16 8 30 1 125.195846576
- spng 23 9 16 30 1 115.572488076
- spng 24 16 10 30 1 109.416634933
- spng 25 11 16 30 1 117.200682592
- spng 26 16 12 30 1 132.098448136
- spng 27 13 16 30 1 145.773797371
- spng 28 16 14 30 1 161.75598907
- spng 29 1 2 100 5 16.9705627485
- spng 30 2 3 100 5 18.0277563773
- spng 31 3 4 100 5 16.4924225025
- spng 32 4 5 100 5 17.2626765016
- spng 33 5 6 100 5 17.4928556845
- spng 34 6 7 100 5 19.2093727123
- spng 35 7 8 100 5 20.6155281281
- spng 36 8 9 100 5 16.2788205961
- spng 37 9 10 100 5 18.0277563773
- spng 38 10 11 100 5 16.1245154966
- spng 39 11 12 100 5 17.4928556845
- spng 40 12 13 100 5 14.1421356237
- spng 41 13 14 100 5 16.2788205961
- spng 42 17 15 100 5 38
- spng 43 16 18 100 5 39
- spng 44 1 3 100 5 34.8281495345
- spng 45 2 4 100 5 34.0147027034
- spng 46 3 5 100 5 33.0151480384
- spng 47 4 6 100 5 34.1760149813
- spng 48 5 7 100 5 36.1247837364
- spng 49 6 8 100 5 39.8246155035
- spng 50 7 9 100 5 36.7967389859
- spng 51 8 10 100 5 34.205262753
- spng 52 9 11 100 5 32.0156211872
- spng 53 10 12 100 5 32.8937684068
- spng 54 11 13 100 5 31.4006369362
- spng 55 12 14 100 5 30.4138126515
- spng 56 1 4 100 5 50.2493781056
- spng 57 2 5 100 5 49.244289009
- spng 58 3 6 100 5 48.6621002424
- spng 59 4 7 100 5 51.6236379966
- spng 60 5 8 100 5 56.5685424949
- spng 61 6 9 100 5 55.9732078766
- spng 62 7 10 100 5 54.4885309033
- spng 63 8 11 100 5 47.0106370942
- spng 64 9 12 100 5 46.0108682813
- spng 65 10 13 100 5 46.0651712251
- spng 66 11 14 100 5 47.5078940809
- \BARFOO\
- else
- echo "will not over write ./lib/zingy.xsp"
- fi
- if `test ! -s ./lib/zwave.xsp`
- then
- echo "writting ./lib/zwave.xsp"
- cat > ./lib/zwave.xsp << '\BARFOO\'
- #1.0 *** XSpringies data file
- cmas 0.5
- elas 1
- kspr 100
- kdmp 1
- fixm 1
- shws 1
- cent -1
- frce 0 0 10 0
- frce 1 0 5 2
- frce 2 0 10 0
- frce 3 0 10000 1
- visc 0
- stck 0
- step 0.025
- prec 1
- adpt 0
- gsnp 20 1
- wall 0 0 0 0
- mass 1 21.639729 470.92505 13.392069 -44.74031 -0.5 1
- mass 2 51.711478 470.92861 2.9402828e-13 -1.9192124e-12 0.5 1
- mass 3 81.64936 470.93216 -8.6518787e-14 2.0792841e-12 0.5 1
- mass 4 111.58724 470.93571 3.6924324e-13 -2.1335293e-12 0.5 1
- mass 5 141.52512 470.93926 2.3528885e-14 1.228292e-12 0.5 1
- mass 6 171.463 470.9428 -1.2769644e-13 9.5427571e-15 0.5 1
- mass 7 201.40089 470.94635 -1.576758e-16 3.1216151e-13 0.5 1
- mass 8 231.33877 470.9499 -5.5718641e-13 4.9338204e-13 0.5 1
- mass 9 261.27665 470.95345 1.1301261e-12 -1.0338929e-12 0.5 1
- mass 10 291.21453 470.957 4.4260768e-13 1.1627536e-12 0.5 1
- mass 11 321.15241 470.96055 1.536321e-13 -1.938644e-12 0.5 1
- mass 12 351.09029 470.9641 -7.5005664e-14 2.7781487e-13 0.5 1
- mass 13 381.02817 470.96765 -3.1045444e-13 8.5054484e-13 0.5 1
- mass 14 410.96606 470.9712 -7.3361805e-13 1.5346888e-12 0.5 1
- mass 15 440.90394 470.97474 7.4892138e-13 -1.7485381e-13 0.5 1
- mass 16 470.84182 470.97829 5.6970896e-13 -1.4606473e-12 0.5 1
- mass 17 500.7797 470.98184 4.6491659e-13 1.1677946e-12 0.5 1
- mass 18 530.71758 470.98539 6.7910642e-13 1.116373e-12 0.5 1
- mass 19 560.65546 470.98894 5.2756933e-13 -3.9238237e-12 0.5 1
- mass 20 590.59334 470.99249 4.5201415e-13 1.9612051e-12 0.5 1
- mass 21 620.44133 470.99603 8.9880047 8.5159468 -0.5 1
- mass 22 590.61239 450.97498 -1.2519178e-12 8.0057266e-13 0.5 1
- mass 23 560.68208 430.88589 1.2166525e-12 1.3557465e-13 0.5 1
- mass 24 530.75177 410.7968 6.3251047e-13 1.3617275e-12 0.5 1
- mass 25 500.82146 390.70771 -2.18909e-12 2.8087122e-12 0.5 1
- mass 26 470.89115 370.61862 -1.5243802e-12 1.3536881e-12 0.5 1
- mass 27 440.96083 350.52953 -9.3463005e-13 2.0526322e-12 0.5 1
- mass 28 411.03052 330.44044 -1.9782396e-12 5.9056097e-13 0.5 1
- mass 29 381.10021 310.35135 9.9737993e-13 -1.0340691e-12 0.5 1
- mass 30 351.1699 290.26226 1.2384388e-13 3.738492e-13 0.5 1
- mass 31 321.23959 270.17317 -1.9281981e-12 1.6168234e-14 0.5 1
- mass 32 291.30927 250.08408 -1.6838465e-13 1.7544632e-12 0.5 1
- mass 33 261.37896 229.99499 -1.1266675e-12 -3.3049241e-13 0.5 1
- mass 34 231.44865 209.9059 -4.2246829e-13 8.6427946e-14 0.5 1
- mass 35 201.51834 189.81681 -1.369676e-12 9.4255072e-13 0.5 1
- mass 36 171.58803 169.72772 -7.700747e-13 1.494e-13 0.5 1
- mass 37 141.65771 149.63863 -5.5405463e-13 1.1322969e-12 0.5 1
- mass 38 111.7274 129.54954 -5.5710249e-13 7.0186294e-13 0.5 1
- mass 39 81.797091 109.46045 -1.6334023e-12 2.9069384e-12 0.5 1
- mass 40 51.866779 89.371356 -1.362396e-12 2.1966162e-12 0.5 1
- mass 41 22.105673 69.395837 -9.6851415 -22.137054 -0.5 1
- mass 42 51.908169 69.425832 1.0139043e-05 -0.00062120184 0.5 1
- mass 43 81.807739 69.456051 4.6818224e-06 -0.0009341814 0.5 1
- mass 44 111.70731 69.486334 -2.4960264e-06 -0.00033427139 0.5 1
- mass 45 141.60688 69.516565 -1.3791049e-06 5.3683436e-05 0.5 1
- mass 46 171.50645 69.546882 4.6598698e-06 -0.00076901234 0.5 1
- mass 47 201.40602 69.577237 4.5393996e-06 -0.0004633936 0.5 1
- mass 48 231.30559 69.607554 -4.2325143e-07 -0.00012803614 0.5 1
- mass 49 261.20516 69.637839 -3.6739255e-06 -0.00078432669 0.5 1
- mass 50 291.10473 69.667966 -4.5766946e-06 -0.00085760696 0.5 1
- mass 51 321.0043 69.698112 -4.4936329e-06 0.00012400123 0.5 1
- mass 52 350.90387 69.728366 -2.2494145e-06 -0.00017028775 0.5 1
- mass 53 380.80344 69.758602 -1.4282967e-06 0.0001854156 0.5 1
- mass 54 410.70301 69.788789 -3.3811341e-06 0.0011435902 0.5 1
- mass 55 440.60258 69.81895 -5.3698626e-06 0.00092986523 0.5 1
- mass 56 470.50215 69.849121 -4.7984152e-06 -0.00052070023 0.5 1
- mass 57 500.40172 69.879302 -2.9327322e-06 -0.00096433796 0.5 1
- mass 58 530.30129 69.909444 -1.9193701e-06 0.0003473992 0.5 1
- mass 59 560.20086 69.939621 -7.2717789e-07 0.00067834358 0.5 1
- mass 60 590.10043 69.96986 -6.7152209e-07 0.00095229897 0.5 1
- mass 61 620 70 -1.4489569e-17 0 -0.5 1
- spng 1 1 2 100 1 8
- spng 2 2 3 100 1 8
- spng 3 3 4 100 1 8
- spng 4 4 5 100 1 8
- spng 5 5 6 100 1 8
- spng 6 6 7 100 1 8
- spng 7 7 8 100 1 8
- spng 8 8 9 100 1 8
- spng 9 9 10 100 1 8
- spng 10 10 11 100 1 8
- spng 11 11 12 100 1 8
- spng 12 12 13 100 1 8
- spng 13 13 14 100 1 8
- spng 14 14 15 100 1 8
- spng 15 15 16 100 1 8
- spng 16 16 17 100 1 8
- spng 17 17 18 100 1 8
- spng 18 18 19 100 1 8
- spng 19 19 20 100 1 8
- spng 20 20 21 100 1 8
- spng 21 21 22 100 1 8
- spng 22 22 23 100 1 8
- spng 23 23 24 100 1 8
- spng 24 24 25 100 1 8
- spng 25 25 26 100 1 8
- spng 26 26 27 100 1 8
- spng 27 27 28 100 1 8
- spng 28 28 29 100 1 8
- spng 29 29 30 100 1 8
- spng 30 30 31 100 1 8
- spng 31 31 32 100 1 8
- spng 32 32 33 100 1 8
- spng 33 33 34 100 1 8
- spng 34 34 35 100 1 8
- spng 35 35 36 100 1 8
- spng 36 36 37 100 1 8
- spng 37 37 38 100 1 8
- spng 38 38 39 100 1 8
- spng 39 39 40 100 1 8
- spng 40 40 41 100 1 8
- spng 41 41 42 100 1 8
- spng 42 42 43 100 1 8
- spng 43 43 44 100 1 8
- spng 44 44 45 100 1 8
- spng 45 45 46 100 1 8
- spng 46 46 47 100 1 8
- spng 47 47 48 100 1 8
- spng 48 48 49 100 1 8
- spng 49 49 50 100 1 8
- spng 50 50 51 100 1 8
- spng 51 51 52 100 1 8
- spng 52 52 53 100 1 8
- spng 53 53 54 100 1 8
- spng 54 54 55 100 1 8
- spng 55 55 56 100 1 8
- spng 56 56 57 100 1 8
- spng 57 57 58 100 1 8
- spng 58 58 59 100 1 8
- spng 59 59 60 100 1 8
- spng 60 60 61 100 1 8
- \BARFOO\
- else
- echo "will not over write ./lib/zwave.xsp"
- fi
- if `test ! -s ./misc.c`
- then
- echo "writting ./misc.c"
- cat > ./misc.c << '\BARFOO\'
- /* misc.c -- misc utility routines for xspringies
- * Copyright (C) 1991,1992 Douglas M. DeCarlo
- *
- * This file is part of XSpringies, a mass and spring simulation system for X
- *
- * XSpringies is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 1, or (at your option)
- * any later version.
- *
- * XSpringies is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with XSpringies; see the file COPYING. If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
- #include "defs.h"
-
- #if defined(__STRICT_BSD__) || defined(__STDC__) || defined(_ANSI_C_SOURCE)
- extern void *malloc(), *realloc();
- #else
- extern char *malloc(), *realloc();
- #endif
-
- /* malloc space, and call fatal if allocation fails */
- char *xmalloc (size)
- int size;
- {
- register char *tmp = (char *)malloc(size);
-
- if (!tmp)
- fatal ("Out of memory");
-
- return tmp;
- }
-
- /* realloc space, and call fatal if re-allocation fails
- (also, call malloc if ptr is NULL) */
- char *xrealloc (ptr, size)
- char *ptr;
- int size;
- {
- register char *tmp;
-
- if (ptr == NULL)
- return (char *)xmalloc(size);
-
- tmp = (char *)realloc(ptr, size);
-
- if (!tmp)
- fatal ("Out of memory");
-
- return tmp;
- }
- \BARFOO\
- else
- echo "will not over write ./misc.c"
- fi
- if `test ! -s ./obj.c`
- then
- echo "writting ./obj.c"
- cat > ./obj.c << '\BARFOO\'
- /* obj.c -- xspringies object (masses, springs) handling
- * Copyright (C) 1991,1992 Douglas M. DeCarlo
- *
- * This file is part of XSpringies, a mass and spring simulation system for X
- *
- * XSpringies is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 1, or (at your option)
- * any later version.
- *
- * XSpringies is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with XSpringies; see the file COPYING. If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
- #include "defs.h"
- #include "obj.h"
-
- #define MPROXIMITY 8.0
- #define SPROXIMITY 8.0
-
- /* Object globals */
- mass *masses;
- spring *springs;
- int num_mass, num_spring;
- static int num_mass_alloc, num_spring_alloc;
- int fake_mass, fake_spring;
- static mass *masses_save = NULL;
- static spring *springs_save = NULL;
- static int num_mass_saved, num_mass_savedalloc, num_spring_saved, num_spring_savedalloc;
-
- /* init_objects: create an initial set of masses and
- springs to work with
- */
- void init_objects()
- {
- /* Create initial objects */
- num_mass = 0;
- num_mass_alloc = ALLOC_SIZE * 2;
- masses = (mass *)xmalloc(sizeof(mass) * num_mass_alloc);
-
- num_spring = 0;
- num_spring_alloc = ALLOC_SIZE;
- springs = (spring *)xmalloc(sizeof(spring) * num_spring_alloc);
-
- fake_mass = create_mass();
- masses[fake_mass].status = S_FIXED;
- fake_spring = create_spring();
- springs[fake_spring].status = 0;
-
- add_massparent(fake_mass, fake_spring);
- springs[fake_spring].m1 = fake_mass;
- }
-
- void attach_fake_spring(tomass)
- int tomass;
- {
- add_massparent(fake_mass, fake_spring);
- springs[fake_spring].m2 = tomass;
- springs[fake_spring].status |= S_ALIVE;
- springs[fake_spring].ks = mst.cur_ks;
- springs[fake_spring].kd = mst.cur_kd;
- }
-
- void kill_fake_spring()
- {
- springs[fake_spring].status &= ~S_ALIVE;
- }
-
- void move_fake_mass(mx, my)
- int mx, my;
- {
- masses[fake_mass].x = mx;
- masses[fake_mass].y = my;
- }
-
- /* create_mass: return the index for a new mass,
- possibly allocating more space if necesary
- */
- int create_mass()
- {
- if (num_mass >= num_mass_alloc) {
- /* Allocate more masses */
- num_mass_alloc += ALLOC_SIZE;
- masses = (mass *)xrealloc(masses, sizeof(mass) * num_mass_alloc);
- }
-
- /* Set parameters for new mass */
- masses[num_mass].x = masses[num_mass].y = 0.0;
- masses[num_mass].vx = masses[num_mass].vy = 0.0;
- masses[num_mass].ax = masses[num_mass].ay = 0.0;
- masses[num_mass].mass = masses[num_mass].elastic = 0.0;
- masses[num_mass].radius = masses[num_mass].num_pars = 0;
- masses[num_mass].pars = NULL;
- masses[num_mass].status = S_ALIVE;
-
- /* Return next unused mass */
- return num_mass++;
- }
-
- /* create_spring: return the index for a new spring,
- possibly allocating more space if necesary
- */
- int create_spring()
- {
- if (num_spring >= num_spring_alloc) {
- /* Allocate more springs */
- num_spring_alloc += ALLOC_SIZE;
- springs = (spring *)xrealloc(springs, sizeof(spring) * num_spring_alloc);
- }
-
- /* Set parameters for new spring */
- springs[num_spring].ks = springs[num_spring].kd = 0.0;
- springs[num_spring].restlen = 0.0;
- springs[num_spring].m1 = springs[num_spring].m2 = 0;
- springs[num_spring].status = S_ALIVE;
-
- /* Return next unused spring */
- return num_spring++;
- }
-
- void add_massparent(which, parent)
- int which, parent;
- {
- int len = masses[which].num_pars++;
-
- masses[which].pars = (int *)xrealloc(masses[which].pars, (len + 1) * sizeof(int));
-
- masses[which].pars[len] = parent;
- }
-
- void del_massparent(which, parent)
- int which, parent;
- {
- int i;
-
- if (masses[which].status & S_ALIVE) {
- for (i = 0; i < masses[which].num_pars; i++) {
- if (masses[which].pars[i] == parent) {
- if (i == masses[which].num_pars - 1) {
- masses[which].num_pars--;
- } else {
- masses[which].pars[i] = masses[which].pars[--masses[which].num_pars];
- }
- return;
- }
- }
- }
- }
-
- /* delete_spring: delete a particular spring
- */
- void delete_spring(which)
- int which;
- {
- if (springs[which].status & S_ALIVE) {
- springs[which].status = 0;
- del_massparent(springs[which].m1, which);
- del_massparent(springs[which].m2, which);
- }
- }
-
- /* delete_mass: delete a particular mass, and all springs
- directly attached to it
- */
- void delete_mass(which)
- int which;
- {
- int i;
-
- if (masses[which].status & S_ALIVE) {
- masses[which].status = 0;
-
- /* Delete all springs connected to it */
- for (i = 0; i < masses[which].num_pars; i++) {
- delete_spring(masses[which].pars[i]);
- }
- }
-
- if (which == mst.center_id)
- mst.center_id = -1;
- }
-
- /* delete_selected: delete all objects which
- are currently selected
- */
- void delete_selected()
- {
- int i;
-
- for (i = 0; i < num_mass; i++) {
- if (masses[i].status & S_SELECTED) {
- delete_mass(i);
- }
- }
-
- for (i = 0; i < num_spring; i++) {
- if (springs[i].status & S_SELECTED) {
- delete_spring(i);
- }
- }
- }
-
- void delete_all()
- {
- int i;
-
- for (i = 0; i < num_mass; i++) {
- free(masses[i].pars);
- }
- free(masses);
- num_mass = num_mass_alloc = 0;
- free(springs);
- num_spring = num_spring_alloc = 0;
- mst.center_id = -1;
- }
-
- void reconnect_masses()
- {
- int i;
-
- for (i = 0; i < num_mass; i++) {
- masses[i].num_pars = 0;
- masses[i].pars = NULL;
- }
-
- for (i = 0; i < num_spring; i++) {
- add_massparent(springs[i].m1, i);
- add_massparent(springs[i].m2, i);
- }
- }
-
- void restore_state()
- {
- delete_all();
-
- if (masses_save != NULL) {
- num_mass = num_mass_saved;
- num_mass_alloc = num_mass_savedalloc;
- num_spring = num_spring_saved;
- num_spring_alloc = num_spring_savedalloc;
-
- masses = (mass *)xmalloc(sizeof(mass) * num_mass_alloc);
- bcopy(masses_save, masses, sizeof(mass) * num_mass_alloc);
- springs = (spring *)xmalloc(sizeof(spring) * num_spring_alloc);
- bcopy(springs_save, springs, sizeof(spring) * num_spring_alloc);
-
- reconnect_masses();
- }
- }
-
- void save_state()
- {
- masses_save = (mass *)xmalloc(sizeof(mass) * num_mass_alloc);
- bcopy(masses, masses_save, sizeof(mass) * num_mass_alloc);
- num_mass_saved = num_mass;
- num_mass_savedalloc = num_mass_alloc;
-
- springs_save = (spring *)xmalloc(sizeof(spring) * num_spring_alloc);
- bcopy(springs, springs_save, sizeof(spring) * num_spring_alloc);
- num_spring_saved = num_spring;
- num_spring_savedalloc = num_spring_alloc;
- }
-
- /* nearest_object: Find the nearest spring or mass to the position
- (x,y), or return -1 if none are close. Set is_mass accordingly
- */
- int nearest_object(x, y, is_mass)
- int x, y;
- boolean *is_mass;
- {
- int i, closest = -1;
- double dist, min_dist = MPROXIMITY * MPROXIMITY, rating, min_rating = draw_wid * draw_ht;
- boolean masses_only = *is_mass;
-
- *is_mass = TRUE;
-
- if (masses_only)
- min_dist = min_dist * 36;
-
- /* Find closest mass */
- for (i = 0; i < num_mass; i++) {
- if (masses[i].status & S_ALIVE) {
- if ((dist = SQR(masses[i].x - (double)x) + SQR(masses[i].y - (double)y) - (double)SQR(masses[i].radius)) < min_dist) {
- rating = SQR(masses[i].x - (double)x) + SQR(masses[i].y - (double)y);
- if (rating < min_rating) {
- min_dist = dist;
- min_rating = rating;
- closest = i;
- }
- }
- }
- }
-
- if (closest != -1)
- return closest;
-
- if (masses_only)
- return -1;
-
- *is_mass = TRUE;
-
- min_dist = SPROXIMITY;
-
- /* Find closest spring */
- for (i = 0; i < num_spring; i++) {
- double x1, x2, y1, y2;
-
- if (springs[i].status & S_ALIVE) {
- x1 = masses[springs[i].m1].x;
- y1 = masses[springs[i].m1].y;
- x2 = masses[springs[i].m2].x;
- y2 = masses[springs[i].m2].y;
-
- if (x > MIN(x1, x2) - SPROXIMITY && x < MAX(x1, x2) + SPROXIMITY &&
- y > MIN(y1, y2) - SPROXIMITY && y < MAX(y1, y2) + SPROXIMITY) {
- double a1, b1, c1, dAB, d;
-
- a1 = y2 - y1;
- b1 = x1 - x2;
- c1 = y1 * x2 - y2 * x1;
- dAB = sqrt((double)(a1*a1 + b1*b1));
- d = (x * a1 + y * b1 + c1) / dAB;
-
- dist = ABS(d);
-
- if (dist < min_dist) {
- min_dist = dist;
- closest = i;
- *is_mass = FALSE;
- }
- }
- }
- }
-
- return closest;
- }
-
- void eval_selection()
- {
- int i;
- double sel_mass, sel_elas, sel_ks, sel_kd;
- boolean sel_fix;
- boolean found = FALSE, changed = FALSE;
- boolean mass_same, elas_same, ks_same, kd_same, fix_same;
-
- for (i = 0; i < num_mass; i++) {
- if (masses[i].status & S_SELECTED) {
- if (found) {
- if (mass_same && masses[i].mass != sel_mass) {
- mass_same = FALSE;
- }
- if (elas_same && masses[i].elastic != sel_elas) {
- elas_same = FALSE;
- }
- if (fix_same && (masses[i].status & S_FIXED)) {
- fix_same = FALSE;
- }
- } else {
- found = TRUE;
- sel_mass = masses[i].mass;
- mass_same = TRUE;
- sel_elas = masses[i].elastic;
- elas_same = TRUE;
- sel_fix = (masses[i].status & S_FIXED);
- fix_same = TRUE;
- }
- }
- }
-
- if (found) {
- if (mass_same && sel_mass != mst.cur_mass) {
- mst.cur_mass = sel_mass;
- changed = TRUE;
- }
- if (elas_same && sel_elas != mst.cur_rest) {
- mst.cur_rest = sel_elas;
- changed = TRUE;
- }
- if (fix_same && sel_fix != mst.fix_mass) {
- mst.fix_mass = sel_fix;
- changed = TRUE;
- }
- }
-
- found = FALSE;
- for (i = 0; i < num_spring; i++) {
- if (springs[i].status & S_SELECTED) {
- if (found) {
- if (ks_same && springs[i].ks != sel_ks) {
- ks_same = FALSE;
- }
- if (ks_same && springs[i].ks != sel_ks) {
- ks_same = FALSE;
- }
- } else {
- found = TRUE;
- sel_ks = springs[i].ks;
- ks_same = TRUE;
- sel_kd = springs[i].kd;
- kd_same = TRUE;
- }
- }
- }
-
- if (found) {
- if (ks_same && sel_ks != mst.cur_ks) {
- mst.cur_ks = sel_ks;
- changed = TRUE;
- }
- if (kd_same && sel_kd != mst.cur_kd) {
- mst.cur_kd = sel_kd;
- changed = TRUE;
- }
- }
-
- if (changed) {
- redraw_widgets(FALSE);
- }
- }
-
- boolean anything_selected()
- {
- int i;
-
- for (i = 0; i < num_mass; i++) {
- if (masses[i].status & S_SELECTED)
- return TRUE;
- }
- for (i = 0; i < num_spring; i++) {
- if (springs[i].status & S_SELECTED)
- return TRUE;
- }
- return FALSE;
- }
-
- void select_object(selection, is_mass, shifted)
- int selection;
- boolean is_mass, shifted;
- {
- if (is_mass) {
- if (shifted) {
- masses[selection].status ^= S_SELECTED;
- } else {
- masses[selection].status |= S_SELECTED;
- }
- } else {
- if (shifted) {
- springs[selection].status ^= S_SELECTED;
- } else {
- springs[selection].status |= S_SELECTED;
- }
- }
- }
-
- void select_objects(ulx, uly, lrx, lry, shifted)
- int ulx, uly, lrx, lry;
- boolean shifted;
- {
- int i;
-
- for (i = 0; i < num_mass; i++) {
- if (masses[i].status & S_ALIVE) {
- if (ulx <= masses[i].x && masses[i].x <= lrx && uly <= masses[i].y && masses[i].y <= lry) {
- select_object(i, TRUE, FALSE);
- }
- }
- }
-
- for (i = 0; i < num_spring; i++) {
- if (springs[i].status & S_ALIVE) {
- int m1, m2;
-
- m1 = springs[i].m1;
- m2 = springs[i].m2;
-
- if (ulx <= masses[m1].x && masses[m1].x <= lrx && uly <= masses[m1].y && masses[m1].y <= lry &&
- ulx <= masses[m2].x && masses[m2].x <= lrx && uly <= masses[m2].y && masses[m2].y <= lry) {
- select_object(i, FALSE, FALSE);
- }
- }
- }
- }
-
- void unselect_all()
- {
- int i;
-
- for (i = 0; i < num_mass; i++) {
- if (masses[i].status & S_SELECTED) {
- masses[i].status &= ~S_SELECTED;
- }
- }
-
- for (i = 0; i < num_spring; i++) {
- if (springs[i].status & S_SELECTED) {
- springs[i].status &= ~S_SELECTED;
- }
- }
- }
-
- void select_all()
- {
- int i;
-
- for (i = 0; i < num_mass; i++) {
- if (masses[i].status & S_ALIVE) {
- masses[i].status |= S_SELECTED;
- }
- }
-
- for (i = 0; i < num_spring; i++) {
- if (springs[i].status & S_ALIVE) {
- springs[i].status |= S_SELECTED;
- }
- }
- }
-
- void duplicate_selected()
- {
- int i, j, *mapfrom, *mapto, num_map, num_map_alloc, spring_start;
- int which;
-
- spring_start = num_spring;
-
- num_map = 0;
- num_map_alloc = ALLOC_SIZE;
- mapfrom = (int *)xmalloc(sizeof(int) * num_map_alloc);
- mapto = (int *)xmalloc(sizeof(int) * num_map_alloc);
-
- for (i = 0; i < num_mass; i++) {
- if (masses[i].status & S_SELECTED) {
- if (num_map >= num_map_alloc) {
- num_map_alloc += ALLOC_SIZE;
- mapfrom = (int *)xrealloc(mapfrom, sizeof(int) * num_map_alloc);
- mapto = (int *)xrealloc(mapto, sizeof(int) * num_map_alloc);
- }
-
- which = create_mass();
- mapto[num_map] = which;
- mapfrom[num_map] = i;
- num_map++;
- masses[which] = masses[i];
- masses[which].status &= ~S_SELECTED;
- masses[which].num_pars = 0;
- masses[which].pars = NULL;
- }
- }
-
- for (i = 0; i < spring_start; i++) {
- if (springs[i].status & S_SELECTED) {
- boolean m1done, m2done;
-
- m1done = m2done = FALSE;
-
- which = create_spring();
- springs[which] = springs[i];
- springs[which].status &= ~S_SELECTED;
-
- for (j = 0; (!m1done || !m2done) && j < num_map; j++) {
- if (!m1done && springs[which].m1 == mapfrom[j]) {
- springs[which].m1 = mapto[j];
- add_massparent(mapto[j], which);
- m1done = TRUE;
- }
- if (!m2done && springs[which].m2 == mapfrom[j]) {
- springs[which].m2 = mapto[j];
- add_massparent(mapto[j], which);
- m2done = TRUE;
- }
- }
- if (!m1done && !m2done) {
- /* delete spring that isn't connected to anyone */
- delete_spring(which);
- }
- }
- }
-
- free(mapfrom);
- free(mapto);
- }
-
- void translate_selobj(dx, dy)
- int dx, dy;
- {
- int i;
-
- for (i = 0; i < num_mass; i++) {
- if (masses[i].status & S_SELECTED) {
- masses[i].x += dx;
- masses[i].y += dy;
- }
- }
- }
-
- void changevel_selobj(vx, vy, relative)
- int vx, vy;
- boolean relative;
- {
- int i;
-
- for (i = 0; i < num_mass; i++) {
- if (masses[i].status & S_SELECTED) {
- if (relative) {
- masses[i].vx += vx;
- masses[i].vy += vy;
- } else {
- masses[i].vx = vx;
- masses[i].vy = vy;
- }
- }
- }
- }
-
- void tempfixed_obj(store)
- boolean store;
- {
- int i;
-
- for (i = 0; i < num_mass; i++) {
- if (masses[i].status & S_SELECTED) {
- if (store) {
- masses[i].status &= ~S_TEMPFIXED;
- if (!(masses[i].status & S_FIXED)) {
- masses[i].status |= (S_TEMPFIXED | S_FIXED);
- }
- } else {
- if (masses[i].status & S_TEMPFIXED) {
- masses[i].status &= ~S_FIXED;
- }
- }
- }
- }
- }
-
- void set_sel_restlen()
- {
- int i;
- double dx, dy;
-
- for (i = 0; i < num_spring; i++) {
- if (springs[i].status & S_SELECTED) {
- dx = masses[springs[i].m1].x - masses[springs[i].m2].x;
- dy = masses[springs[i].m1].y - masses[springs[i].m2].y;
- springs[i].restlen = sqrt(dx * dx + dy * dy);
- }
- }
- }
-
- void set_center()
- {
- int i, cent = -1;
-
- for (i = 0; i < num_mass; i++) {
- if (masses[i].status & S_SELECTED) {
- if (cent != -1)
- return;
-
- cent = i;
- }
- }
-
- mst.center_id = cent;
- }
- \BARFOO\
- else
- echo "will not over write ./obj.c"
- fi
- if `test ! -s ./obj.h`
- then
- echo "writting ./obj.h"
- cat > ./obj.h << '\BARFOO\'
- #define S_ALIVE 0x01
- #define S_SELECTED 0x02
- #define S_FIXED 0x04
- #define S_TEMPFIXED 0x08
-
- #define ALLOC_SIZE 32
-
- typedef struct {
- /* Current position, velocity, acceleration */
- double x, y;
- double vx, vy;
- double ax, ay;
-
- /* Mass and radius of mass */
- double mass;
- double elastic;
- int radius;
-
- /* Connections to springs */
- int *pars;
- int num_pars;
-
- int status;
-
- /* RK temporary space */
- double cur_x, cur_y, cur_vx, cur_vy;
- double old_x, old_y, old_vx, old_vy;
- double test_x, test_y, test_vx, test_vy;
- double k1x, k1y, k1vx, k1vy;
- double k2x, k2y, k2vx, k2vy;
- double k3x, k3y, k3vx, k3vy;
- double k4x, k4y, k4vx, k4vy;
- } mass;
-
- typedef struct {
- /* Ks, Kd and rest length of spring */
- double ks, kd;
- double restlen;
-
- /* Connected to masses m1 and m2 */
- int m1, m2;
-
- int status;
- } spring;
-
- extern mass *masses;
- extern spring *springs;
- extern int num_mass, num_spring, fake_mass, fake_spring;
-
- \BARFOO\
- else
- echo "will not over write ./obj.h"
- fi
- if `test ! -s ./patchlevel.h`
- then
- echo "writting ./patchlevel.h"
- cat > ./patchlevel.h << '\BARFOO\'
- #define VERSION 1.1
- #define PATCHLEVEL 0
- \BARFOO\
- else
- echo "will not over write ./patchlevel.h"
- fi
- if `test ! -s ./phys.c`
- then
- echo "writting ./phys.c"
- cat > ./phys.c << '\BARFOO\'
- /* phys.c -- xspringies physical modeling and numerical solving routines
- * Copyright (C) 1991,1992 Douglas M. DeCarlo
- *
- * This file is part of XSpringies, a mass and spring simulation system for X
- *
- * XSpringies is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 1, or (at your option)
- * any later version.
- *
- * XSpringies is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with XSpringies; see the file COPYING. If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
- #include "defs.h"
- #include "obj.h"
-
- #ifndef M_PI
- #define M_PI 3.14159265358979323846
- #endif
-
- #define DT_MIN 0.0001
- #define DT_MAX 0.5
-
- #define MAXCON 1024
-
- #define CONSTR_KS 1.0
- #define CONSTR_KD 1.0
-
- /* Do fudgy bounces */
- #define BOUNCE_FUDGE 1
-
- /* Stickiness calibration: STICK_MAG = 1.0, means that a mass = 1.0 with gravity = 1.0 will remain
- stuck on a wall for all stickiness values > 1.0 */
- #define STICK_MAG 1.0
-
- void accumulate_accel()
- {
- double gval, gmisc;
- double gx = 0, gy = 0, ogx = 0, ogy = 0;
- double center_x = draw_wid/2.0, center_y = draw_ht/2.0, center_rad = 1.0;
- mass *m, *m1, *m2;
- spring *s;
- register int i;
-
- /* ------------------ applied force effects ----------------------- */
-
- if (mst.center_id >= 0) {
- if (masses[mst.center_id].status & S_ALIVE) {
- center_x = masses[mst.center_id].x;
- center_y = masses[mst.center_id].y;
- } else {
- mst.center_id = -1;
- }
- }
-
- /* Do gravity */
- if (mst.bf_mode[FR_GRAV] > 0) {
- gval = mst.cur_grav_val[FR_GRAV];
- gmisc = mst.cur_misc_val[FR_GRAV];
-
- gx = COORD_DX(gval * sin(gmisc * M_PI / 180.0));
- gy = COORD_DY(gval * cos(gmisc * M_PI / 180.0));
- }
-
- /* Keep center of mass in the middle force */
- if (mst.bf_mode[FR_CMASS] > 0) {
- double mixix = 0.0, mixiy = 0.0, mivix = 0.0, miviy = 0.0, msum = 0.0;
- gval = mst.cur_grav_val[FR_CMASS];
- gmisc = mst.cur_misc_val[FR_CMASS];
-
- for (i = 0; i < num_mass; i++) {
- m = masses + i;
- if (i != mst.center_id && (m->status & S_ALIVE) && !(m->status & S_FIXED)) {
- msum += m->mass;
- mixix += m->mass * m->x;
- mixiy += m->mass * m->y;
- mivix += m->mass * m->vx;
- miviy += m->mass * m->vy;
- }
- }
-
- if (msum) {
- mixix /= msum;
- mixiy /= msum;
- mivix /= msum;
- miviy /= msum;
-
- mixix -= center_x;
- mixiy -= center_y;
-
- ogx -= (gval * mixix + gmisc * mivix) / msum;
- ogy -= (gval * mixiy + gmisc * miviy) / msum;
- }
- }
-
- /* Apply Gravity, CM and air drag to all masses */
- for (i = 0; i < num_mass; i++) {
- m = masses + i;
- if ((m->status & S_ALIVE) && !(m->status & S_FIXED)) {
- /* Do viscous drag */
- if (i != mst.center_id) {
- m->ax = gx + ogx - mst.cur_visc * m->vx;
- m->ay = gy + ogy - mst.cur_visc * m->vy;
- } else {
- m->ax = gx - mst.cur_visc * m->vx;
- m->ay = gy - mst.cur_visc * m->vy;
- }
- }
- }
-
- /* Do point attraction force */
- if (mst.bf_mode[FR_PTATTRACT] > 0) {
- gval = mst.cur_grav_val[FR_PTATTRACT];
- gmisc = mst.cur_misc_val[FR_PTATTRACT];
-
- for (i = 0; i < num_mass; i++) {
- m = masses + i;
- if ((m->status & S_ALIVE) && !(m->status & S_FIXED)) {
- double dx, dy, mag, fmag;
-
- dx = (center_x - m->x);
- dy = (center_y - m->y);
- mag = sqrt(dx * dx + dy * dy);
-
- if (mag < m->radius + center_rad) {
- dx *= mag / (m->radius + center_rad);
- dy *= mag / (m->radius + center_rad);
- mag = m->radius + center_rad;
- }
-
- fmag = gval / pow(mag, gmisc);
-
- m->ax += fmag * dx / mag;
- m->ay += fmag * dy / mag;
- }
- }
- }
-
- /* Wall attract/repel force */
- if (mst.bf_mode[FR_WALL] > 0) {
- double dax, day, dist;
-
- gval = -mst.cur_grav_val[FR_WALL];
- gmisc = mst.cur_misc_val[FR_WALL];
-
- for (i = 0; i < num_mass; i++) {
- m = masses + i;
- if ((m->status & S_ALIVE) && !(m->status & S_FIXED)) {
- dax = day = 0;
-
- if (mst.w_left && (dist = m->x - m->radius) >= 0) {
- if (dist < 1) dist = 1;
- dist = pow(dist, gmisc);
- dax -= gval / dist;
- }
- if (mst.w_right && (dist = draw_wid - m->radius - m->x) >= 0) {
- if (dist < 1) dist = 1;
- dist = pow(dist, gmisc);
- dax += gval / dist;
- }
- if (mst.w_top && (dist = draw_ht - m->radius - m->y) >= 0) {
- if (dist < 1) dist = 1;
- dist = pow(dist, gmisc);
- day += gval / dist;
- }
- if (mst.w_bottom && (dist = m->y - m->radius) >= 0) {
- if (dist < 1) dist = 1;
- dist = pow(dist, gmisc);
- day -= gval / dist;
- }
-
- m->ax += dax;
- m->ay += day;
- }
- }
- }
-
- /* ------------------ spring effects ----------------------- */
-
- /* Spring compression/damping effects on masses */
- for (i = 0; i < num_spring; i++) {
- s = springs + i;
- if (s->status & S_ALIVE) {
- double dx, dy, force, forcex, forcey, mag, damp, mass1, mass2;
-
- m1 = masses + s->m1;
- m2 = masses + s->m2;
-
- dx = m1->x - m2->x;
- dy = m1->y - m2->y;
-
- if (dx || dy) {
- mag = sqrt(dx * dx + dy * dy);
-
- force = s->ks * (s->restlen - mag);
- if (s->kd) {
- damp = ((m1->vx - m2->vx) * dx + (m1->vy - m2->vy) * dy) / mag;
- force -= s->kd * damp;
- }
-
- force /= mag;
- forcex = force * dx;
- forcey = force * dy;
-
- mass1 = m1->mass;
- mass2 = m2->mass;
-
- m1->ax += forcex / mass1;
- m1->ay += forcey / mass1;
- m2->ax -= forcex / mass2;
- m2->ay -= forcey / mass2;
- }
- }
- }
- }
-
- void runge_kutta(h, testloc)
- double h;
- boolean testloc;
- {
- mass *m;
- int i;
-
- accumulate_accel();
-
- /* k1 step */
- for (i = 0; i < num_mass; i++) {
- m = masses + i;
-
- if ((m->status & S_ALIVE) && !(m->status & S_FIXED)) {
- /* Initial storage */
- m->cur_x = m->x;
- m->cur_y = m->y;
- m->cur_vx = m->vx;
- m->cur_vy = m->vy;
-
- m->k1x = m->vx * h;
- m->k1y = m->vy * h;
- m->k1vx = m->ax * h;
- m->k1vy = m->ay * h;
-
- m->x = m->cur_x + m->k1x / 2;
- m->y = m->cur_y + m->k1y / 2;
- m->vx = m->cur_vx + m->k1vx / 2;
- m->vy = m->cur_vy + m->k1vy / 2;
- }
- }
-
- accumulate_accel();
-
- /* k2 step */
- for (i = 0; i < num_mass; i++) {
- m = masses + i;
- if ((m->status & S_ALIVE) && !(m->status & S_FIXED)) {
- m->k2x = m->vx * h;
- m->k2y = m->vy * h;
- m->k2vx = m->ax * h;
- m->k2vy = m->ay * h;
-
- m->x = m->cur_x + m->k2x / 2;
- m->y = m->cur_y + m->k2y / 2;
- m->vx = m->cur_vx + m->k2vx / 2;
- m->vy = m->cur_vy + m->k2vy / 2;
- }
- }
-
- accumulate_accel();
-
- /* k3 step */
- for (i = 0; i < num_mass; i++) {
- m = masses + i;
- if ((m->status & S_ALIVE) && !(m->status & S_FIXED)) {
- m->k3x = m->vx * h;
- m->k3y = m->vy * h;
- m->k3vx = m->ax * h;
- m->k3vy = m->ay * h;
-
- m->x = m->cur_x + m->k3x;
- m->y = m->cur_y + m->k3y;
- m->vx = m->cur_vx + m->k3vx;
- m->vy = m->cur_vy + m->k3vy;
- }
- }
-
- accumulate_accel();
-
- /* k4 step */
- for (i = 0; i < num_mass; i++) {
- m = masses + i;
- if ((m->status & S_ALIVE) && !(m->status & S_FIXED)) {
- m->k4x = m->vx * h;
- m->k4y = m->vy * h;
- m->k4vx = m->ax * h;
- m->k4vy = m->ay * h;
- }
- }
-
- /* Find next position */
- for (i = 0; i < num_mass; i++) {
- m = masses + i;
- if ((m->status & S_ALIVE) && !(m->status & S_FIXED)) {
- if (testloc) {
- m->test_x = m->cur_x + (m->k1x/2.0 + m->k2x + m->k3x + m->k4x/2.0)/3.0;
- m->test_y = m->cur_y + (m->k1y/2.0 + m->k2y + m->k3y + m->k4y/2.0)/3.0;
- m->test_vx = m->cur_vx + (m->k1vx/2.0 + m->k2vx + m->k3vx + m->k4vx/2.0)/3.0;
- m->test_vy = m->cur_vy + (m->k1vy/2.0 + m->k2vy + m->k3vy + m->k4vy/2.0)/3.0;
- } else {
- m->x = m->cur_x + (m->k1x/2.0 + m->k2x + m->k3x + m->k4x/2.0)/3.0;
- m->y = m->cur_y + (m->k1y/2.0 + m->k2y + m->k3y + m->k4y/2.0)/3.0;
- m->vx = m->cur_vx + (m->k1vx/2.0 + m->k2vx + m->k3vx + m->k4vx/2.0)/3.0;
- m->vy = m->cur_vy + (m->k1vy/2.0 + m->k2vy + m->k3vy + m->k4vy/2.0)/3.0;
- }
- }
- }
- }
-
- void adaptive_runge_kutta()
- {
- int i;
- mass *m;
- double err, maxerr;
-
- restart:
- if (mst.cur_dt > DT_MAX)
- mst.cur_dt = DT_MAX;
- if (mst.cur_dt < DT_MIN)
- mst.cur_dt = DT_MIN;
-
- runge_kutta(mst.cur_dt/2.0, FALSE);
- runge_kutta(mst.cur_dt/2.0, TRUE);
-
- for (i = 0; i < num_mass; i++) {
- m = masses + i;
- if ((m->status & S_ALIVE) && !(m->status & S_FIXED)) {
- m->x = m->old_x;
- m->y = m->old_y;
- m->vx = m->old_vx;
- m->vy = m->old_vy;
- }
- }
- runge_kutta(mst.cur_dt, FALSE);
-
- /* Find error */
- maxerr = 0.00001;
- for (i = 0; i < num_mass; i++) {
- m = masses + i;
- if ((m->status & S_ALIVE) && !(m->status & S_FIXED)) {
- err = fabs(m->x - m->test_x) + fabs(m->y - m->test_y) +
- fabs(m->vx - m->test_vx) + fabs(m->vy - m->test_vy);
-
- if (err > maxerr) {
- maxerr = err;
- }
- }
- }
-
- /* Fudgy scale factor -- user controlled */
- maxerr /= mst.cur_prec;
-
- if (maxerr < 1.0) {
- mst.cur_dt *= 0.9 * exp(-log(maxerr)/8.0);
- } else {
- if (mst.cur_dt > DT_MIN) {
- for (i = 0; i < num_mass; i++) {
- m = masses + i;
- if ((m->status & S_ALIVE) && !(m->status & S_FIXED)) {
- m->x = m->old_x;
- m->y = m->old_y;
- m->vx = m->old_vx;
- m->vy = m->old_vy;
- }
- }
-
- mst.cur_dt *= 0.9 * exp(-log(maxerr)/4.0);
-
- goto restart;
- }
- }
- }
-
- boolean animate_obj()
- {
- mass *m;
- spring *s;
- int i;
- double stick_mag;
- static int num_since = 0;
- static double time_elapsed = 0.0;
-
- /* Save initial values */
- for (i = 0; i < num_mass; i++) {
- m = masses + i;
- if ((m->status & S_ALIVE) && !(m->status & S_FIXED)) {
- m->old_x = m->x;
- m->old_y = m->y;
- m->old_vx = m->vx;
- m->old_vy = m->vy;
- }
- }
-
- if (mst.adaptive_step) {
- boolean any_spring = FALSE;
-
- for (i = 0; i < num_spring; i++) {
- s = springs + i;
- if (s->status & S_ALIVE) {
- any_spring = TRUE;
- break;
- }
- }
-
- /* If no springs, then use dt=DEF_TSTEP */
- if (any_spring) {
- adaptive_runge_kutta();
- } else {
- runge_kutta(mst.cur_dt = DEF_TSTEP, FALSE);
- }
- } else {
- runge_kutta(mst.cur_dt, FALSE);
- }
-
- stick_mag = STICK_MAG * mst.cur_dt * mst.cur_stick;
-
- /* Crappy wall code */
- for (i = 0; i < num_mass; i++) {
- m = masses + i;
-
- if ((m->status & S_ALIVE) && !(m->status & S_FIXED)) {
- /* Delete "exploded" objects */
- if (m->ax - m->ax != 0.0 || m->ay - m->ay != 0.0 || m->x - m->x != 0.0 || m->y - m->y != 0.0) {
- delete_mass(i);
- continue;
- }
-
- /* Check if stuck to a wall */
- if (m->old_vx == 0.0 && m->old_vy == 0.0) {
- /* Left or right wall */
- if ((mst.w_left && ABS(m->old_x - m->radius) < 0.5) || (mst.w_right && ABS(m->old_x - draw_wid + m->radius) < 0.5)) {
- if (ABS(m->vx) < stick_mag / m->mass) {
- m->vx = m->vy = 0;
- m->x = m->old_x;
- m->y = m->old_y;
-
- continue;
- }
- } else if ((mst.w_bottom && ABS(m->old_y - m->radius) < 0.5) || (mst.w_top && ABS(m->old_y - draw_ht + m->radius) < 0.5)) {
- /* Top or bottom wall */
- if (ABS(m->vy) < stick_mag / m->mass) {
- m->vx = m->vy = 0;
- m->x = m->old_x;
- m->y = m->old_y;
-
- continue;
- }
- }
- }
-
- /* Bounce off left or right wall */
- if (mst.w_left && m->x < m->radius && m->old_x >= m->radius) {
- m->x = m->radius;
-
- if (m->vx < 0) {
- m->vx = -m->vx * m->elastic;
- m->vy *= m->elastic;
-
- /* Get stuck if not going fast enough */
- if (m->vx > 0) {
- m->vx -= STICK_MAG * mst.cur_stick / m->mass;
-
- if (m->vx < 0) {
- m->vx = m->vy = 0;
- }
- }
- }
- } else if (mst.w_right && m->x > draw_wid - m->radius && m->old_x <= draw_wid - m->radius) {
- m->x = draw_wid - m->radius;
-
- if (m->vx > 0) {
- m->vx = -m->vx * m->elastic;
- m->vy *= m->elastic;
-
- /* Get stuck if not going fast enough */
- if (m->vx < 0) {
- m->vx += STICK_MAG * mst.cur_stick / m->mass;
-
- if (m->vx > 0) {
- m->vx = m->vy = 0;
- }
- }
- }
- }
- /* Stick to top or bottom wall */
- if (mst.w_bottom && m->y < m->radius && m->old_y >= m->radius) {
- m->y = m->radius;
-
- if (m->vy < 0) {
- m->vy = -m->vy * m->elastic;
- m->vx *= m->elastic;
-
- /* Get stuck if not going fast enough */
- if (m->vy > 0) {
- m->vy -= STICK_MAG * mst.cur_stick / m->mass;
-
- if (m->vy < 0) {
- m->vx = m->vy = 0;
- }
- }
- }
- } else if (mst.w_top && m->y > (draw_ht - m->radius) && m->old_y <= (draw_ht - m->radius)) {
- m->y = draw_ht - m->radius;
-
- if (m->vy > 0) {
- m->vy = -m->vy * m->elastic;
- m->vx *= m->elastic;
-
- /* Get stuck if not going fast enough */
- if (m->vy < 0) {
- m->vy += STICK_MAG * mst.cur_stick / m->mass;
-
- if (m->vy > 0) {
- m->vx = m->vy = 0;
- }
- }
- }
- }
- }
- }
-
- time_elapsed += mst.cur_dt;
-
- if (time_elapsed > 0.05) {
- time_elapsed -= 0.05;
- num_since = 0;
- return TRUE;
- }
-
- num_since++;
-
- if (num_since > 8) {
- num_since = 0;
- return TRUE;
- }
- return FALSE;
- }
- \BARFOO\
- else
- echo "will not over write ./phys.c"
- fi
- echo "Finished archive 4 of 16"
- exit
-
- exit 0 # Just in case...
- --
- // chris@IMD.Sterling.COM | Send comp.sources.x submissions to:
- \X/ Amiga - The only way to fly! |
- "It's intuitively obvious to the most | sources-x@imd.sterling.com
- casual observer..." |
-