#include "stdafx.h" #include "DS_1b_cube.h" using namespace std; //------------------------------------------------------------------------------------ // drawLine6Connected() // Description - Marks a line within the cube that is 6-connected (face only), with // value of 'draw_value', from point start_coord to end_coord. //------------------------------------------------------------------------------------ void DS_1b_cube::drawLine6Connected( Vect3usi &start_coord, Vect3usi &end_coord, bool draw_value ) { float dx = (float)end_coord.x - start_coord.x; float dy = (float)end_coord.y - start_coord.y; float dz = (float)end_coord.z - start_coord.z; float mdist = ((dx>=0)?(dx):(-dx)) + ((dy>=0)?(dy):(-dy)) + ((dz>=0)?(dz):(-dz)); Vect3usi cur_coord = start_coord; // Mark start and end spots if ( draw_value ) { this->set_spot_1( start_coord ); this->set_spot_1( end_coord ); } else { this->set_spot_0( start_coord ); this->set_spot_0( end_coord ); } dx = dx/mdist; dy = dy/mdist; dz = dz/mdist; float tx = 0, ty = 0, tz = 0; while ( cur_coord != end_coord ) { tx += dx; // Make sure enough difference has been built up to warrant a full voxel progression if ( (tx >= 1.0f) || (tx <= -1.0f) ) { (tx > 0) ? (++cur_coord.x) : (--cur_coord.x); // Make sure we are not next to the goal voxel yet if ( end_coord == cur_coord ) { return; } else { // Mark the spot if ( draw_value ) { this->set_spot_1( cur_coord ); } else { this->set_spot_0( cur_coord ); } } // If we are at the goal, make delta 0 so we never enter here again if ( end_coord.x == cur_coord.x ) { dx = 0.0f; } // Reduce tx by one, since we have just added an offset path node (tx > 0) ? (--tx):(++tx); } // ====================== Repeat above for z and y deltas as well ====================== // ty += dy; if ( (ty >= 1.0f) || (ty <= -1.0f) ) { (ty > 0) ? (++cur_coord.y) : (--cur_coord.y); if ( end_coord == cur_coord ) { return; } else { if ( draw_value ) { this->set_spot_1( cur_coord ); } else { this->set_spot_0( cur_coord ); } } if ( end_coord.y == cur_coord.y ) { dy = 0.0f; } (ty > 0) ? (--ty):(++ty); } tz += dz; if ( (tz >= 1.0f) || (tz <= -1.0f) ) { (tz > 0) ? (++cur_coord.z) : (--cur_coord.z); if ( end_coord == cur_coord ) { return; } else { if ( draw_value ) { this->set_spot_1( cur_coord ); } else { this->set_spot_0( cur_coord ); } } if ( end_coord.z == cur_coord.z ) { dz = 0.0f; } (tz > 0) ? (--tz):(++tz); } } } //------------------------------------------------------------------------------------ // drawSolidBox() // Description - Marks a line within the cube that is 6-connected (face only), with // value of 'draw_value', from point start_coord to end_coord. //------------------------------------------------------------------------------------ void DS_1b_cube::drawSolidBox( Vect3usi &corner_coord, Vect3usi &dimensions, bool fill_value ) { Vect3usi cur_coord; Vect3usi end_coord = corner_coord; end_coord.add( dimensions ); for ( cur_coord.z = corner_coord.z; cur_coord.z < end_coord.z; cur_coord.z ++ ) { for ( cur_coord.y = corner_coord.y; cur_coord.y < end_coord.y; cur_coord.y ++ ) { for ( cur_coord.x = corner_coord.x; cur_coord.x < end_coord.x; cur_coord.x ++ ) { if ( fill_value ) { this->set_spot_1( cur_coord ); } else { this->set_spot_0( cur_coord ); } } } } } //------------------------------------------------------------------------------------ // drawSolidSphere() // Description - Draws a sphere, will 'fill_value' everywhere between provided // inner diameter and outer diameter. This is very similar to the // Sphere Grow code, but does not use a precomputed sqrt table. //------------------------------------------------------------------------------------ void DS_1b_cube::drawSolidSphere( Vect3usi ¢er_coord, unsigned short inn_diam, unsigned short out_diam, bool fill_value) { short int dz, dy; int z_m_dz, z_p_dz, y_m_dy, y_p_dy, x_m_dx, x_p_dx; short int dx, dx_inner_lim, dx_outer_lim; unsigned short z, y, x; unsigned short rad = (out_diam)/2; unsigned short inn_rad = (inn_diam)/2; unsigned int rad2; unsigned int inn_rad2; unsigned int dz2, dz2_dy2; unsigned short dy_range; if ( (out_diam%2) == 0 ) { rad2 = rad*rad; } else { rad2 = (unsigned int)(((double)rad+0.5f)*((double)rad+0.5f)); // inn_rad2 = (unsigned int)(((double)inn_rad+0.5f)*((double)inn_rad+0.5f)); } inn_rad2 = inn_rad*inn_rad; center_coord.to_zyx(z, y, x); // Set initial spot to final diameter if spreading entire sphere if ( inn_diam == 0 ) { // Mark the spot if ( fill_value ) { this->set_spot_1( z, y, x ); } else { this->set_spot_0( z, y, x ); } } for (dz = 0; dz <= rad; dz++) { dz2 = dz*dz; z_p_dz = z+dz; z_m_dz = z-dz; dy_range = (unsigned short)sqrt((double)rad2 - dz2); for (dy = 0; dy <= dy_range; dy++) { dz2_dy2 = dz2 + dy*dy; y_p_dy = y+dy; y_m_dy = y-dy; dx_outer_lim = (unsigned short)(0.5+sqrt((double)rad2 - dz2_dy2)); if (dz2_dy2 > inn_rad2) dx_inner_lim = -1; else dx_inner_lim = (unsigned short)sqrt((double)inn_rad2 - dz2_dy2); for (dx = dx_outer_lim; dx > dx_inner_lim; dx--) { x_p_dx = x+dx; x_m_dx = x-dx; //pos z, pos y if (z_p_dz < this->wZ) { if (y_p_dy < this->wY) { if (x_p_dx < this->wX) { this->set_spot((unsigned short)z_p_dz, (unsigned short)y_p_dy, (unsigned short)x_p_dx, fill_value); } if ( (x_m_dx != x_p_dx) && (x_m_dx >= 0) ) { this->set_spot((unsigned short)z_p_dz, (unsigned short)y_p_dy, (unsigned short)x_m_dx, fill_value); } } if ( (y_m_dy != y_p_dy) && (y_m_dy >= 0) ) {//neg y if (x_p_dx < this->wX) { this->set_spot((unsigned short)z_p_dz, (unsigned short)y_m_dy, (unsigned short)x_p_dx, fill_value); } if ( (x_m_dx != x_p_dx) && (x_m_dx >= 0) ) { this->set_spot((unsigned short)z_p_dz, (unsigned short)y_m_dy, (unsigned short)x_m_dx, fill_value); } } } //neg z if ( (z_m_dz != z_p_dz) && (z_m_dz >= 0) ) {//pos y if (y_p_dy < this->wY) { if (x_p_dx < this->wX) { this->set_spot((unsigned short)z_m_dz, (unsigned short)y_p_dy, (unsigned short)x_p_dx, fill_value); } if ( (x_m_dx != x_p_dx) && (x_m_dx >= 0) ) { this->set_spot((unsigned short)z_m_dz, (unsigned short)y_p_dy, (unsigned short)x_m_dx, fill_value); } } if ( (y_m_dy != y_p_dy) && (y_m_dy >= 0) ) {//neg y if (x_p_dx < this->wX) { this->set_spot((unsigned short)z_m_dz, (unsigned short)y_m_dy, (unsigned short)x_p_dx, fill_value); } if ( (x_m_dx != x_p_dx) && (x_m_dx >= 0) ) { this->set_spot((unsigned short)z_m_dz, (unsigned short)y_m_dy, (unsigned short)x_m_dx, fill_value); } } } }//end FOR DX }//end FOR DY }//end FOR DZ }