home *** CD-ROM | disk | FTP | other *** search
/ ftp.hitl.washington.edu / ftp.hitl.washington.edu.tar / ftp.hitl.washington.edu / pub / people / peter / ER / BP_plot.cxx < prev    next >
C/C++ Source or Header  |  1998-07-07  |  23KB  |  798 lines

  1. /*
  2.  BP_plot.cc
  3. */
  4.  
  5. #include "BP_plot.h"
  6.  
  7. #include <iostream.h>
  8. #include "wt.h"
  9.  
  10. #include "v3dSystem.h"
  11.  
  12. ///////////////////////////
  13. //    BPPlot        //
  14. /////////////////////////
  15.  
  16. #define REMOBJ    // Remove objects from simulation instead of hiding.
  17. #define NOPERFORMER    // Turn off Performer optimizations.
  18. //#define FRAMERATE    // Print the frame rate at certain intervals.
  19.  
  20. const int BPPlot::Waveform_Tess = 3;    // Tesselation of the waveform objects.
  21. const int BPPlot::Lead_Object_Tess = 4;
  22.                     // Tesselation of the lead object.
  23.  
  24. const int BPPlot::Default_Num_Increments = 80;
  25.                 // Default number of plot increments on an BP plot object.
  26. const int BPPlot::Minimum_Num_Increments = 10;
  27.                 // Minimum number of plot increments on an BP plot object.
  28.  
  29. // Initial colors for the various parts of an BP plot object.
  30. const v3dColor BPPlot::BP_plot_background_color = v3dColor (0, 0, 255);
  31. const v3dColor BPPlot::BP_plot_waveform_color = v3dColor (255, 255, 255);
  32. const v3dColor BPPlot::BP_plot_frame_color = v3dColor (255, 255, 255);
  33. const v3dColor BPPlot::BP_plot_lead_object_color = v3dColor (0, 255, 0);
  34.  
  35. ///////////////
  36. // CREATORS //
  37. /////////////
  38.  
  39. BPPlot::BPPlot (const BPPlot& plot)
  40. {
  41.     initialize (plot.BP_driver_, plot.length_, plot.height_,
  42.         plot.depth_, plot.num_increments_);
  43.  
  44.     paused_ = plot.paused_;
  45.  
  46.     current_x_ = plot.current_x_;
  47.     last_x_ = plot.last_x_;
  48.     last_y_ = plot.last_y_;
  49.     current_index_ = plot.current_index_;
  50.     hide_index_ = plot.hide_index_;
  51.     last_drv_index_ = plot.last_drv_index_;
  52.  
  53.     for (int i = 0; i < num_increments_; ++i)
  54.         plot_values_[i] = plot.plot_values_[i];
  55.  
  56.     MoveAbsolute (plot.GetAbsolutePosition());
  57.     SetAbsoluteOrientation (plot.GetAbsoluteOrientation());
  58. }
  59.  
  60. // BPPlot::Copy()
  61. //    Creates a copy of the plot and returns a pointer to the new plot.
  62. inline v3dEntity*
  63. BPPlot::Copy() const
  64. {
  65.     return new BPPlot (*this);
  66. }
  67.  
  68. ///////////////////
  69. // MANIPULATORS //
  70. /////////////////
  71.  
  72. // BPPlot::initialize
  73. //    Initializer for BPPlot object, called by a BPPlot constructor.
  74. //    Registers this object as a receiver of BP data from an
  75. //    BPDataSender object.
  76. // Parameters:
  77. //    float    length
  78. //            Horizontal extent of the BP plot.
  79. //    float    height
  80. //            Vertical extent of the BP plot.
  81. //    float    depth
  82. //            Thickness of the BP object.
  83. //    int    num_increments
  84. //            Number of increments to show along the length of
  85. //            the plot.
  86. void
  87. BPPlot::initialize (BPDriver    *BP_driver,
  88.     float    length, float height, float depth,
  89.     int    num_increments)
  90. {
  91.     // Assign the BP driver.
  92.     BP_driver_ = BP_driver;
  93.  
  94.     length_ = length;
  95.     height_ = height;
  96.     depth_ = depth;
  97.     num_increments_ = num_increments;
  98.     waveform_radius_ = height_ / 100;
  99.  
  100.     // Calculate plot variables based on the client's specifications.
  101.     calculate_plot_variables();
  102.  
  103.     // Request the range of data from the BP sender object, and calculate
  104.     // the range and scale to be used for the plot.
  105.     data_range_ = BP_driver_->GetDataRange();
  106.     calculate_scale_variables();
  107.  
  108.     // Initialize variables used in determining plotting position.
  109.     current_x_ = increment_length_;
  110.     last_x_ = last_y_ = 0;
  111.     current_index_ = 0;
  112.     last_drv_index_ = 0;
  113.  
  114.     // Register this object's event handler with the BP data sender.
  115.     RegisterEventHandler(v3dSystem::GetInstance(),
  116.         v3dSystem::SYSTEM_SIMULATION_LOOP, &BP_update_callback, 0);
  117.  
  118.     paused_ = false;    // The BP plot doesn't start out paused.
  119.  
  120.         // Create the background and frame.
  121.     create_background_and_frame ();
  122.  
  123.     // Create the baseline and other necessary objects.
  124.     create_baseline();
  125. }
  126.  
  127. // BPPlot::Pause
  128. //    Pause the update of the BP plot.  No new data will be shown until
  129. //    the plot is unpaused.
  130. void
  131. BPPlot::Pause()
  132. {
  133.     paused_ = true;
  134. // ADD: pausing!
  135. }
  136.  
  137. // BPPlot::Unpause
  138. //    Restart the update of the BP plot.
  139. void
  140. BPPlot::Unpause()
  141. {
  142.     paused_ = false;
  143. // ADD: unpausing!
  144. }
  145.  
  146. // BPPlot::calculate_plot_variables
  147. //    Calculate plot variables based on the client's specifications.
  148. void
  149. BPPlot::calculate_plot_variables()
  150. {
  151.     waveform_radius_ = height_ / 100;
  152.     hide_interval_ = num_increments_ / 8;
  153.     half_depth_ = depth_ / 2;
  154.     lead_object_radius_ = waveform_radius_ * 3;
  155.     frame_width_ = length_ > height_ ? length_ / 40 : height_ / 40;
  156.     background_depth_ = depth_ / 5;
  157.     vert_buffer_ = frame_width_ * 2;
  158.     horiz_buffer_ = length_ / 100;
  159.     baseline_length_ = length_ - 2 * frame_width_ - 2 * horiz_buffer_; 
  160.     baseline_X_ = frame_width_ + horiz_buffer_;
  161. //    baseline_Y_ = height_ / 2;
  162.     baseline_Y_ = frame_width_ + vert_buffer_;
  163.     increment_length_ = baseline_length_ / num_increments_;
  164. }
  165.  
  166. // BPPlot::calculate_scale_variables
  167. //    Calculate the vertical range and scale of the plot based on plot
  168. //    variables and the range of data sent by the BP data sender.
  169. void
  170. BPPlot::calculate_scale_variables()
  171. {
  172.     vert_plot_range_ = height_ - 2 * frame_width_ - 2 * vert_buffer_;
  173.     BP_DATA_TYPE range = data_range_.maximum_value -
  174.         (data_range_.minimum_value > 0 ? 0 : data_range_.minimum_value);
  175.     if (range > 0)
  176.         vert_scale_ = vert_plot_range_ / range;
  177.     else
  178.         vert_scale_ = vert_plot_range_;
  179. cerr << "max value: " << data_range_.maximum_value <<
  180.     " min value: " << data_range_.minimum_value <<
  181.     " vert scale: " << vert_scale_ << endl;
  182. }
  183.  
  184. // BPPlot::create_background_and_frame
  185. //    Creates the bounding box, background and frame objects for the BP plot.
  186. void
  187. BPPlot::create_background_and_frame ()
  188. {
  189.     // Create the bounding box that will serve as the root of the object
  190.     // hierarchy for the component objects of the BP.
  191.     bounding_box_ = new v3dBlockObject (length_, height_, depth_);
  192.     bounding_box_->Hide();
  193.  
  194.     // Create the BP object background.
  195.     background_ = new v3dBlockObject (length_, height_, background_depth_);
  196.     background_->MoveAbsolute (v3dPos (0, 0,
  197.                     (depth_ - background_depth_ / 2)));
  198.  
  199.     // The background is initially hidden.
  200.     HideBackground();
  201.  
  202.     // Create the BP object frame.
  203.     frame_bottom_ = new v3dBlockObject (length_, frame_width_, depth_);
  204.     frame_top_ = new v3dBlockObject (length_, frame_width_, depth_);
  205.     frame_left_ = new v3dBlockObject (frame_width_, height_, depth_);
  206.     frame_right_ = new v3dBlockObject (frame_width_, height_, depth_);
  207.  
  208.     frame_bottom_->MoveAbsolute (v3dPos (0, (height_ - frame_width_) / 2,
  209.         0));
  210.     frame_top_->MoveAbsolute (v3dVector (0, (height_ - frame_width_) / -2,
  211.         0));
  212.     frame_left_->MoveAbsolute (v3dVector ((length_ - frame_width_) / -2,
  213.         0, 0));
  214.     frame_right_->MoveAbsolute (v3dVector ((length_ - frame_width_) / 2,
  215.         0, 0));
  216.  
  217.     // Add the frame and the background to the bounding box.
  218.     bounding_box_->Add (background_);
  219.     bounding_box_->Add (frame_bottom_);
  220.     bounding_box_->Add (frame_top_);
  221.     bounding_box_->Add (frame_left_);
  222.     bounding_box_->Add (frame_right_);
  223.  
  224.     // Set the colors of the various elements.
  225.     background_->SetColor(BP_plot_background_color);
  226.     frame_bottom_->SetColor(BP_plot_frame_color);
  227.     frame_top_->SetColor(BP_plot_frame_color);
  228.     frame_left_->SetColor(BP_plot_frame_color);
  229.     frame_right_->SetColor(BP_plot_frame_color);
  230.  
  231. #ifndef NOPERFORMER
  232.     // Specify Performer rendering.
  233.     WTobject_addperformer (
  234.         (WTobject *)background_->GetHandler(),
  235.         FALSE, FALSE, FALSE, FALSE, NULL, NULL);
  236.     WTobject_addperformer (
  237.         (WTobject *)frame_bottom_->GetHandler(),
  238.         FALSE, FALSE, FALSE, FALSE, NULL, NULL);
  239.     WTobject_addperformer (
  240.         (WTobject *)frame_top_->GetHandler(),
  241.         FALSE, FALSE, FALSE, FALSE, NULL, NULL);
  242.     WTobject_addperformer (
  243.         (WTobject *)frame_left_->GetHandler(),
  244.         FALSE, FALSE, FALSE, FALSE, NULL, NULL);
  245.     WTobject_addperformer (
  246.         (WTobject *)frame_right_->GetHandler(),
  247.         FALSE, FALSE, FALSE, FALSE, NULL, NULL);
  248. #endif    // NOPERFORMER
  249.  
  250.     // Set the BP's implementation object to the background's
  251.     // implementation object.
  252.     imp_ = bounding_box_->GetImplement();
  253.  
  254.     // The frame is initially shown.
  255.     ShowFrame();
  256. }
  257.  
  258. void
  259. BPPlot::scale_background_and_frame(const v3dVector &factors,
  260.     const v3dPos& point)
  261. {
  262. #ifndef NOPERFORMER
  263.     // Temporarirly disable Performer rendering.
  264.     WTobject_deleteperformer ((WTobject *)background_->GetHandler());
  265.     WTobject_deleteperformer ((WTobject *)frame_bottom_->GetHandler());
  266.     WTobject_deleteperformer ((WTobject *)frame_top_->GetHandler());
  267.     WTobject_deleteperformer ((WTobject *)frame_left_->GetHandler());
  268.     WTobject_deleteperformer ((WTobject *)frame_right_->GetHandler());
  269. #endif    // NOPERFORMER
  270.     
  271.     bounding_box_->Scale (factors, point);
  272.     background_->Scale (factors, point);
  273.     frame_top_->Scale (factors, point);
  274.     frame_bottom_->Scale (factors, point);
  275.     frame_left_->Scale (factors, point);
  276.     frame_right_->Scale (factors, point);
  277.  
  278. #ifndef NOPERFORMER
  279.     // Reinstate Performer rendering.
  280.     WTobject_addperformer (
  281.         (WTobject *)background_->GetHandler(),
  282.         FALSE, FALSE, FALSE, FALSE, NULL, NULL);
  283.     WTobject_addperformer (
  284.         (WTobject *)frame_bottom_->GetHandler(),
  285.         FALSE, FALSE, FALSE, FALSE, NULL, NULL);
  286.     WTobject_addperformer (
  287.         (WTobject *)frame_top_->GetHandler(),
  288.         FALSE, FALSE, FALSE, FALSE, NULL, NULL);
  289.     WTobject_addperformer (
  290.         (WTobject *)frame_left_->GetHandler(),
  291.         FALSE, FALSE, FALSE, FALSE, NULL, NULL);
  292.     WTobject_addperformer (
  293.         (WTobject *)frame_right_->GetHandler(),
  294.         FALSE, FALSE, FALSE, FALSE, NULL, NULL);
  295. #endif    // NOPERFORMER
  296. }
  297.  
  298. void
  299. BPPlot::delete_background_and_frame()
  300. {
  301. //    delete bounding_box_;
  302.     delete background_;
  303.     delete frame_left_;
  304.     delete frame_right_;
  305.     delete frame_top_;
  306.     delete frame_bottom_;
  307. }
  308.  
  309. // BPPlot::create_baseline
  310. //    Creates the BP plot's baseline and all objects associated with it.
  311. void
  312. BPPlot::create_baseline()
  313. {
  314.     // Create the baseline origin for the waveform.
  315. //    origin_ = new v3dSphereObject (waveform_radius_, Waveform_Tess,
  316. //        Waveform_Tess);
  317.     origin_ = new v3dBlockObject (1, 1, 1);
  318.     origin_->MoveAbsolute (v3dVector(baseline_X_ - length_ / 2,
  319.             -baseline_Y_ + height_ / 2, 0));
  320. #ifdef REMOBJ
  321.     origin_->Disable();
  322. #else
  323.     origin_->Hide();
  324. #endif
  325.  
  326.     // Add the baseline origin to the background hierarchy.
  327.     bounding_box_->Add (origin_);
  328.  
  329.     // Create the lead object.
  330.     float    current_X = baseline_X_ - length_ / 2,
  331.         half_increment = increment_length_ / 2;
  332.  
  333.     lead_object_ = new v3dSphereObject (lead_object_radius_,
  334.         Lead_Object_Tess, Lead_Object_Tess);
  335.     origin_->Add (lead_object_);
  336. //    lead_object_->MoveAbsolute (v3dVector (current_X + half_increment,
  337. //        -baseline_Y_, half_depth_));
  338.     lead_object_->Move (v3dVector (current_X + half_increment, 0, 0));
  339.     lead_object_->SetColor(BP_plot_lead_object_color);
  340. #ifndef NOPERFORMER
  341.     WTobject_addperformer (
  342.         (WTobject *)lead_object_->GetHandler(),
  343.         FALSE, FALSE, FALSE, FALSE, NULL, NULL);
  344. #endif    // NOPERFORMER
  345.  
  346.     // Create the individual baseline plot objects.
  347.     baseline_array_ = new v3dLineObject * [num_increments_];
  348.     plot_values_ = new BP_DATA_TYPE [num_increments_];
  349. //    WTp3    align_vec = { 1, 0, 0 };
  350.     v3dVector    inc_vec (increment_length_, 0, 0);
  351.  
  352. //    v3dPos    from_pos (current_X, -baseline_Y_, half_depth_);
  353.     v3dPos    from_pos (current_X, 0, 0);
  354.  
  355.     for (int ci = 0; ci < num_increments_; ++ci) {
  356.         plot_values_[ci] = 0;
  357.         from_pos.x (current_X);
  358.         baseline_array_[ci]
  359.             = new v3dLineObject (from_pos, from_pos + inc_vec,
  360.                 waveform_radius_, Waveform_Tess);
  361. // CHANGE: this!
  362.         baseline_array_[ci]->SetPoints(*origin_, from_pos, from_pos + inc_vec);
  363. #if 0
  364.         baseline_array_[ci]
  365.             = new v3dLineObject (
  366.                 ((v3dEntity *)origin_)->GetAbsolutePosition(from_pos),
  367.                 ((v3dEntity *)origin_)->GetAbsolutePosition(from_pos + inc_vec),
  368.                 waveform_radius_, Waveform_Tess);
  369. #endif
  370.  
  371.         // Add a baseline plot object to the baseline origin.
  372.         origin_->Add (baseline_array_[ci]);
  373.  
  374. #ifdef REMOBJ
  375.         baseline_array_[ci]->Disable();
  376. #else
  377.         baseline_array_[ci]->Hide();
  378. #endif
  379.  
  380.         // Color the baseline objects.
  381.         baseline_array_[ci]->SetColor(BP_plot_waveform_color);
  382.  
  383.         current_X += increment_length_;
  384.     }
  385.  
  386.     lead_object_->SetColor(BP_plot_lead_object_color);
  387. }
  388.  
  389. void
  390. BPPlot::delete_baseline()
  391. {
  392.     for (int ci = 0; ci < num_increments_; ci++)
  393.         delete baseline_array_[ci];
  394.     delete origin_;
  395.     delete lead_object_;
  396. }
  397.  
  398. // BPPlot::BP_update_callback
  399. //    Event handler callback function, notified every cycle to request
  400. //    the latest data from the BP driver.
  401. void
  402. BPPlot::BP_update_callback (const v3dEventMessage *message)
  403. {
  404. #ifdef FRAMERATE
  405.     static int frame_count = 0;
  406.  
  407.     if (++frame_count == 40) {
  408.         cerr << "Frame rate: " << WTuniverse_framerate() << endl;
  409.         frame_count = 0;
  410.     }
  411. #endif    // FRAMERATE
  412.     ((BPPlot *)message->GetEventReceiver())->plot_new_data ();
  413. }
  414.  
  415. // BPPlot::plot_new_data
  416. //    Copies the latest data from the BP driver, then plots any new
  417. //    data on the BP.
  418. void
  419. BPPlot::plot_new_data ()
  420. {
  421.     int current_drv_index = BP_driver_->GetCurrentDataIndex();
  422.  
  423.     // If there's no new data to be displayed, then just return.
  424.     if (last_drv_index_ == current_drv_index)
  425.         return;
  426.  
  427.     int    new_index = current_index_;
  428.  
  429.     // Copy the data from the BP driver.
  430.     do {
  431.         last_drv_index_ =
  432.             BP_driver_->GetNextDataIndex(last_drv_index_);
  433.  
  434.         plot_values_[new_index++] =
  435.                 BP_driver_->data_list[last_drv_index_];
  436.         if (new_index >= num_increments_)
  437.             new_index = 0;
  438.     } while (last_drv_index_ != current_drv_index);
  439.  
  440.     // Plot the new data.
  441.     plot_data (new_index);
  442.  
  443.     current_index_ = new_index;
  444. }
  445.  
  446. // BPPlot::plot_data
  447. //    Plots the BP data on the waveform up to the new index specified.
  448. // Parameters:
  449. //    int new_index
  450. //        The last index of the plot data to be shown.
  451. void
  452. BPPlot::plot_data (int new_index)
  453. {
  454.     float    this_y;
  455.     v3dPos    new_pos,
  456.         last_pos = v3dVector(last_x_, -(last_y_), 0);
  457.  
  458.     while (current_index_ != new_index) {
  459.         this_y = plot_values_[current_index_] * vert_scale_;
  460.         new_pos = v3dVector(current_x_, -(this_y), 0);
  461.  
  462.         hide_index_ = (current_index_ + hide_interval_)
  463.             % num_increments_;
  464.         baseline_array_[hide_index_]->Disable();
  465.  
  466. // cout << "data:" << this_y << " diff: " << diff_y << " ";
  467.  
  468.         baseline_array_[current_index_]->SetPoints(*origin_,
  469.                             last_pos, new_pos);
  470.         baseline_array_[current_index_]->Enable();
  471.  
  472.         // Color the plot.
  473.         baseline_array_[current_index_]->SetColor(
  474.                         BP_plot_waveform_color);
  475.  
  476.         last_y_ = this_y;
  477.         last_pos = new_pos;
  478.         ++current_index_;
  479.         if (current_index_ >= num_increments_) {
  480.             current_index_ = 0;
  481.             current_x_ = increment_length_;
  482.             last_x_ = 0;
  483.             last_pos.x(0);
  484.         } else {
  485.             last_x_ = current_x_;
  486.             current_x_ += increment_length_;
  487.         }
  488.     }
  489.     lead_object_->Move(new_pos);
  490. }
  491.  
  492. void
  493. BPPlot::scale_baseline (const v3dVector &factors, const v3dPos& point)
  494. {
  495.     origin_->Scale(factors, point);
  496.  
  497.     float current_x = increment_length_, last_x = 0;
  498.     float last_y = plot_values_[num_increments_ - 1] * vert_scale_;
  499.  
  500.     for (int i = 0; i < num_increments_; ++i) {
  501.         float    this_y = plot_values_[i] * vert_scale_;
  502. #if 0
  503.         v3dPos    new_pos = origin_->GetAbsolutePosition()
  504.                 + v3dVector(current_x, -(this_y), 0),
  505.             last_pos = origin_->GetAbsolutePosition()
  506.                 + v3dVector(last_x, -(last_y), 0);
  507. #endif
  508.         v3dPos    new_pos = v3dVector(current_x, -(this_y), 0),
  509.             last_pos = v3dVector(last_x, -(last_y), 0);
  510.  
  511.         delete baseline_array_[i];
  512.         baseline_array_[i]
  513.             = new v3dLineObject (last_pos, new_pos,
  514.                 waveform_radius_, Waveform_Tess);
  515.  
  516.         origin_->Add (baseline_array_[i]);
  517. // CHANGE: this!
  518.         baseline_array_[i]->SetPoints(*origin_, last_pos, new_pos);
  519.  
  520. //        baseline_array_[i]->SetPoints(last_pos, new_pos);
  521.         last_x = current_x;
  522.         last_y = this_y;
  523.         current_x += increment_length_;
  524.     }
  525.  
  526.     // Recalculate plotting position variables.
  527. //    last_x_ *= factors.x();
  528. //    current_x_ *= factors.x();
  529. //    if (current_index_ == 0)
  530. //        last_x_ = 0;
  531. //    else
  532.     last_x_ = current_index_ * increment_length_;
  533.     current_x_ = (current_index_+1) * increment_length_;
  534.     last_y_ *= factors.y();
  535. //    last_y_ = plot_values_ [current_index_] * vert_scale_;
  536.  
  537.     delete lead_object_;
  538.     lead_object_ = new v3dSphereObject (lead_object_radius_,
  539.         Lead_Object_Tess, Lead_Object_Tess);
  540.     origin_->Add(lead_object_);
  541.  
  542.     lead_object_->Move(v3dVector(last_x_, -(last_y_), 0));
  543.     lead_object_->SetColor(BP_plot_lead_object_color);
  544. //    lead_object_->Move(origin_->GetAbsolutePosition()
  545. //                + v3dVector(last_x_, -(last_y_), 0));
  546. }
  547.  
  548. // BPPlot::fix_hide_interval
  549. //    Re-hides objects along the hide interval to fix any errors introduced
  550. //    when the sweep speed was changed.
  551. void
  552. BPPlot::fix_hide_interval ()
  553. {
  554.     hide_interval_ = num_increments_ / 8;
  555.  
  556.     int    current_index = current_index_;
  557.     for (int i = 0; i < hide_interval_; ++i, ++current_index) {
  558.         if (current_index >= num_increments_)
  559.             current_index = 0;
  560. #ifdef REMOBJ
  561.         baseline_array_[current_index]->Disable();
  562. #else
  563.         baseline_array_[current_index]->Hide();
  564. #endif
  565.     }
  566. }
  567.  
  568. // BPPlot::extend_baseline
  569. //    Extends the baseline to the number of increments specified.
  570. //    The old baseline array is copied to a new baseline array, and the
  571. //    new elements in the array are initialized with flat baseline
  572. //    elements.
  573. // Parameters:
  574. //    unsigned int    old_increment_num
  575. //        Old number of increments on the the baseline.
  576. //    unsigned int    new_increment_num
  577. //        New number of increments on the the baseline.
  578. void
  579. BPPlot::extend_baseline (unsigned int old_increment_num,
  580.     unsigned int new_increment_num)
  581. {
  582.     ASSERT (new_increment_num >= old_increment_num);
  583.  
  584.     v3dLineObject    **new_baseline_array
  585.         = new v3dLineObject * [new_increment_num];
  586.     BP_DATA_TYPE    *new_plot_values
  587.         = new BP_DATA_TYPE [new_increment_num];
  588.  
  589.     // Copy the old baseline elements into the new array.
  590.     for (int i = 0; i < old_increment_num; ++i) {
  591.         new_baseline_array[i] = baseline_array_[i];
  592.         new_plot_values [i] = plot_values_ [i];
  593.     }
  594.     delete [] baseline_array_;
  595.     delete [] plot_values_;
  596.  
  597.     // Create new, flat baseline objects.
  598.     v3dVector    inc_vec (increment_length_, 0, 0);
  599.     float    current_X = old_increment_num * increment_length_;
  600.  
  601.     v3dPos    from_pos (current_X, 0, 0);
  602. //    v3dPos    from_pos (current_X, -baseline_Y_, half_depth_);
  603.  
  604.     for (int ci = old_increment_num; ci < new_increment_num; ++ci) {
  605.         new_plot_values[ci] = 0;
  606.         from_pos.x (current_X);
  607. #if 0
  608.         new_baseline_array[ci]
  609.             = new v3dLineObject (
  610.                 ((v3dEntity *)origin_)->GetAbsolutePosition(from_pos),
  611.                 ((v3dEntity *)origin_)->GetAbsolutePosition(from_pos + inc_vec),
  612.                 waveform_radius_, Waveform_Tess);
  613. #endif
  614.         new_baseline_array[ci]
  615.             = new v3dLineObject (from_pos, from_pos + inc_vec,
  616.                 waveform_radius_, Waveform_Tess);
  617. // CHANGE: this!
  618.         new_baseline_array[ci]->SetPoints(*origin_, from_pos, from_pos + inc_vec);
  619.  
  620.         // Add a baseline plot object to the baseline origin.
  621.         origin_->Add (new_baseline_array[ci]);
  622.  
  623. #if 0
  624. #ifdef REMOBJ
  625.         new_baseline_array[ci]->Disable();
  626. #else
  627.         new_baseline_array[ci]->Hide();
  628. #endif
  629. #endif
  630.  
  631.         // Color the baseline objects.
  632.         new_baseline_array[ci]->SetColor(BP_plot_waveform_color);
  633.  
  634.         current_X += increment_length_;
  635.     }
  636.  
  637.     baseline_array_ = new_baseline_array;
  638.     plot_values_ = new_plot_values;
  639. }
  640.  
  641. // BPPlot::shrink_baseline
  642. //    Shrinks the baseline to the number of increments specified.
  643. //    The old baseline array is copied to a new baseline array, leaving
  644. //    out extra elements farthest from the leading edge of the graph.
  645. // Parameters:
  646. //    unsigned int    old_increment_num
  647. //        Old number of increments on the the baseline.
  648. //    unsigned int    new_increment_num
  649. //        New number of increments on the the baseline.
  650. void
  651. BPPlot::shrink_baseline (unsigned int old_increment_num,
  652.     unsigned int new_increment_num)
  653. {
  654.     ASSERT (new_increment_num <= old_increment_num);
  655.  
  656.     v3dLineObject    **new_baseline_array
  657.         = new v3dLineObject * [new_increment_num];
  658.     BP_DATA_TYPE    *new_plot_values
  659.         = new BP_DATA_TYPE [new_increment_num];
  660.  
  661.     // Copy the old baseline elements into the new array.
  662.     int    start_index, finish_index;
  663.     if (current_index_ >= new_increment_num) {
  664.         start_index = current_index_ - new_increment_num + 1;
  665.         finish_index = current_index_ + 1;
  666.         current_index_ = new_increment_num - 1;
  667.         current_x_ = current_index_ * increment_length_;
  668.         last_x_ = (current_index_-1) * increment_length_;
  669.     } else {
  670.         start_index = 0;
  671.         finish_index = new_increment_num;
  672.     }
  673.     for (int j = 0; j < start_index; ++j)
  674.         delete baseline_array_[j];
  675.     for (int i = start_index; i < finish_index; ++i) {
  676.         new_baseline_array[i-start_index] = baseline_array_[i];
  677.         new_plot_values [i-start_index] = plot_values_ [i];
  678.     }
  679.     for (int k = finish_index; k < old_increment_num; ++k)
  680.         delete baseline_array_[k];
  681.  
  682.     delete [] baseline_array_;
  683.     delete [] plot_values_;
  684.  
  685.     baseline_array_ = new_baseline_array;
  686.     plot_values_ = new_plot_values;
  687. }
  688.  
  689. // BPPlot::MoveFrontLowerLeftCorner
  690. //    Move the entire BP plot.
  691. // Parameters:
  692. //    v3dPos&    pos
  693. //            New location for the front lower left corner.
  694. void
  695. BPPlot::MoveFrontLowerLeftCorner (const v3dPos& pos)
  696. {
  697.     GetObject()->MoveAbsolute (v3dVector (pos.x() + length_ / 2,
  698.         pos.y() - height_ / 2,
  699.         pos.z() + depth_ / 2));
  700. }
  701.  
  702. void
  703. BPPlot::HideFrame ()
  704. {
  705.     frame_left_->Hide();
  706.     frame_right_->Hide();
  707.     frame_top_->Hide();
  708.     frame_bottom_->Hide();
  709.     frame_hidden_ = true;
  710. }
  711.  
  712. void
  713. BPPlot::ShowFrame ()
  714. {
  715.     frame_left_->Show();
  716.     frame_right_->Show();
  717.     frame_top_->Show();
  718.     frame_bottom_->Show();
  719.     frame_hidden_ = false;
  720. }
  721.  
  722. // BPPlot::Scale
  723. //    Stretches the BP plot about a point by the given factors.
  724. void
  725. BPPlot::Scale (const v3dVector &factors, const v3dPos& point)
  726. {
  727.     scale_background_and_frame(factors, point);
  728.  
  729.     v3dDim dim = bounding_box_->GetSize();
  730.     length_ = dim.x();
  731.     height_ = dim.y();
  732.     depth_ = dim.z();
  733.  
  734.     calculate_plot_variables();
  735.     calculate_scale_variables();
  736.  
  737.     scale_baseline(factors, point);
  738.  
  739.     fix_hide_interval();
  740. }
  741.  
  742. // BPPlot::SetSize
  743. //    Sets the exact size of the BP.
  744. inline void
  745. BPPlot::SetSize (const v3dDim &dimensions)
  746. {
  747.     Scale (v3dVector (dimensions.x() / length_,
  748.         dimensions.y() / height_,
  749.         dimensions.z() / depth_));
  750. }
  751.  
  752. // BPPlot::ChangeSweepSpeed
  753. //    Increases or decreases the sweep speed of the BP plot by the
  754. //    specified factor.
  755. //    The number of increments on the baseline is either increased or
  756. //    decreased, and the baseline as a whole is scaled up or down.
  757. // Parameters:
  758. //    float    change_factor
  759. //            Factor to change the speed by.  For example,
  760. //                1 = no change,
  761. //                1.05 = 5% faster,
  762. //                0.95 = 5% slower
  763. void
  764. BPPlot::ChangeSweepSpeed (float change_factor)
  765. {
  766.     int new_num_increments = (int)trunc (num_increments_ * change_factor);
  767.     if (new_num_increments < Minimum_Num_Increments)
  768.         new_num_increments = Minimum_Num_Increments;
  769.  
  770.     if (change_factor > 1)
  771.         extend_baseline (num_increments_, new_num_increments);
  772.     else
  773.         shrink_baseline (num_increments_, new_num_increments);
  774.     num_increments_ = new_num_increments;
  775.  
  776.     increment_length_ = baseline_length_ / new_num_increments;
  777.     scale_baseline (v3dVector (1/change_factor, 1, 1),
  778.                 origin_->GetAbsolutePosition());
  779.  
  780.     fix_hide_interval();
  781. }
  782.  
  783. // BPPlot::~BPPlot
  784. BPPlot::~BPPlot ()
  785. {
  786.     delete_baseline();
  787.     delete_background_and_frame();
  788. }
  789.  
  790. void
  791. BPPlot::switch_data ()
  792. {
  793.     last_drv_index_ = 0;
  794.     data_range_ = BP_driver_->GetDataRange();
  795.     calculate_scale_variables();
  796. }
  797.  
  798.