LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (https://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   programm for perspective-grid (https://www.linuxquestions.org/questions/linux-newbie-8/programm-for-perspective-grid-918203/)

zenbo 12-11-2011 01:10 PM

programm for perspective-grid
 
hey guys

i am looking for a program to create perspective-grids to draw skyscrapers, houses etc. in perspective.heres a sample.

http://www.perspectivegrid.com/index.php?page=9^0^0

thanks and greetings zenbo

zenbo

S. Chapelin 12-11-2011 07:18 PM

I don't know if I understand your request, but Blender is great for setting up 3d scenes which you can then render as a picture or film with a moving camera. It's free. I've been playing with it for years. You can make anything from buildings to people, etc.

Dark_Helmet 12-11-2011 07:27 PM

I wasn't sure what a "perspective-grid" was either. Then I did a quick search. If i understand correctly, it's just a 2D projection of squares/rectangles as they diminish to a fixed vanishing point.

Anyway, my terminology notwithstanding, I did see a link to a You Tube video that purports to show how to create perspective grids in GIMP (which should be included in virtually every Linux distribution).

Here's the link: GIMP: How to Create Perspective Grids with the Path Tool

zenbo 12-13-2011 05:53 AM

Quote:

Originally Posted by Dark_Helmet (Post 4547517)
I wasn't sure what a "perspective-grid" was either. Then I did a quick search. If i understand correctly, it's just a 2D projection of squares/rectangles as they diminish to a fixed vanishing point.

Anyway, my terminology notwithstanding, I did see a link to a You Tube video that purports to show how to create perspective grids in GIMP (which should be included in virtually every Linux distribution).

Here's the link: GIMP: How to Create Perspective Grids with the Path Tool

thanks, but that tool is not good enough, it would take me forever...

heres what i mean, those grids are for artists to draw houses etc. over them:

http://www.perspectivegrid.com/index.php?page=9^0^0

Dark_Helmet 12-15-2011 06:31 AM

Well, I was bored and struck by inspiration. So I wrote a script to generate some basic perspective grids using gnuplot.

This probably won't do everything you want it to do. However, it shows that with some scripting, you can modify it and get the features you want.

To use it, you will need to have gnuplot and bc installed. Almost every distribution has bc. So the only thing you might need to install would be gnuplot.

The way it works is, you specify vanishing point coordinates on the command line. You can specify as many as you like, but I've never seen more than two. You also specify an angle increment for each vanishing point. For each vanishing point, a horizontal line is drawn. Then an angled line is drawn through each vanishing point at each angle increment specified.

For instance, you could run the script like so:
Code:

<script_name> -point 10 7 -angle 5 -point 1 7 -angle 10
That would create two vanishing points: (10, 7) and (1, 7). The first vanishing point (10, 7) will have radial lines drawn from it at 5, 10, 15, 20, ... 360 degrees. The second vanishing point (1, 7) will have radial lines drawn from it at 10, 20, 30, 40, ... 360 degrees. Note: the "-angle" option influences the point most recently specified.

The coordinates are in "inches" and the origin would be the bottom-left of the image produced. The script defaults to creating an image for a plain 8.5 x 11 sheet of paper in landscape. The visible coordinates are restricted to the paper size. For instance, using the defaults, x-values from 0 to 11 would be visible and y-values from 0 to 8.5 would be visible.

There is no restriction on the placement of the vanishing points--they need not be placed within the viewable area.

Some caveats:
(1) Because gnuplot is used as the drawing workhorse, it is not a simple matter to have it draw a vertical line. It's not impossible to do (there are directives to manually draw non-function related lines), but I didn't look into it much. Besides, manually drawing one vertical line per vanishing point ain't a lot of inconvenience.

(2) Currently, the angle increment(s) must be integers and they should divide into 180 degrees evenly. If they do not divide into 180 evenly, the radial lines will be "unbalanced."

(3) While this script cannot create the image shown on the website you linked to, it is feasible to use the script two or more times and piece the resulting images together. For instance, to create the "floor" of the image on that webpage, you could run the script once with a few vanishing points (e.g. "<script_name> -point 5.5 8.5 -angle 5 -point 5.5 8 -angle 180 -point 5.5 7 -angle 180 -point 5.5 5 -angle 180"). By placing the first point at the upper limit of the viewing area, you "cut off" the top half of the radial lines. The subsequent points are horizontal lines because their angle increment is 180. You repeat the process for the "roof" by creating another plot, but this time putting the first vanishing point at the bottom of the viewing area and placing the horizontal lines above.

You might also use image manipulation software to do some scaling. Though, it is possible to do that directly through gnuplot. I did not add that into the script, but it could be done.

In all, it's passable and decent (in my opinion) for a few hours of hacking. If you want to try it out, make sure you read the script's comments regarding options it recognizes (e.g. -point, -angle, -dpi, -paperwidth, -paperheight, -output). There is NO nice "usage" help message.

Copy the script into a text editor, save it, make it executable (chmod u+x <script_name>), and then give it a try if you like.

Here's the script
Code:

#!/bin/bash

# Command variables. Currently the script needs gnuplot, bc, printf, and rm
# Customize to your location if the paths are different
cmdGNUPLOT=/usr/bin/gnuplot
cmdBC=/usr/bin/bc
cmdPRINTF=/usr/bin/printf
cmdRM=/bin/rm

# Default angle increment
defaultANGLE=5

# File to hold all the gnuplot commands
dataFILE=/tmp/perspective_grid.gnuplot

# File to save the plot/image to
outputFILE=perspective_grid.png

# Default resolution of the image
dotsPerInch=300

# Physical dimensions of the target paper/canvas (in inches)
paperWidth=11
paperHeight=8.5

# There really should be a "usage" message and/or argument-checker, but
# I'm not motivated to do that right now.
if [ $# -lt 2 ] ; then
  echo "args error"
  exit 1
fi

# coordID is a marker into the array containing vanishing points
coordID=-1
while [ $# -gt 0 ] ; do

  # "-point" identifies a new vanishing point
  # format: "-point <x coordinate> <y coordinate>"
  # coordinates can be floating point
  if [ "${1}" = "-point" ] ; then
    let coordID=coordID+1
    x_coord[${coordID}]=${2}
    y_coord[${coordID}]=${3}
    shift 3
    continue
  fi

  # "-angle" specifies the frequency of radial lines through the vanishing
  #    point in terms of degrees
  # format: "-angle <degrees>"
  # The angle will be applied to the most recently defined vanishing point on
  # the command line.
  # Currently, the angle argument MUST be an integer AND it must be able to
  # divide 180 degrees evenly
  if [ "${1}" = "-angle" ] ; then
    angle_data[${coordID}]=${2}
    shift 2
    continue
  fi

  # "-dpi" specifies the final plot/image resolution (as calculated by the
  #    paper/canvas dimensions)
  # format: "-dpi <dots per inch>
  # The argument should be an integer. Script may work if a float. Untested.
  if [ "${1}" = "-dpi" ] ; then
    dotsPerInch=${2}
    shift 2
    continue
  fi

  # "-paperwidth" and "-paperheight" specify the physical dimensions of the
  #    paper/canvas
  # format: "-paperwidth <size in inches>"
  #        "-paperheight <size in inches>"
  # The argument to either option can be floating point.
  if [ "${1}" = "-paperwidth" ] ; then
    paperWidth=${2}
    shift 2
    continue
  fi

  if [ "${1}" = "-paperheight" ] ; then
    paperHeight=${2}
    shift 2
    continue
  fi


  # "-output" specifies the output image filename
  # format: "-output <filename>"
  if [ "${1}" = "-output" ] ; then
    outputFILE=${1}
    shift 2
    continue
  fi

  echo "ERROR: Unrecognized argument: ${1}"
  exit 2
done

# Calculate the needed resolution of the generated image
pixelWidth=$( echo "${dotsPerInch}*${paperWidth}" | ${cmdBC} -l )
pixelHeight=$( echo "${dotsPerInch}*${paperHeight}" | ${cmdBC} -l )

# Strip/truncate any decimal places--need an integer
pixelWidth=$( ${cmdPRINTF} "%.0f" ${pixelWidth} )
pixelHeight=$( ${cmdPRINTF} "%.0f" ${pixelHeight} )

# Gnuplot directives
# set output -> tells gnuplot where to save the image
# set terminal png size X,Y -> tells gnuplot to save as PNG and at what size
# unset xtics, unset ytics -> remove the numeric values on the axes
# set angle degrees -> use degrees rather than (default) radians
# set key off -> turn off the plot's legend
# set xrange[0:X] -> specify the plot/image's horizontal view
# set yrange[0:Y] -> specify the plot/image's vertical view
echo "set output \"${outputFILE}\"" > ${dataFILE}
echo "set terminal png size ${pixelWidth},${pixelHeight}" >> ${dataFILE}
echo "set size square" >> ${dataFILE}
echo "unset xtics" >> ${dataFILE}
echo "unset ytics" >> ${dataFILE}
echo "set angle degrees" >> ${dataFILE}
echo "set key off" >> ${dataFILE}
echo "set xrange[0:${paperWidth}]" >> ${dataFILE}
echo "set yrange[0:${paperHeight}]" >> ${dataFILE}

# Like with the command line argument parsing, coordID will serve as an
# index into the vanishing point array to work with. Only this time, it
# will work backward.
let coordID=coordID+1

# function_counter is just a number used to suffix the various function
# definitions given to gnuplot so that each function will have a unique
# name.
function_counter=0
while [ ${coordID} -gt 0 ] ; do
  let coordID=coordID-1

  # Give the user a warm and fuzzy by restating command line arguments in a
  # more concise form
  echo "Perspective point: ( ${x_coord[${coordID}]}, ${y_coord[${coordID}]})"
  if [ -z "${angle_data[${coordID}]}" ] ; then
    angle_data[${coordID}]=${defaultANGLE}
  fi
  echo "  Line every ${angle_data[${coordID}]} degrees"

  # angle_counter starts at 180 and is repeatedly subtracted by the specified
  # angle increment
  angle_counter=180
  while [ ${angle_counter} -gt 0 ] ; do

    # Angle = 180 is a horizontal line
    if [ ${angle_counter} -eq 180 ] ; then
      echo "f${function_counter}(x) = ${y_coord[${coordID}]}" >> ${dataFILE}
      let function_counter=function_counter+1
    fi

    if [ ${angle_counter} -eq 90 ] ; then
      echo "# No support for vertical lines yet" >> ${dataFILE}
    else
      # Most interesting case. The function defining the line to draw is:
      # f(x) = (x - vanishing_x) * tan(angle) + vanishing_y
      echo "f${function_counter}(x) = (x - ${x_coord[${coordID}]}) * tan(${angle_counter}) + ${y_coord[${coordID}]}" >> ${dataFILE}
      let function_counter=function_counter+1
    fi

    let angle_counter=angle_counter-${angle_data[${coordID}]}
  done
done

# Construct our "plot" directive to gnuplot by counting backwards through
# all the functions defined in the loop above.
#
# The "lt -1" added after each function reference just tells gnuplot to
# use a black line. By default, gnuplot wants to use multi-colored
# lines to differentiate each function.
echo -n "plot " >> ${dataFILE}
while [ ${function_counter} -gt 0 ] ; do
  let function_counter=function_counter-1
  echo -n "f${function_counter}(x) lt -1" >> ${dataFILE}
  if [ ${function_counter} -gt 0 ] ; then
    echo -n ", " >> ${dataFILE}
  else
    echo "" >> ${dataFILE}
  fi
done

# Creation of the gnuplot data file is finished. Launch gnuplot and point
# it to the file.
${cmdGNUPLOT} ${dataFILE}

if [ $? -eq 0 ] ; then
  echo "GNUPlot exited cleanly. See \"${outputFILE}\" for image"
else
  echo "GNUPlot failed. Please check your arguments and/or the data file given"
  echo " to GNUPlot:"
  echo " ${dataFILE}"
  exit 3
fi

# Cleanup
${cmdRM} ${dataFILE} 

exit 0


zenbo 12-15-2011 01:21 PM

wow!!!!!

thanks alot, i hope i get this thing running!!
thanks mate, i appreciate it!!!!!!!

greetings zenbo

zenbo 12-15-2011 01:31 PM

im quite a newb, i will download that program, and see if i can run your script, maybe ill need some help, and you happen to have time to check this thread, ill keep ya informed.

thanks and greetings zenbo

Dark_Helmet 12-15-2011 01:33 PM

Well, I'm actually working on improving it a bit.

I'm trying to add angle start/stop for the radial lines, give the alternative option of saying "I want X radial lines spaced equally between the start-stop angles," and allow for floating-point angle values.

And I'm looking at changing the drawing mechanism from functions to two-point line segments--which would allow for vertical lines easily enough. Though, I need to look at the gnuplot docs just to make sure what I'm thinking is possible.

I'll post a revised script with what I get working. I may not get everything I want added, but I'll get some.

zenbo 12-15-2011 01:45 PM

ok, first prob, i downloaded gnuplot, but cant find it, its not where the other progs are...

also i pasted the script into the terminal, and pressed enter, after that the terminal desapeared..

Dark_Helmet 12-15-2011 01:56 PM

You'll be using this from the command line. You won't ever actually manually open gnuplot--the script takes care of that.

So, open a terminal: if you're using Ubuntu or something Debian-based, there should be an Applications->Accessories->Terminal menu item (or something similar). That will get you to a command prompt.

Save the script somewhere. And then, in the terminal, issue "cd <path>" where <path> is the directory to where you saved the script.

Once in the same directory (you can confirm by typing "ls -l" at the terminal, and you should see the filename of the script you saved), then issue the command "chmod u+x <filename>" where <filename> is whatever you named your local copy of the script.

To run it, the type "./<filename> <options>" where <options> are whatever switches you want to give the script. It should print some info, and if all is successful, there will be a new PNG file in the same directory. You can use whatever image-viewing utility you like to look at it. Just navigate to it with whatever file manager you use and double-click.

EDIT:
Quote:

Originally Posted by zenbo
also i pasted the script into the terminal, and pressed enter, after that the terminal desapeared..

Paste it into an editor like gedit. Then save it as something like "perspective_grid.bash" or whatever name you think is appropriate.

The reason the terminal disappeared was because pasting it directly caused the terminal to try and execute the script then and there. There are some "exit" statements that would have caused the terminal to close. It's not a big deal. Like I said, just save it as a file, and you'll launch it from the terminal a little later.

EDIT2:
And to make sure that gnuplot is installed, type "which gnuplot" at the terminal. If it doesn't spit out anything but another prompt, then gnuplot has not been installed. You should see something like this:
Code:

user@localhost:~$ which gnuplot
/usr/bin/gnuplot
user@localhost:~$


zenbo 12-15-2011 02:47 PM

Quote:

Originally Posted by Dark_Helmet (Post 4550892)

So, open a terminal: if you're using Ubuntu or something Debian-based, there should be an Applications->Accessories->Terminal menu item (or something similar). That will get you to a command prompt.

im still stuck here, im with linux-mint, when opening the terminal i cant find:Applications->Accessories->Terminal

you dont mean typing it in, right?

did you mean alt+F2 , (run application) ?

Dark_Helmet 12-15-2011 02:51 PM

You don't necessarily need to use that specific method. In an earlier reply, you mentioned that you had pasted the script directly into the terminal and the terminal disappeared.

However you opened that previous terminal is fine--just so long as you can get to a command line.

zenbo 12-15-2011 02:59 PM

Quote:

Originally Posted by Dark_Helmet (Post 4550940)
You don't necessarily need to use that specific method. In an earlier reply, you mentioned that you had pasted the script directly into the terminal and the terminal disappeared.

However you opened that previous terminal is fine--just so long as you can get to a command line.

i dont get it mate, what should i open, where can i find a comand line?

Dark_Helmet 12-15-2011 03:07 PM

Quote:

also i pasted the script into the terminal, and pressed enter, after that the terminal desapeared
However you opened the terminal you were talking about in the above message is fine.

Other options:
1. Navigate through your programs menu (or whatever Mint refers to it as) and look for any subgroup that has an entry for "terminal" or "command line." And start it from there.

2. You can use the alt+f2 shortcut if you like and run "gnome-terminal" or "xterm" or "konsole" or whatever terminal emulator you have installed.

zenbo 12-15-2011 03:18 PM

Quote:

Originally Posted by Dark_Helmet (Post 4550952)
However you opened the terminal you were talking about in the above message is fine.

Other options:
1. Navigate through your programs menu (or whatever Mint refers to it as) and look for any subgroup that has an entry for "terminal" or "command line." And start it from there.

2. You can use the alt+f2 shortcut if you like and run "gnome-terminal" or "xterm" or "konsole" or whatever terminal emulator you have installed.

can i open alt+f2 and put in your script and run it?

zenbo 12-15-2011 03:32 PM

Quote:

Originally Posted by zenbo (Post 4550958)
can i open alt+f2 and put in your script and run it?

tried it, got an error message, we are having a bit of a problem at this point, i dont know what to do?

Dark_Helmet 12-15-2011 03:34 PM

Quote:

can i open alt+f2 and put in your script and run it?
Not yet.

1. Copy the script into a text editor.

2. Save the script to a file. Name it "perspective_grid.bash" -- take note of the directory the file is saved in (e.g. /home/<username>/Documents)

3. Open a terminal (e.g. alt+f2 and type "gnome-terminal" in the prompt)
- you should get a new window that allows you to type commands

4. Verify that gnuplot is installed by typing "which gnuplot" as a command in the new terminal window. You should see output similar to what I showed at the end of one of my earlier replies.

5. Type "cd /home/<username>/Documents" as a command in the new terminal window -- this is the same directory mentioned in step #2 and <username> should be replaced with whatever you saw previously. Also, just in case, directory names in Linux are case-sensitive. In other words "documents" is not the same as "Documents"

6. Type "ls -l" as a command in the terminal window. You should see a text listing of all the files in the directory. Confirm that "perspective_grid.bash" is listed

7. Type "chmod u+x perspective_grid.bash" as a command in the terminal window. You won't see any output--just another prompt.

8. Type "./perspective_grid.bash -point 4 4" as a command in the terminal window. The script will print some information, and if all goes well, a new file should be created called "perspective_grid.png"

9. Use a graphical file manager to view your Documents directory. Double-click the icon for "perspective_grid.png" and it should open in your default image viewer program. You should be able to print/shrink/stretch/whatever through that program's tools.

10. To create another image, go back to the terminal and type "./perspective_grid.bash <options>" where <options> is replaced by the sequence of items you want (e.g. different vanishing points, angles, paper dimensions, etc.)--as described by the comments in the script.

11. Once you think the script can handle what you need, then we can talk about getting it so you can run it straight from the alt+f2 prompt.

zenbo 12-15-2011 03:36 PM

sounds good, but what is a text editor? where do i find it?

Dark_Helmet 12-15-2011 03:45 PM

Look through your programs menu. Look for an "accessories" sub group. There should be an entry titled "gedit Text Editor" or something similar.

Alternatively, you can use alt+f2 again. If you use alt+f2, then type "gedit" as the command. A new window should open that will allow you to type or copy-paste text into a new document and save it.

zenbo 12-15-2011 04:44 PM

Quote:

Originally Posted by Dark_Helmet (Post 4550973)
Look through your programs menu. Look for an "accessories" sub group. There should be an entry titled "gedit Text Editor" or something similar.

Alternatively, you can use alt+f2 again. If you use alt+f2, then type "gedit" as the command. A new window should open that will allow you to type or copy-paste text into a new document and save it.

mmh ok,

reply to which gnupol is :"/usr/bin/gnuplot"

then i dont get:"cd /home/<username>/Dokumente" , whats the username? the documents name? my name?
do i write these ">" as well?

Dark_Helmet 12-15-2011 04:52 PM

Quote:

then i dont get:"cd /home/<username>/Dokumente" , whats the username? the documents name? my name?
The username is probably the same as your Linux user account name. For instance, on my machine, I have an account named "darkhelmet". If I were to follow the directions I gave, I would type: "cd /home/darkhelmet/Documents"

I only use the '<' and '>' to help signify that a specific portion of the instructions should be replaced with whatever matches your setup. You would not type them as part of the command.

EDIT:
But again, I used that as an example of what is normal on systems I have used. The main thing is, it should match the directory that you saved the script to.

If you have trouble finding the file, go to the terminal window and type exactly this (you should be able to copy-paste it into your terminal):
Code:

cd $( dirname $( find ${HOME} -name "perspective_grid.bash" | head -n 1 ) )
The above command will find the file and issue the appropriate cd command to satisfy step #5 above.

zenbo 12-15-2011 04:59 PM

Quote:

Originally Posted by Dark_Helmet (Post 4551026)
The username is probably the same as your Linux user account name. For instance, on my machine, I have an account named "darkhelmet". If I were to follow the directions I gave, I would type: "cd /home/darkhelmet/Documents"

I only use the '<' and '>' to help signify that a specific portion of the instructions should be replaced with whatever matches your setup. You would not type them as part of the command.

didnt work:

(_)-(_)
wallride@wallride-MXC062 ~ $ which gnuplot
/usr/bin/gnuplot

wallride@wallride-MXC062 ~ $ cd /home/rob/Documents
bash: cd: /home/rob/Documents: No such file or directory
wallride@wallride-MXC062 ~ $ cd /home/rob/Dokumente
bash: cd: /home/rob/Dokumente: No such file or directory
wallride@wallride-MXC062 ~ $ cd /home/ROB/Dokumente
bash: cd: /home/ROB/Dokumente: No such file or directory
wallride@wallride-MXC062 ~ $ cd /home/ROB/Documents
bash: cd: /home/ROB/Documents: No such fi

zenbo 12-15-2011 05:09 PM

ok, made it so far:

(__)\ )\/\
||----w |
|| ||
wallride@wallride-MXC062 ~ $ which gnuplot
/usr/bin/gnuplot
wallride@wallride-MXC062 ~ $ cd /home/wallride/Dokumente
wallride@wallride-MXC062 ~/Dokumente $ Is -I
Is: command not found
wallride@wallride-MXC062 ~/Dokumente $ IS-I
IS-I: command not found
wallride@wallride-MXC062 ~/Dokumente $ ls -l
total 8
-rw-r--r-- 1 wallride wallride 6326 2011-12-15 23:35 grid
wallride@wallride-MXC062 ~/Dokumente $ chmod u+x grid
wallride@wallride-MXC062 ~/Dokumente $ ./grid -point 4 4
Perspective point: ( 4, 4)
Line every 5 degrees
GNUPlot exited cleanly. See "perspective_grid.png" for image
wallride@wallride-MXC062 ~/Dokumente $


whats that:"graphical file manager"?

zenbo 12-15-2011 05:39 PM

1 Attachment(s)
yoew!!

Dark_Helmet 12-15-2011 06:05 PM

Made it through I see.

So now you can play around with it some. For instance, try this:
Code:

./grid -point 12 5 -angle 1 -point -2 5 -angle 1
That will give you the criss-crossing lines where both vanishing points are located off the viewable canvas/paper. Play around and see what it can do.

I've already improved the script to allow vertical lines and start/stop angles. I'll post the updated script once I work out one or two more bugs.

zenbo 12-15-2011 06:12 PM

Quote:

Originally Posted by Dark_Helmet (Post 4551082)
Made it through I see.

So now you can play around with it some. For instance, try this:
Code:

./grid -point 12 5 -angle 1 -point -2 5 -angle 1
That will give you the criss-crossing lines where both vanishing points are located off the viewable canvas/paper. Play around and see what it can do.

I've already improved the script to allow vertical lines and start/stop angles. I'll post the updated script once I work out on or two more bugs.

hey this was fun!!!
there are 1,2 and 3 point perspectives, 1 and 2 point perspectives are placed on the horizont line, the third point is placed above ( or under the horizont-line ).

allright mate,im off to sleep, i wish you a good evening, and greetings from central europe. tomorow were suposed to have storms here.

later dude, and thamks a lot!

zenbo

ps. ill be back tomorow

zenbo 12-15-2011 06:20 PM

i guess ill have more questions to you, hopefully i ll see ya tomorow or soon back online!!

Dark_Helmet 12-15-2011 09:58 PM

I'm pasting the revised script. Just open up your text editor again, copy-paste it, etc. like before.

If you overwrite the previous copy, you shouldn't need to do the chmod command again.

Code:

#!/bin/bash

# Command variables. Currently the script needs gnuplot, bc, printf, and rm
# Customize to your location if the paths are different
cmdGNUPLOT=/usr/bin/gnuplot
cmdBC=/usr/bin/bc
cmdPRINTF=/usr/bin/printf
cmdRM=/bin/rm

# Default angle increment
defaultANGLE=5

# File to hold all the gnuplot commands
commandFile=/tmp/perspective_grid.gnuplot
vectorDataFile=/tmp/perspective_grid.vector_data

# File to save the plot/image to
outputFILE=perspective_grid.png

# Default resolution of the image
dotsPerInch=300

# Physical dimensions of the target paper/canvas (in inches)
paperWidth=11
paperHeight=8.5

function PrintUsage() {
cat <<EOF
Usage:
${0##*/} -point <x> <y> [option ...] [-point <x> <y> [option ...]] ...

Creates an image file with one or more points--each point with radial lines
drawn extending outward from the point based on other options.

The options are as follows:
-point <x> <y>    Specifies a point to draw radial lines from. The x and y
                  coordinates are required. The coordinates are in relation
                  to the origin--located at the lower left corner of the
                  image produced. Coordinates can be thought of as
                  representing "inches." Coordinates may be floating point
                  (e.g. 2.5 3.125)

                  Any number of points may be specified. Points do not need to
                  be located within the final viewing area.

-angleinc <deg>    Specifies an increment value for radial lines measured in
                  degrees. For example, "-angleinc 10" would draw radial lines
                  at 10, 20, 30, 40, ... etc. degrees. The increment value
                  may be floating point.

                  This option affects the most recently specified "-point"
                  defined on the command line and ONLY that point.

                  Note: the "-radials" option overrides this option.

                  DEFAULT: ${defaultANGLE}

-anglestart <deg>  Specifies the angle at which to start drawing radial lines
                  measured in degrees. An angle of 0 begins at "3 o'clock" and
                  the angle moves counter-clockwise as the angle value
                  increases. The value may be floating point. A radial line
                  is drawn at the start angle regardless of any other options.

                  This option affects the most recently specified "-point"
                  defined on the command line and ONLY that point.

                  DEFAULT: 0

-anglestop <deg>  Specifies the angle at which to stop drawing radial lines
                  measured in degrees. An angle of 0 begins at "3 o'clock" and
                  the angle moves counter-clockwise as the angle value
                  increases. The value may be floating point. A radial line
                  is drawn at the stop angle regardless of any other options.

                  This option affects the most recently specified "-point"
                  defined on the command line and ONLY that point.

                  DEFAULT: 360

-radials <cnt>    Specifies a fixed number of radial lines to draw between
                  starting and stopping angles. This does not include the lines
                  drawn for the starting and stopping angles themselves. The
                  argument must be an integer.

                  This option affects the most recently specified "-point"
                  defined on the command line and ONLY that point.

                  Note: this option overrides the "-angleinc" option

-dpi <resolution>  Specifies the resolution of the final image. Argument must
                  be an integer.

                  DEFAULT: ${dotsPerInch}

-paperWidth <dim>  Specifies the physical width of the final image in "inches."
                  This is used along with the dots per inch to determine the
                  true horizontal resolution for the image. Argument may be a
                  floating point.

                  DEFAULT: ${paperWidth}

-paperHeight <dim> Specifies the physical height of the final image in "inches."
                  This is used along with the dots per inch to determine the
                  true vertical resolution for the image. Argument may be a
                  floating point.

                  DEFAULT: ${paperHeight}

-output <filename> Specifies the filename to save the final image to.

                  DEFAULT: ${outputFILE}
EOF

exit 5
}
# There really should be a "usage" message and/or argument-checker, but
# I'm not motivated to do that right now.
if [ $# -lt 3 ] ; then
  PrintUsage
fi

# coordID is a marker into the array containing vanishing points
coordID=-1
while [ $# -gt 0 ] ; do

  # "-point" identifies a new vanishing point
  # format: "-point <x coordinate> <y coordinate>"
  # coordinates can be floating point
  if [ "${1}" = "-point" ] ; then
    let coordID=coordID+1
    x_coord[${coordID}]=${2}
    y_coord[${coordID}]=${3}
    shift 3
    continue
  fi

  # "-angleinc" specifies the frequency of radial lines through the vanishing
  #    point in terms of degrees
  # format: "-angleinc <degrees>"
  # The angle effect will be applied to the most recently defined vanishing
  # point the command line.
  # Note: specifying "-radials" will override "-angleinc"
  if [ "${1}" = "-angleinc" ] ; then
    angle_increment[${coordID}]=${2}
    shift 2
    continue
  fi

  # "-anglestart" specifies the beginning angle at which to draw radial lines
  #    through the vanishing point (in degrees)
  # format: "-anglestart <degrees>"
  # The angle effect will be applied to the most recently defined vanishing
  # point the command line.
  if [ "${1}" = "-anglestart" ] ; then
    angle_start[${coordID}]=${2}
    shift 2
    continue
  fi

  # "-anglestop" specifies the final angle at which to draw radial lines
  #    through the vanishing point (in degrees)
  # format: "-anglestop <degrees>"
  # The angle effect will be applied to the most recently defined vanishing
  # point the command line.
  if [ "${1}" = "-anglestop" ] ; then
    angle_stop[${coordID}]=${2}
    shift 2
    continue
  fi

  # "-radials" specifies the the number of evenly spaced radial lines to draw
  #    through the vanishing point (in degrees)
  # format: "-radials <line count>"
  # The angle effect will be applied to the most recently defined vanishing
  # point the command line.
  # Note: specifying "-radials" will override "-angleinc"
  if [ "${1}" = "-radials" ] ; then
    angle_count[${coordID}]=${2}
    shift 2
    continue
  fi

  # "-dpi" specifies the final plot/image resolution (as calculated by the
  #    paper/canvas dimensions)
  # format: "-dpi <dots per inch>
  # The argument should be an integer. Script may work if a float. Untested.
  if [ "${1}" = "-dpi" ] ; then
    dotsPerInch=${2}
    shift 2
    continue
  fi

  # "-paperwidth" and "-paperheight" specify the physical dimensions of the
  #    paper/canvas
  # format: "-paperwidth <size in inches>"
  #        "-paperheight <size in inches>"
  # The argument to either option can be floating point.
  if [ "${1}" = "-paperwidth" ] ; then
    paperWidth=${2}
    shift 2
    continue
  fi

  if [ "${1}" = "-paperheight" ] ; then
    paperHeight=${2}
    shift 2
    continue
  fi


  # "-output" specifies the output image filename
  # format: "-output <filename>"
  if [ "${1}" = "-output" ] ; then
    outputFILE=${1}
    shift 2
    continue
  fi

  echo "ERROR: Unrecognized argument: ${1}"
  PrintUsage
done

# Calculate the needed resolution of the generated image
pixelWidth=$( echo "${dotsPerInch}*${paperWidth}" | ${cmdBC} -l )
pixelHeight=$( echo "${dotsPerInch}*${paperHeight}" | ${cmdBC} -l )

# Strip/truncate any decimal places--need an integer
pixelWidth=$( ${cmdPRINTF} "%.0f" ${pixelWidth} )
pixelHeight=$( ${cmdPRINTF} "%.0f" ${pixelHeight} )

# Truncate working files
> ${commandFile}
> ${vectorDataFile}

# Gnuplot directives
# set output -> tells gnuplot where to save the image
# set terminal png size X,Y -> tells gnuplot to save as PNG and at what size
# unset xtics, unset ytics -> remove the numeric values on the axes
# set clip two -> forces gnuplot to all lines even if endpoints are not in
#                viewable area
# set angle degrees -> use degrees rather than (default) radians
# set key off -> turn off the plot's legend
# set xrange[0:X] -> specify the plot/image's horizontal view
# set yrange[0:Y] -> specify the plot/image's vertical view
# plot <stuff> -> give gnuplot a coordinate file, treat the coordinates
#                as vector data, do no display heads on the vectors, and
#                use simple monochrome/black lines
echo "set output \"${outputFILE}\"" >> ${commandFile}
echo "set terminal png size ${pixelWidth},${pixelHeight}" >> ${commandFile}
echo "unset xtics" >> ${commandFile}
echo "unset ytics" >> ${commandFile}
echo "set clip two" >> ${commandFile}
echo "set angle degrees" >> ${commandFile}
echo "set key off" >> ${commandFile}
echo "set xrange[0:${paperWidth}]" >> ${commandFile}
echo "set yrange[0:${paperHeight}]" >> ${commandFile}
echo "plot '${vectorDataFile}' with vectors nohead lt -1" >> ${commandFile}

# Like with the command line argument parsing, coordID will serve as an
# index into the vanishing point array to work with. Only this time, it
# will work backward.
let coordID=coordID+1

# function_counter is just a number used to suffix the various function
# definitions given to gnuplot so that each function will have a unique
# name.
function_counter=0
while [ ${coordID} -gt 0 ] ; do
  let coordID=coordID-1

  if [ -z "${angle_start[${coordID}]}" ] ; then
    angle_start[${coordID}]=0
  fi
  if [ -z "${angle_stop[${coordID}]}" ] ; then
    angle_stop[${coordID}]=360
  fi
  if [ ! -z "${angle_count[${coordID}]}" ] ; then
    angle_increment[${coordID}]=$( ${cmdPRINTF} "%6.3f" $( echo "(${angle_stop[${coordID}]}-${angle_start[${coordID}]}) / (${angle_count[${coordID}]}+1)" | ${cmdBC} -l ) )
  fi

  # Give the user a warm and fuzzy by restating command line arguments in a
  # more concise form
  echo "Perspective point: ( ${x_coord[${coordID}]}, ${y_coord[${coordID}]})"
  if [ -z "${angle_increment[${coordID}]}" ] ; then
    angle_increment[${coordID}]=${defaultANGLE}
  fi
  echo "  Radial line every ${angle_increment[${coordID}]} degrees"
  echo "    Starting: ${angle_start[${coordID}]}"
  echo "    Stopping: ${angle_stop[${coordID}]}"

  # angle_counter starts at specified starting angle and is repeatedly
  # incremented by the specified angle increment
  angle_counter=${angle_start[${coordID}]}
  angle_loop_finished=0
  while [ ${angle_loop_finished} -eq 0 ] ; do

    # Special case: vertical line
    # Angle == 90: vertical line extending "up" (positive y)
    if [ $( echo "${angle_counter} == 90" | ${cmdBC} -l ) = "1" ] ; then
      y_offset=$( echo "${paperHeight} - ${y_coord[${coordID}]} + 1" | ${cmdBC} -l )
      echo "${x_coord[${coordID}]} ${y_coord[${coordID}]} 0 ${y_offset} " >> ${vectorDataFile}

    # Special case: vertical line
    # Angle == 270: vertical line extending "down" (negative y)
    elif [ $( echo "${angle_counter} == 270" | ${cmdBC} -l ) = "1" ] ; then
      y_offset=$( echo "-1 * (${y_coord[${coordID}]} + 1)" | ${cmdBC} -l )
      echo "${x_coord[${coordID}]} ${y_coord[${coordID}]} 0 ${y_offset} " >> ${vectorDataFile}

    # The following is the "normal" which can be handled with trigonometric
    # functions to determine offsets
    else
   
      if [ $( echo "(${angle_counter} > 90) && (${angle_counter} < 270)" | ${cmdBC} -l ) = "1" ] ; then
        x_offset=$( echo "-1 * (${x_coord[${coordID}]} + 1)" | ${cmdBC} -l )
      else
        x_offset=$( echo "${paperWidth} - ${x_coord[${coordID}]} + 1" | ${cmdBC} -l )
      fi

      y_offset=$( echo "${x_offset} * s(${angle_counter}*8*a(1)/360)/c(${angle_counter}*8*a(1)/360)" | ${cmdBC} -l )
      echo "${x_coord[${coordID}]} ${y_coord[${coordID}]} ${x_offset} ${y_offset}" >> ${vectorDataFile}
    fi

    # Increment the angle by the desired amount
    angle_counter=$( ${cmdPRINTF} "%6.3f" $( echo "(${angle_counter}+${angle_increment[${coordID}]})" | ${cmdBC} -l ) )

    # Check if the increment caused us to exceed the given stop angle.
    # If so, flag that we're done with the radials for this vanishing point
    if [ "$( echo "${angle_counter} > ${angle_stop[${coordID}]}" | ${cmdBC} )" = "1" ] ; then
      angle_loop_finished=1
    fi

    # Check if the angle exceeds 360. If so, subtract 360 to keep the angle
    # in the range [0, 360)
    if [ "$( echo "${angle_counter} > 360" | ${cmdBC} )" = "1" ] ; then
      angle_counter=$( ${cmdPRINTF} "%6.3f" $( echo "${angle_counter} - 360" | ${cmdBC} -l ) )
    fi
  done

  # Once out of the radial line loop, check that we don't need to specifically
  # draw the line at the stop angle.
  if [ "$( echo "${angle_counter} == ${angle_stop[${coordID}]}" | ${cmdBC} )" = "0" ] ; then
    angle_counter=${angle_stop[${coordID}]}

    # Special case: vertical line
    # Angle == 90: vertical line extending "up" (positive y)
    if [ $( echo "${angle_counter} == 90" | ${cmdBC} -l ) = "1" ] ; then
      y_offset=$( echo "${paperHeight} - ${y_coord[${coordID}]} + 1" | ${cmdBC} -l )
      echo "${x_coord[${coordID}]} ${y_coord[${coordID}]} 0 ${y_offset} " >> ${vectorDataFile}

    # Special case: vertical line
    # Angle == 270: vertical line extending "down" (negative y)
    elif [ $( echo "${angle_counter} == 270" | ${cmdBC} -l ) = "1" ] ; then
      y_offset=$( echo "-1 * (${y_coord[${coordID}]} + 1)" | ${cmdBC} -l )
      echo "${x_coord[${coordID}]} ${y_coord[${coordID}]} 0 ${y_offset} " >> ${vectorDataFile}

    # The following is the "normal" which can be handled with trigonometric
    # functions to determine offsets
    else
   
      if [ $( echo "(${angle_counter} > 90) && (${angle_counter} < 270)" | ${cmdBC} -l ) = "1" ] ; then
        x_offset=$( echo "-1 * (${x_coord[${coordID}]} + 1)" | ${cmdBC} -l )
      else
        x_offset=$( echo "${paperWidth} - ${x_coord[${coordID}]} + 1" | ${cmdBC} -l )
      fi

      y_offset=$( echo "${x_offset} * s(${angle_counter}*8*a(1)/360)/c(${angle_counter}*8*a(1)/360)" | ${cmdBC} -l )
      echo "${x_coord[${coordID}]} ${y_coord[${coordID}]} ${x_offset} ${y_offset}" >> ${vectorDataFile}
    fi
  fi
done

# Creation of the gnuplot data file is finished. Launch gnuplot and point
# it to the file.
${cmdGNUPLOT} ${commandFile}

if [ $? -eq 0 ] ; then
  echo "GNUPlot exited cleanly. See \"${outputFILE}\" for image"
else
  echo "GNUPlot failed. Please check your arguments and/or the data file given"
  echo " to GNUPlot:"
  echo " ${commandFile}"
  exit 3
fi

# Cleanup
${cmdRM} ${commandFile} 
${cmdRM} ${vectorDataFile}

exit 0

I think this is as far as I'll take this script. The new features are to specify start and stop angles for the radial lines on a per-perspective-point basis. Start/stop angles and angle increments can use floating point values now. Alternatively to an angle increment, theres a "radials" option that allows you to specify a fixed number of radial lines drawn between the start and stop angles.

To draw a two-point perspective grid of a "floor" you could do this (with the revised script):
Code:

./grid -point 1 4.5 -radials 30 -anglestart 180 -point 10 4.5 -radials 30 -anglestart 180

S. Chapelin 12-16-2011 03:11 AM

Quote:

i am looking for a program to create perspective-grids to draw skyscrapers, houses etc. in perspective.
So back to basics. What is the end purpose of your need.
Because if it is to draw skyscrapers, houses etc. in perspective, as you say, fire up Blender, build the skyscrapers, houses etc., place the camera at the angle you need to get the perspective you want and take a picture (render the scene). You can make your buildings as complicated or as simple as you want. If it's for a presentation, you can go professional polish all the way. You can make your buildings of futuristic metal, plastic or alien goo, in any color you want. Or you can just pop some cubes on a plane. There is no limit to what you can do in Blender. And the best thing is that Blender does all the perspective calculations for you.
But then maybe that is not the end purpose of your need.

zenbo 12-16-2011 05:33 AM

Quote:

Originally Posted by S. Chapelin (Post 4551382)
So back to basics. What is the end purpose of your need.
Because if it is to draw skyscrapers, houses etc. in perspective, as you say, fire up Blender, build the skyscrapers, houses etc., place the camera at the angle you need to get the perspective you want and take a picture (render the scene). You can make your buildings as complicated or as simple as you want. If it's for a presentation, you can go professional polish all the way. You can make your buildings of futuristic metal, plastic or alien goo, in any color you want. Or you can just pop some cubes on a plane. There is no limit to what you can do in Blender. And the best thing is that Blender does all the perspective calculations for you.
But then maybe that is not the end purpose of your need.

putting a tracingpaper over a grid allows me to illustrate the houses first try, there aint no faster way.

zenbo 12-16-2011 06:17 AM

Quote:

Originally Posted by Dark_Helmet (Post 4551228)
To draw a two-point perspective grid of a "floor" you could do this (with the revised script):
Code:

./grid -point 1 4.5 -radials 30 -anglestart 180 -point 10 4.5 -radials 30 -anglestart 180

ok mate, ill try it later, all grids have a horizont line where first and second vanishingpoints are put onto, the third point is above them.if you have time it would be nice if you could explain me the proper usage of the program,

see you later

Dark_Helmet 12-16-2011 11:43 AM

Quote:

Originally Posted by zenbo
ok mate, ill try it later, all grids have a horizont line where first and second vanishingpoints are put onto, the third point is above them.if you have time it would be nice if you could explain me the proper usage of the program

When you open your terminal to run the script, the revised script will print a length usage message if you run the script with no arguments (e.g. "./grid"). You'll need to scroll up in the terminal window to read it all.

Here's the high-level view of how the script works--what it's actually doing. Gnuplot is what draws the image. The script simply creates the data files that tell gnuplot what to draw.

Because gnuplot is more-or-less a tool designed to plot functions, the data files contain information in the form of coordinates and offsets. So, that is why the script requires vanishing points be given with coordinates. The script tries to simplify using coordinates by treating gnuplot's center-point/origin at the bottom left of the produced image. That way, the user will always be entering positive coordinates--no worrying about negatives (except for specific reasons). If you use the defaults, you can visualize this by drawing a graph-paper-grid on a sheet of paper (in landscape--i.e. longest dimension horizontal) with the grid lines 1 inch apart. That's the coordinate system.

When you specify a point to the script, you're giving the coordinate for a vanishing point. By default, a vanishing point is illustrated by drawing radial lines extending from the point you specify. If you take all the defaults, a radial will be drawn at 0 degrees (a horizontal line extending to the right) and additional radial lines will be drawn every 5 degrees counter-clockwise for a full rotation (i.e. all the way back to 0 degrees).

In a nutshell, that's it. That's all the script does. It calculates the coordinates needed for gnuplot to draw the radials. It gives you options to control how many radials are drawn, but it's all just a variation on the process above.

For two vanishing points to share a horizontal line: specify two points to the script with both points having the same y-coordinate (e.g. (1, 5) and (10, 5) --or-- (2, 7) and (7, 7))
Example command:
Code:

./grid -point 1 5 -point 10 5
That will draw two vanishing points with each having a radial drawn at 5 degree increments for the full 360 degrees. Both are on a horizontal line because their y-coordinates are the same value (5).

Example command:
Code:

./grid -point 1 5 -anglestart 180 -point 10 5
That will draw two vanishing points like the previous command. The difference is, the first vanishing point will NOT have any radials drawn above its horizon. This is caused by the "-anglestart" option. In this case, the starting angle for drawing radials for the first vanishing point is 180 degrees (which is a horizontal line extending to the left of the paper) and each additional radial will be drawn 5 degrees apart.

You can add as many points as you like:
Code:

./grid -point 1 3 -anglestart 180 -point 10 3 -anglestart 180 -point 5.5 7
Whether that produces the type of grid you want is up to you. You can play with the options. It's probably quicker for you to run an experiment with the script than waiting for me to see a question and respond.

Some "tricks":
To draw a horizontal line, include this as part of the script's options:
Code:

./grid -point 1 4 -radials 1
You interpret that as "draw one radial between 0 degrees and 360 degrees. The result is a radial drawn at 180. So, it draws a horizontal line 4 "inches" up from the bottom of the image.

To have a vanishing point have more radials at certain degrees. Try this:
Code:

./grid -point 4 4 -anglestop 45 -radials 50 -point 4 4 -anglestart 45 -anglestop 135 -radials 50 -point 4 4 -anglestart 135 -anglestop 180 -radials 50

Dark_Helmet 12-16-2011 01:17 PM

And, rather than add an edit to the previous post, here's a sample command that creates something sort of like the bottom half of the image from the original web page you linked to.

Code:

./grid -point 5.5 3.5 -radials 40 -anglestart 180 -point 0 3.25 -radials 1 -point 0 3 -radials 1 -point 0 2.5 -radials 1 -point 0 1.5 -radials 1
The first point-radials-anglestart sequence gives the radial lines. The following point-radials sequences define the horizontal lines: one point-radials sequence per horizontal line. The spacing of the horizontal lines is controlled by their respective y-coodinates. So, that command illustrates that you can get as complex or as simple as you like.

Something similar to the top half of the original image could be created by swapping things around. For instance:
Code:

./grid -point 5.5 5.5 -radials 40 -anglestop 180 -point 0 5.75 -radials 1 -point 0 6 -radials 1 -point 0 6.5 -radials 1 -point 0 7.5 -radials 1
You could also combine all those options in one really long command:
Code:

./grid -point 5.5 3.5 -radials 40 -anglestart 180 -point 0 3.25 -radials 1 -point 0 3 -radials 1 -point 0 2.5 -radials 1 -point 0 1.5 -radials 1 -point 5.5 5.5 -radials 40 -anglestop 180 -point 0 5.75 -radials 1 -point 0 6 -radials 1 -point 0 6.5 -radials 1 -point 0 7.5 -radials 1
Lastly, I should point out that gnuplot does support "true" 3D plot drawing. Though, I approached it from a straight 2D framework. Using gnuplot's 3D plotting abilities might give better results, but would require some significant re-working of the script to support. Or creating the necessary files for gnuplot by hand.

zenbo 12-16-2011 03:04 PM

dark helmet

i installed the script, it works fine, im trying all the options you includet, ill get back to you if i have more questions.
most of all i wanna say thank you for your effort, this was really cool of you, im having a buddy helping me, who is better on computers than me.

again thanks alot, ill let you know what i think of it. catch you later.

zenbo

Dark_Helmet 12-16-2011 03:26 PM

No problem. I hope it works for you.

Every so often I get a "programming itch." It just so happened that I had one right around the time you posted your original message and it dawned on me that the process could be automated (somewhat) with gnuplot.

So, as crazy as it might sound, I was entertained by the challenge of it. In addition to having entertained me, I hope it's ends up being useful for you :)

zenbo 12-16-2011 04:18 PM

Quote:

Originally Posted by Dark_Helmet (Post 4551948)
No problem. I hope it works for you.

Every so often I get a "programming itch." It just so happened that I had one right around the time you posted your original message and it dawned on me that the process could be automated (somewhat) with gnuplot.

So, as crazy as it might sound, I was entertained by the challenge of it. In addition to having entertained me, I hope it's ends up being useful for you :)

how come you can program so well, is it a job? are programing-languages for linux the same as say mac or windows?

Dark_Helmet 12-19-2011 11:04 PM

In all honesty, that script is not much of a programming feat, but I appreciate the compliment :)

As to your other questions, I've programmed here and there for a long time. Some in grade school, some in my university degree program, some professionally, and some just as a personal hobby. Though, I would not classify myself as a "professional" programmer. The work I did professionally was not the "software development" that most people think of.

And yes, programming languages are computer-independent. A computer language just specifies the "vocabulary and grammar" to use when programming. Any computer can then interpret that code as long as the computer has a compiler--a translator of sorts (keeping with the analogy).

If you ever decide to get into programming, you'll notice that there may be some cosmetic differences, but almost all programming languages support some core "features." Once you're proficient with one language, you probably won't need much time to become "competent" in another language.


All times are GMT -5. The time now is 10:26 AM.