#!/usr/local/bin/perl # # Program name: phase1 Larry Gales, 11-1999 # # Purpose: # This program is desighed to prepare data to feed into a "phase2" # program which generates a VRML file to be displayed in 3D. # It reads in two data files: a "specifications" file which contains # information about the data and the 3D plot, and a raw data file # which contains the data to be plotted. To make this description # specific, lets suppose we are plottting a file that deals with population # and the two files are named: "pop.spc" and "pop.raw". # The "pop.spc" file contains several lines in this sequence and format: # # // Data and Axis information # Type=cone, color=red, width=0.2, height=0.4 # Xcol=2, Ycol=1, Zcol=4 # Xcolor=white, Xgrid=10, Xname=Population # Ycolor=white, Ygrid=10, Yname=Growth Rate # Zcolor=white, Zgrid=6, Zname=Region # // Title # type=text,color=white,x=50,y=150,z=0,string=Growth Rate by Region # // Legend # type=cone,color=yellow,x=0, y=120,z=0,height=4,width=3 # type=text,color=yellow,x=10,y=120,z=0,size=9, string=:Africa # type=cone,color=red ,x=0, y=130,z=0,height=4,width=3 # type=text,color=red ,x=10,y=130,z=0,size=9, string=:Asia # # This means that: # the X coord is in column 2 and its values are converted to 0 - 100 # the Y coord is in column 1 and its values are converted to 0 - 70 # the Z coord is in column 4 and its values are converted to 0 - 30 # The X-axis is white, has 10 grid lines, and labeled with "Population" # The Y-axis is white, has 10 grid lines, and labeled with "Growth Rate" # The Z-axis is white, has 6 grid lines, and labeled with "Region" # # It has a white title at the top that says "Growth Rate by Region" # and the legend says that yellow cones mark "Africa" and red cones # mark Asia. # # # The "pop.raw" file contains the data columns from which we extract # the X, Y, and Z coordinates. Note: data lines with a "//" in it are # comments and are ignored by the program. # # The output consists of lines that describe the axes, along with # x, y, and z coordinates appended to the data description: # # Type = cone, color = green, width=0.2, height=0.4,x=23,y=44,z=16 # Type = cone, color = green, width=0.2, height=0.4,x=12,y=33,z=17 # Type = cone, color = green, width=0.2, height=0.4,x=22,y=22,z=18 # Type = cone, color = green, width=0.2, height=0.4,x=13,y=11,z=19 # Type = cone, color = green, width=0.2, height=0.4,x=14,y=55,z=20 # Type = cone, color = green, width=0.2, height=0.4,x=15,y=66,z=21 # # Note that one may wish to edit the output of this program (pop.data) # to change say, the colors or sizes of data elements # # Invocation: # mead% phase1 pop.spc pop.raw pop.data # $Xrange=100; $Yrange=100; $Zrange=100; # Initialize variables $height=0; $width =0; $radius= 0; $type =0; $color =0; $size = 0; $Xgrid =0; $Ygrid =0; $Zgrid = 0; $Xcolor="white"; $Ycolor="white"; $Zcolor="white"; # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ # Determine what files are available: there should be 3 file arguments $Nargs = @ARGV; if ( $Nargs != 3 ) { print "ERROR: there must be 3 file arguments. The input should \n"; print " be: phase1 xxx.spc xxx.raw xxx.data \n"; exit(1); } open(SPC,"<$ARGV[0]"); # Plot specifications open(RAW,"<$ARGV[1]"); # Raw data open(DATA,">$ARGV[2]"); # Output data # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ # Read in the VRML header information in terms of coordinates and ranges # Read in VRML header line while ( ) { # Read in VRML header line if ( $_ =~ /\bdata and axis\b/i ) { next; } if ( $_ =~ /\btitle\b/i ) { last; } chop; @pairs = split( /,/, $_); $len = @pairs; for ( $j=0; $j < $len; $j++ ) { ($t,$v) = split(/=/, $pairs[$j]); if ( $t =~ /\btype\b/i ) { $type = $v; } elsif ( $t =~ /\bcolor\b/i) { $color = $v; } elsif ( $t =~ /\bsize\b/i ) { $size = $v; } elsif ( $t =~ /\bheight\b/i ) { $height = $v; } elsif ( $t =~ /\bwidth\b/i ) { $width = $v; } elsif ( $t =~ /\bradius\b/i ) { $radius = $v; } elsif ( $t =~ /\bxname\b/i ) { $Xname = $v; } elsif ( $t =~ /\byname\b/i ) { $Yname = $v; } elsif ( $t =~ /\bzname\b/i ) { $Zname = $v; } elsif ( $t =~ /\bxcol\b/i ) { $x = $v; } elsif ( $t =~ /\bycol\b/i ) { $y = $v; } elsif ( $t =~ /\bzcol\b/i ) { $z = $v; } elsif ( $t =~ /\bxcolor\b/i ) { $Xcolor = $v; } elsif ( $t =~ /\bycolor\b/i ) { $Ycolor = $v; } elsif ( $t =~ /\bzcolor\b/i ) { $Zcolor = $v; } elsif ( $t =~ /\bxgrid\b/i ) { $Xgrid = $v; } elsif ( $t =~ /\bygrid\b/i ) { $Ygrid = $v; } elsif ( $t =~ /\bzgrid\b/i ) { $Zgrid = $v; } elsif ( $t =~ /\bxrange\b/i ) { $Xrange = $v; $Xrange = ($Xrange > 100 ) ? 100 : $Xrange; # Limit Xrange <= 100 } elsif ( $t =~ /\byrange\b/i ) { $Yrange = $v; $Yrange = ($Yrange > 100 ) ? 100 : $Yrange; # Limit Yrange <= 100 } elsif ( $t =~ /\bzrange\b/i ) { $Zrange = $v; $Zrange = ($Zrange > 100 ) ? 100 : $Zrange; # Limit Zrange <= 100 } } } print DATA $_; # print out the Title and Legend info while ( ) { # as is print DATA $_; } close( SPC); # vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ # Now scan thru the data and determine the min/max values of each coord. open(TEMP,">xTempx"); $Xmax = -999999999.0; $Xmin = 99999999999.0; $Ymax = -999999999.0; $Ymin = 99999999999.0; $Zmax = -999999999.0; $Zmin = 99999999999.0; while ( ) { # Scan thru data to locate max and min print TEMP $_; chop; $line = $_; if ( $line =~ /\/\// ) { # Ignore comment lines next; } $line =~ s/(^\s*)(\w)/$2/; $line =~ s/(\s+)/_/g; @coords = split(/_/, $line); $xc = $coords[ $x-1 ]; $yc = $coords[ $y-1 ]; $zc = $coords[ $z-1 ]; $Xmax = ($xc > $Xmax) ? $xc : $Xmax; $Ymax = ($yc > $Ymax) ? $yc : $Ymax; $Zmax = ($zc > $Zmax) ? $zc : $Zmax; $Xmin = ($xc < $Xmin) ? $xc : $Xmin; $Ymin = ($yc < $Ymin) ? $yc : $Ymin; $Zmin = ($zc < $Zmin) ? $zc : $Zmin; } $Ax = $Xrange/($Xmax - $Xmin); # Compute factors to normalize data $Ay = $Yrange/($Ymax - $Ymin); # between 0 and 100 $Az = $Zrange/($Zmax - $Zmin); $Bx = (- $Xrange * $Xmin)/($Xmax - $Xmin); $By = (- $Yrange * $Ymin)/($Ymax - $Ymin); $Bz = (- $Zrange * $Zmin)/($Zmax - $Zmin); close (TEMP); open(TEMP,"xTempx"); $Xspan = $Xmin . "-" . $Xmax; $Yspan = $Ymin . "-" . $Ymax; $Zspan = $Zmin . "-" . $Zmax; print DATA "type=x-axis,color=$Xcolor,max=$Xrange,span=$Xspan,thick=1,"; print DATA "grid=$Xgrid,name=$Xname\n"; print DATA "type=y-axis,color=$Ycolor,max=$Yrange,span=$Yspan,thick=1,"; print DATA "grid=$Ygrid,name=$Yname\n"; print DATA "type=z-axis,color=$Zcolor,max=$Zrange,span=$Zspan,thick=1,"; print DATA "grid=$Zgrid,name=$Zname\n"; if ( $type =~ /cone/i ) { $first_part = "type=cone,height=$height,width=$width,color=$color "; } elsif ( $type =~ /cylinder/i ) { $first_part = "type=cylinder,height=$height,width=$width,color=$color "; } elsif ( $type =~ /sphere/i ) { $first_part = "type=shere,radius=$radius,color=$color "; } elsif ( $type =~ /box/i ) { $first_part = "type=box,size=$size,color=$color "; } elsif ( $type =~ /text/i ) { $first_part = "type=text,size=$size,string=x ,color=$color "; } else { print "ERROR: wrong type = $type \n"; } print DATA "// \n"; print DATA "//Real min. X = $Xmin, real max. X = $Xmax, converted to 0 $Xrange \n"; print DATA "//Real min. Y = $Ymin, real max. Y = $Ymax, converted to 0 $Yrange \n"; print DATA "//Real min. Z = $Zmin, real max. Z = $Zmax, converted to 0 $Zrange \n"; print DATA "// \n"; # vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ # Now re-read the data and convert coordinates to 0 - $Xrange etc. while ( ) { chop; $line = $_; if ( $line =~ /\/\// ) { # Ignore comment lines print DATA "$_\n"; next; } $line =~ s/(^\s*)(\w)/$2/; $line =~ s/(\s+)/_/g; @coords = split(/_/, $line); $xc = $coords[ $x-1 ]; $yc = $coords[ $y-1 ]; $zc = $coords[ $z-1 ]; $xc = ($Ax * $xc + $Bx) % 101; # Convert to 0 - Xrange $yc = ($Ay * $yc + $By) % 101; $zc = ($Az * $zc + $Bz) % 101; $newline = $first_part . ",x=" . $xc . ",y=" . $yc . ",z=" . $zc; print DATA "$newline \n"; } close (TEMP ); # vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv