function bezier_surface_display ( node_file_name, rectangle_file_name ) %*****************************************************************************80 % %% BEZIER_SURFACE displays the faces of a shape defined by a Bezier surface file. % % Licensing: % % This code is distributed under the GNU LGPL license. % % Modified: % % 10 February 2010 % % Author: % % John Burkardt % % Usage: % % bezier_surface_display ( 'node_file_name', 'rectangle_file_name' ) % % Parameters: % % Input, character NODE_FILE_NAME, the name of the node file. % % Input, character RECTANGLE_FILE_NAME, the name of the rectangle file. % timestamp ( ); fprintf ( 1, '\n' ); fprintf ( 1, 'BEZIER_SURFACE_DISPLAY\n' ); fprintf ( 1, ' MATLAB version\n' ); fprintf ( 1, ' Reads the nodes and rectangles defining\n' ); fprintf ( 1, ' a Bezier surface and displays the object\n' ); fprintf ( 1, ' as a MATLAB shape.\n' ); % % If at least one command line argument, it's the node file name. % if ( nargin < 1 ) fprintf ( 1, '\n' ); fprintf ( 1, 'BEZIER_SURFACE_DISPLAY:\n' ); node_file_name = input ( 'Enter the name of the node file:' ); end % % If at least two command line arguments, it's the node file name. % if ( nargin < 2 ) fprintf ( 1, '\n' ); fprintf ( 1, 'BEZIER_SURFACE_DISPLAY:\n' ); rectangle_file_name = input ( 'Enter the name of the rectangle file:' ); end % % Read the nodes. % [ node_num, node_xyz ] = bezier_surface_node_file_read ( node_file_name ); fprintf ( 1, '\n' ); fprintf ( 1, ' Number of nodes = %d\n', node_num ); % % Read the rectangles. % [ rectangle_num, rectangle_node ] = bezier_surface_rectangle_file_read ( ... rectangle_file_name ); fprintf ( 1, ' Number of rectangles = %d\n', rectangle_num ); % % Display the crude image as a collection of rectangular patches involving only % the corner nodes. % corners = [1,4,16,13]; face_matrix = rectangle_node(corners,1:rectangle_num)'; handle = patch ( 'Vertices', node_xyz', 'Faces', face_matrix ); set ( handle, 'FaceColor', [0.5, 0.6, 0.8], 'EdgeColor', 'Black' ); axis equal; grid on; xlabel ( '--X Axis--' ) ylabel ( '--Y Axis--' ) zlabel ( '--Z Axis--' ) % % The TITLE function will interpret underscores in the title. % We need to unescape such escape sequences! % title_string = s_escape_tex ( rectangle_file_name ); title ( title_string ) % % Terminate. % fprintf ( 1, '\n' ); fprintf ( 1, 'BEZIER_SURFACE_DISPLAY:\n' ); fprintf ( 1, ' Normal end of execution.\n' ); fprintf ( 1, '\n' ); timestamp ( ); return end function [ node_num, node_xyz ] = bezier_surface_node_file_read ( ... node_file_name ) %*****************************************************************************80 % %% BEZIER_SURFACE_NODE_FILE_READ reads node information from a Bezier surface node file. % % Licensing: % % This code is distributed under the GNU LGPL license. % % Modified: % % 11 June 2006 % % Author: % % John Burkardt % % Reference: % % Edward Angel, % Interactive Computer Graphics, % a Top-Down Approach with OpenGL, % Addison-Wesley, 2000. % % Parameters: % % Input, string NODE_FILE_NAME, the name of the node file. % % Output, integer NODE_NUM, the number of nodes defined. % % Output, real NODE_XYZ(3,NODE_NUM), the coordinates of nodes. % [ dim_num, node_num ] = r8mat_header_read ( node_file_name ); node_xyz = r8mat_data_read ( node_file_name, dim_num, node_num ); return end function [ rectangle_num, rectangle_node ] = ... bezier_surface_rectangle_file_read ( rectangle_file_name ) %*****************************************************************************80 % %% BEZIER_SURFACE_RECTANGLE_FILE_READ reads rectangles from a Bezier surface rectangle file. % % Licensing: % % This code is distributed under the GNU LGPL license. % % Modified: % % 11 June 2006 % % Author: % % John Burkardt % % Reference: % % Edward Angel, % Interactive Computer Graphics, % a Top-Down Approach with OpenGL, % Addison-Wesley, 2000. % % Parameters: % % Input, string RECTANGLE_FILE_NAME, the name of the rectangle file. % % Output, integer RECTANGLE_NUM, the number of rectangles defined. % % Output, real RECTANGLE_NODE(4,RECTANGLE_NUM), the nodes making up each rectangle. % [ dim_num, rectangle_num ] = i4mat_header_read ( rectangle_file_name ); rectangle_node = i4mat_data_read ( rectangle_file_name, ... dim_num, rectangle_num ); return end function column_num = file_column_count ( input_file_name ) %*****************************************************************************80 % %% FILE_COLUMN_COUNT counts the columns in the first line of a file. % % Discussion: % % The file is assumed to be a simple text file. % % Most lines of the file are presumed to consist of COLUMN_NUM words, % separated by spaces. There may also be some blank lines, and some % comment lines, which have a "#" in column 1. % % The routine tries to find the first non-comment non-blank line and % counts the number of words in that line. % % If all lines are blanks or comments, it goes back and tries to analyze % a comment line. % % Licensing: % % This code is distributed under the GNU LGPL license. % % Modified: % % 21 February 2004 % % Author: % % John Burkardt % % Parameters: % % Input, string INPUT_FILE_NAME, the name of the file. % % Output, integer COLUMN_NUM, the number of columns in the file. % FALSE = 0; TRUE = 1; % % Open the file. % input_unit = fopen ( input_file_name ); if ( input_unit < 0 ) fprintf ( 1, '\n' ); fprintf ( 1, 'FILE_COLUMN_COUNT - Error!\n' ); fprintf ( 1, ' Could not open the file "%s".\n', input_file_name ); error ( 'FILE_COLUMN_COUNT - Error!' ); end % % Read one line, but skip blank lines and comment lines. % Use FGETL so we drop the newline character! % got_one = FALSE; while ( 1 ) line = fgetl ( input_unit ); if ( line == -1 ) break; end if ( s_len_trim ( line ) == 0 ) elseif ( line(1) == '#' ) else got_one = TRUE; break; end end fclose ( input_unit ); if ( got_one == FALSE ) fprintf ( 1, '\n' ); fprintf ( 1, 'FILE_COLUMN_COUNT - Warning!\n' ); fprintf ( 1, ' The file does not seem to contain any data.\n' ); column_num = -1; return; end column_num = s_word_count ( line ); return end function row_num = file_row_count ( input_file_name ) %*****************************************************************************80 % %% FILE_ROW_COUNT counts the number of row records in a file. % % Discussion: % % Each input line is a "RECORD". % % The records are divided into three groups: % % * BLANK LINES (nothing but blanks) % * COMMENT LINES (begin with a '#') % * DATA RECORDS (anything else) % % The value returned by the function is the number of data records. % % By the way, if the MATLAB routine FGETS is used, instead of % FGETL, then the variable LINE will include line termination % characters, which means that a blank line would not actually % have zero characters. % % Licensing: % % This code is distributed under the GNU LGPL license. % % Modified: % % 31 December 2006 % % Author: % % John Burkardt % % Parameters: % % Input, string INPUT_FILE_NAME, the name of the input file. % % Output, integer ROW_NUM, the number of rows found. % input_unit = fopen ( input_file_name ); if ( input_unit < 0 ) fprintf ( 1, '\n' ); fprintf ( 1, 'FILE_ROW_COUNT - Error!\n' ); fprintf ( 1, ' Could not open the file "%s".\n', input_file_name ); error ( 'FILE_ROW_COUNT - Error!' ); end blank_num = 0; comment_num = 0; row_num = 0; record_num = 0; while ( 1 ) line = fgetl ( input_unit ); if ( line == -1 ) break; end record_num = record_num + 1; record_length = s_len_trim ( line ); if ( record_length <= 0 ) blank_num = blank_num + 1; elseif ( line(1) == '#' ) comment_num = comment_num + 1; else row_num = row_num + 1; end end fclose ( input_unit ); return end function table = i4mat_data_read ( input_filename, m, n ) %*****************************************************************************80 % %% I4MAT_DATA_READ reads data from an I4MAT file. % % Discussion: % % An I4MAT is an array of I4's. % % Licensing: % % This code is distributed under the GNU LGPL license. % % Modified: % % 08 February 2010 % % Author: % % John Burkardt % % Parameters: % % Input, string INPUT_FILENAME, the name of the input file. % % Input, integer M, N, the number of rows and columns in the data. % % Output, integer TABLE(M,N), the point coordinates. % % % Build up the format string for reading M real numbers. % string = ' '; for i = 0 : m string = strcat ( string, ' %d' ); end input_unit = fopen ( input_filename ); if ( input_unit < 0 ) fprintf ( 1, '\n' ); fprintf ( 1, 'I4MAT_DATA_READ - Error!\n' ); fprintf ( 1, ' Could not open the input file.\n' ); error ( 'I4MAT_DATA_READ - Error!' ); end table = zeros ( m, n ); i = 0; while ( i < n ) line = fgets ( input_unit ); if ( line == -1 ) fprintf ( 1, '\n' ); fprintf ( 1, 'I4MAT_DATA_READ - Error!\n' ); fprintf ( 1, ' End of input while reading data.\n' ); error ( 'I4MAT_DATA_READ - Error!' ); end if ( line(1) == '#' ) elseif ( s_len_trim ( line ) == 0 ) else [ x, count ] = sscanf ( line, string ); if ( count == m ) i = i + 1; table(1:m,i) = x(1:m); end end end fclose ( input_unit ); return end function [ m, n ] = i4mat_header_read ( input_filename ) %*****************************************************************************80 % %% I4MAT_HEADER_READ reads the header from an I4MAT file. % % Discussion: % % An I4MAT is an array of I4's. % % Licensing: % % This code is distributed under the GNU LGPL license. % % Modified: % % 22 October 2004 % % Author: % % John Burkardt % % Parameters: % % Input, string INPUT_FILENAME, the name of the input file. % % Output, integer M, the spatial dimension. % % Output, integer N, the number of points. % m = file_column_count ( input_filename ); if ( m <= 0 ) fprintf ( 1, '\n' ); fprintf ( 1, 'I4MAT_HEADER_READ - Fatal error!\n' ); fprintf ( 1, ' There was some kind of I/O problem while trying\n' ); fprintf ( 1, ' to count the number of data columns in\n' ); fprintf ( 1, ' the file %s.\n', input_filename ); end n = file_row_count ( input_filename ); if ( n <= 0 ) fprintf ( 1, '\n' ); fprintf ( 1, 'I4MAT_HEADER_READ - Fatal error!\n' ); fprintf ( 1, ' There was some kind of I/O problem while trying\n' ); fprintf ( 1, ' to count the number of data rows in\n' ); fprintf ( 1, ' the file %s\n', input_filename ); end return end function table = r8mat_data_read ( input_filename, m, n ) %*****************************************************************************80 % %% R8MAT_DATA_READ reads data from an R8MAT file. % % Discussion: % % An R8MAT is an array of R8's. % % Licensing: % % This code is distributed under the GNU LGPL license. % % Modified: % % 08 February 2010 % % Author: % % John Burkardt % % Parameters: % % Input, string INPUT_FILENAME, the name of the input file. % % Input, integer M, N, the number of rows and columns of data. % % Output, real TABLE(M,N), the point coordinates. % % % Build up the format string for reading M real numbers. % string = ' '; for i = 0 : m string = strcat ( string, ' %f' ); end input_unit = fopen ( input_filename ); if ( input_unit < 0 ) fprintf ( 1, '\n' ); fprintf ( 1, 'R8MAT_DATA_READ - Error!\n' ); fprintf ( 1, ' Could not open the file.\n' ); error ( 'R8MAT_DATA_READ - Error!' ); end table = zeros(m,n); i = 0; while ( i < n ) line = fgets ( input_unit ); if ( line == -1 ) break; end if ( line(1) == '#' ) elseif ( s_len_trim ( line ) == 0 ) else [ x, count ] = sscanf ( line, string ); if ( count == m ) i = i + 1; table(1:m,i) = x(1:m); end end end fclose ( input_unit ); return end function [ m, n ] = r8mat_header_read ( input_filename ) %*****************************************************************************80 % %% R8MAT_HEADER_READ reads the header from an R8MAT file. % % Discussion: % % An R8MAT is an array of R8's. % % Licensing: % % This code is distributed under the GNU LGPL license. % % Modified: % % 22 October 2004 % % Author: % % John Burkardt % % Parameters: % % Input, string INPUT_FILENAME, the name of the input file. % % Output, integer M, the spatial dimension. % % Output, integer N, the number of points. % m = file_column_count ( input_filename ); if ( m <= 0 ) fprintf ( 1, '\n' ); fprintf ( 1, 'R8MAT_HEADER_READ - Fatal error!\n' ); fprintf ( 1, ' There was some kind of I/O problem while trying\n' ); fprintf ( 1, ' to count the number of data columns in\n' ); fprintf ( 1, ' the file %s.\n', input_filename ); end n = file_row_count ( input_filename ); if ( n <= 0 ) fprintf ( 1, '\n' ); fprintf ( 1, 'R8MAT_HEADER_READ - Fatal error!\n' ); fprintf ( 1, ' There was some kind of I/O problem while trying\n' ); fprintf ( 1, ' to count the number of data rows in\n' ); fprintf ( 1, ' the file %s\n', input_filename ); end return end function s2 = s_escape_tex ( s1 ) %*****************************************************************************80 % %% S_ESCAPE_TEX de-escapes TeX escape sequences. % % Discussion: % % In particular, every occurrence of the characters '\', '_', % '^', '{' and '}' will be replaced by '\\', '\_', '\^', % '\{' and '\}'. A TeX interpreter, on seeing these character % strings, is then likely to return the original characters. % % Licensing: % % This code is distributed under the GNU LGPL license. % % Modified: % % 19 January 2007 % % Author: % % John Burkardt % % Parameters: % % Input, string S1, the string to be de-escaped. % % Output, string S2, a copy of the string, modified to avoid TeX escapes. % s1_length = length ( s1 ); s1_pos = 0; s2_pos = 0; s2 = []; while ( s1_pos < s1_length ) s1_pos = s1_pos + 1; if ( s1(s1_pos) == '\' || ... s1(s1_pos) == '_' || ... s1(s1_pos) == '^' || ... s1(s1_pos) == '{' || ... s1(s1_pos) == '}' ) s2_pos = s2_pos + 1; s2 = strcat ( s2, '\' ); end s2_pos = s2_pos + 1; s2 = strcat ( s2, s1(s1_pos) ); end return end function len = s_len_trim ( s ) %*****************************************************************************80 % %% S_LEN_TRIM returns the length of a character string to the last nonblank. % % Licensing: % % This code is distributed under the GNU LGPL license. % % Modified: % % 14 June 2003 % % Author: % % John Burkardt % % Parameters: % % Input, string S, the string to be measured. % % Output, integer LEN, the length of the string up to the last nonblank. % len = length ( s ); while ( 0 < len ) if ( s(len) ~= ' ' ) return end len = len - 1; end return end function word_num = s_word_count ( s ) %*****************************************************************************80 % %% S_WORD_COUNT counts the number of "words" in a string. % % Licensing: % % This code is distributed under the GNU LGPL license. % % Modified: % % 30 January 2006 % % Author: % % John Burkardt % % Parameters: % % Input, string S, the string to be examined. % % Output, integer WORD_NUM, the number of "words" in the string. % Words are presumed to be separated by one or more blanks. % FALSE = 0; TRUE = 1; word_num = 0; s_length = length ( s ); if ( s_length <= 0 ) return; end blank = TRUE; for i = 1 : s_length if ( s(i) == ' ' ) blank = TRUE; elseif ( blank == TRUE ) word_num = word_num + 1; blank = FALSE; end end return end function timestamp ( ) %*****************************************************************************80 % %% TIMESTAMP prints the current YMDHMS date as a timestamp. % % Licensing: % % This code is distributed under the GNU LGPL license. % % Modified: % % 14 February 2003 % % Author: % % John Burkardt % t = now; c = datevec ( t ); s = datestr ( c, 0 ); fprintf ( 1, '%s\n', s ); return end