#! /usr/bin/gawk -f # Last edited on 2009-05-02 20:23:55 by stolfilocal # Reads from stdin the Cartesian or Homogneous coordinates of one or more 3D points, # outputs the corresponding 2D coordinates in the figure. # Input must have one point per line. # If 3 coords are given, assumes Cartesian. # If 4 coords are given, assumes homogeneous with weight at front. BEGIN { abort = -1; split("", R); R[1,1] = 135.42299444176988051780; R[1,2] = 37.79246356514508293520; R[2,1] = 184.57700555823011946000; R[2,2] = 27.72809412442669114516; R[3,1] = 0.00000000000000000000; R[3,2] = -224.07797950339221983107; split("", M); M[1,1] = +1.00000000000000000000; M[1,2] = 320.00000000000000000000; M[1,3] = 400.00000000000000000000; M[2,1] = -0.15746859818810451223; M[2,2] = -135.42299444176988051780; M[2,3] = 37.79246356514508293520; M[3,1] = -0.03418092695522779990; M[3,2] = 184.57700555823011946000; M[3,3] = 27.72809412442669114516; M[4,1] = -0.04978737949333313041; M[4,2] = 0.00000000000000000000; M[4,3] = -224.07797950339221983107; } # Abort on error: (abort >= 0) { exit abort; } # Remove funny spaces: //{ gsub(/[\011\015]/, " ", $0); } # Save original coords and comments, remove previous "--> ...": //{ orig = $0; gsub(/[ ]*([\#].*|[-][-][>].*|)$/, "", orig); comm = $0; gsub(/^[^\#]*([\#][ ]*|$)/, " ", comm); } # Remove delimiters and separators: //{ $0 = orig; gsub(/[\[\],;<>()]+/, " ", $0); } # Skip empty lines: /^[ ]*$/{ print ""; next; } # Process Cartesian coords: (NF == 3) { w = 1; x = $1; y = $2; z = $3; map_point_and_write(w,x,y,z,orig,comm); next; } # Process homogeneous coords: (NF == 4) { w = $1; x = $2; y = $3; z = $4; map_point_and_write(w,x,y,z,orig,comm); next; } # Errors: //{ data_error("invalid input format"); } function map_point_and_write(w,x,y,z,orig,comm, wm,xm,ym,X,Y) { w = w + 0.0; x = x + 0.0; y = y + 0.0; z = z + 0.0; wm = w*M[1,1] + x*M[2,1] + y*M[3,1] + z*M[4,1]; xm = w*M[1,2] + x*M[2,2] + y*M[3,2] + z*M[4,2]; ym = w*M[1,3] + x*M[2,3] + y*M[3,3] + z*M[4,3]; X = xm/wm; Y = ym/wm; printf "%s --> %05.1f,%05.1f", orig, X, Y; if (comm != "") { printf " # %s", comm; } printf "\n" } function data_error(msg) { printf "%s:%s: ** %s\n", FILENAME, FNR, msg > "/dev/stderr"; abort = 1 exit abort }