home *** CD-ROM | disk | FTP | other *** search
/ ARM Club 3 / TheARMClub_PDCD3.iso / hensa / programming / toollib_2 / Examples / Tree / Builds / c / tree < prev    next >
Encoding:
Text File  |  1995-12-06  |  3.9 KB  |  125 lines

  1. /*** tree.c ***/
  2. /* Simple tree drawing program
  3.  * (c) Paul Field
  4.  * v1.00 - 7/10/95
  5.  * v2.00 - 21/11/95 (More complex trees)
  6.  */
  7.  
  8. #include "tree.h"
  9.  
  10. #include "fast_trig.h"
  11.  
  12.  
  13. enum { level_max = 15 };
  14.  
  15.  
  16. /* In a future version, the choose_colour function will probably be
  17.  * replaced with a lookup table passed in as a parameter
  18.  */
  19. static colour choose_colour(unsigned remaining_depth)
  20.  { unsigned long red;
  21.    unsigned long green;
  22.    unsigned long blue;
  23.    unsigned      level;
  24.  
  25.    if (remaining_depth <= level_max)
  26.     { level = level_max - remaining_depth;
  27.     }
  28.    else
  29.     { level = 0;
  30.     }
  31.  
  32.    red =  8UL * level;
  33.    if (red > 255)
  34.     { red = 255;
  35.     }
  36.  
  37.    green = 16UL * level;
  38.    if (green > 255)
  39.     { green = 255;
  40.     }
  41.  
  42.    blue =  2UL * level;
  43.    if (blue > 255)
  44.     { blue = 255;
  45.     }
  46.  
  47.    return (blue << 16) | (green << 8) | red;
  48.  }
  49.  
  50.  
  51.  
  52.  
  53. static void tree_calculate_recursive
  54.  ( int x,
  55.    int y,
  56.    const tree_state *state,
  57.    const tree_parameters *parameters,
  58.    const line_processor *lines
  59.  )
  60.  { int end_x;
  61.    int end_y;
  62.    int segment_x_change;  /* Change in x coordinate when you move along the branch by one segment */
  63.    int segment_y_change;  /* Change in y coordinate when you move along the branch by one segment */
  64.  
  65.    /* Calculate coordinate changes along a segment */
  66.    segment_x_change = (int)(state->segment_length * fast_sin(state->tree_angle));
  67.    segment_y_change = (int)(state->segment_length * fast_cos(state->tree_angle));
  68.  
  69.  
  70.    /* Draw the main tree shaft */
  71.    end_x = x + parameters->segments * segment_x_change;
  72.    end_y = y + parameters->segments * segment_y_change;
  73.    lines->add_line(choose_colour(state->remaining_depth), x, y, end_x, end_y);
  74.  
  75.  
  76.    if (state->remaining_depth > 1)
  77.     { tree_state branch_state;
  78.       unsigned   segment_num;
  79.       int        branch_x;
  80.       int        branch_y;
  81.  
  82.       /* Branches are actually trees. Calculate the tree state for branches on the left of the main shaft */
  83.       branch_state.segment_length  = (unsigned)(state->segment_length * parameters->length_scale);
  84.       branch_state.tree_angle      = state->tree_angle - state->branch_angle;
  85.       branch_state.branch_angle    = (int)(state->branch_angle * parameters->angle_scale);
  86.       branch_state.remaining_depth = state->remaining_depth-1;
  87.  
  88.       /* Draw the branches on the left of the main shaft */
  89.       branch_x = x + (int)(segment_x_change * parameters->left_proportion);
  90.       branch_y = y + (int)(segment_y_change * parameters->left_proportion);
  91.  
  92.       for (segment_num = 0; segment_num < parameters->segments; segment_num++)
  93.        { tree_calculate_recursive(branch_x, branch_y, &branch_state, parameters, lines);
  94.          branch_x += segment_x_change;
  95.          branch_y += segment_y_change;
  96.          branch_state.segment_length = (unsigned)(branch_state.segment_length * parameters->length_scale_scale);
  97.        }
  98.  
  99.       /* Calculate the tree state for branches on the right of the main shaft */
  100.       /* Branches on the right are the same as those on the left except for their angle */
  101.       branch_state.tree_angle = state->tree_angle + state->branch_angle;
  102.       branch_state.segment_length  = (unsigned)(state->segment_length * parameters->length_scale);
  103.  
  104.       /* Draw the branches on the right of the main shaft */
  105.       branch_x = x + (int)(segment_x_change * parameters->right_proportion);
  106.       branch_y = y + (int)(segment_y_change * parameters->right_proportion);
  107.  
  108.       for (segment_num = 0; segment_num < parameters->segments; segment_num++)
  109.        { tree_calculate_recursive(branch_x, branch_y, &branch_state, parameters, lines);
  110.          branch_x += segment_x_change;
  111.          branch_y += segment_y_change;
  112.          branch_state.segment_length = (unsigned)(branch_state.segment_length * parameters->length_scale_scale);
  113.        }
  114.     }
  115.  }
  116.  
  117.  
  118.  
  119.  
  120. void tree_calculate(int x, int y, const tree_def *tree, const line_processor *lines)
  121.  { lines->initialise();
  122.    tree_calculate_recursive(x, y, &tree->initial_state, &tree->parameters, lines);
  123.    lines->finished();
  124.  }
  125.