VocExile Main Menu / ProgTopics /Design
by Ed Perley
SURFACE VIEW is a program that allows one to see what the view would be from any point on a topographic map. When completed, it will allows one to have a 45 degree wide view, looking in all four directions.
This page reports the planning, design and coding of the program. This project tests the feasibility of an unusual program design, which is described below.
The program provides a surface view looking north, south, east, or west from anywhere on the 40 X 40 grid. Contrast is obtained by varying color from very light in the background to very dark in the foreground. The program allows one to be able to see the surface from one of four different directions, with the view horizontal or tilted up or down. Altitude data for the 40 X 40 altitude map can be easily entered into a table and saved to disk. Altitudes can be obtained from topographic maps from the U.S. Geological Survey, available at many major libraries. Or, you can make up your own landscape
The program, called SURFACE VIEW, provides a three dimensional view of any landscape. The user will enter altitude and color data on a 40 x 40 grid. Not all grid spaces will need to be filled in. The computer will estimate the values in any empty elements of the grid. The completed grid can be saved to and retrieived from the disk drive. The 40 X 40 grid data will be expanded to a 160 X 160 array, which the program uses to draw each surface view. The gaps in the latter grid will be filled with calculated values that will approximate the curvature of the surface, rather than just "connecting the dots."
The user will be able to get a 3D view from any point on the grid, looking north, south, east or west. As presently designed, edges of the map "wrap around" to the opposite sides of the map. There is also be a provision to tilt the view up (for viewing mountains up close) or down ( for looking down into canyons). So, there is a total of over nineteen thousand different views from the surface that can be generated by this program. Also, the user can specify a view from any height above each point. So the number of different views possible with this program numbers in the millions.
Visual BASIC Ver. 3 is used because of the abundance of powerful graphics and math functions in the language, and the ready made input and output structures that it supports. Minimum requirements for the program will be a 386 PC with windows 3.1. A 16 bit or greater graphics configuration is recommended.
The program uses a unique system to transfer information between program modules. Global variable arrays are be used for temporary storage to transfer values to and from program modules. This is something like how information in assembly language is handled.
The program has a "plug and play" design, like that on a circuit board with dip switches and connector ports. It contains a control panel that will allow the user to select and/or turn program modules off and on at will. These changes can be made while the program is running. This should make design and debugging of a program faster and easier. Control panel data will be stored in a global character array that will be saved to a disk. The Programming Topics Menu that this page branches from contains a link to an essay that discusses this design.
A Visual Basic program contains a collection of window structures called forms. Program code can be attached to the different structures located within these forms, such as control buttons, input boxex, etc. The program often contains a code module, which contains subprograms that can be called by code elsewhere in the program.
The Program contains five separate forms or modules. They are listed below.
The user is given the choice of data entry, viewing the map and surface views, making changes with the control panel, or exiting the program. A completed map can be loaded using the File menu bar. Upon loading, the 40 X 40 map is expanded to a 160 X 160 display grid, ready for the program to read to draw a survace view.
Altitude data for a 20 mile square area is entered into a 40 X 40 table. If the user wishes to enter a 10 square mile grid, he can simply multiply each altitude by two to get the proper scale. There is provision for the program to fill in gaps, useful for saving time if part of the map is flat or has a uniform slope. The File Menu bar can be used to save or load a map file.
The 40 X 40 altitude data is displayed on this form. High altitudes are colored lighter. If you click the mouse somewhere on the map, the map coordinates (in miles from the left and top margins) are displayed. Alternately, the coordinates can be entered by the user. Once the coordinates have been selected, the 3D surface View form can be activated.
The appearance of the map surface from the selected map coordinates is drawn. 148 surface profile lines are extracted from the display grid and drawn across the form. (The last twelve lines are not drawn to avoid a 'wraparound' effect in the direction of view.) Each line is properly scaled amd positioned for it's distance from the viewer. The most distant surface profile line is drawn first, and the nearest one is drawn last. The illustration demonstrates how these lines can build up a surface.
The program in it's present form does not show this pattern. It shows no distinct lines, but uses color to show the contour of the land. The space below each surface profile line is filled with color as it is drawn. The most distant contours are colored very light. They get steadily darker as the nearer contours are drawn. An example of one of these displays is shown at the top of this page.
This form can be used to turn program modules on or off, or switch between modules, while the program is running. It may eventually be used to modify how the surface view can be displayed. It and the program design are described below.
The code module is completely invisible to the user. It contains code called by the other forms. The Control Panel subroutines are located here, as well as definitions of global variables, and setup routines.
To Programming Menu
To Main Menu
The code fragments below demonstrate the use of the control panel to control program execution, and how global variables are used to pass data to functions. Global variables, those accessable everywhere in the program, are defined in the main() subprogram in the code module. Some of these are shown below.
The Standard Global Variables are are used to transfer data to and from different portions of the program.
Global GVinteger(10) As Integer
Global GVstring(10) As String
Global GVfloat(10) As Single
The table in which the Control Panel data is stored, and a table of descriptions of Control Panel items are also defined.
Global control(100, 3) As Integer
Global Control_String(100) As String
The table in which the map altitude data is stored, and the display data table is also a global variable. The former array is floating point to leave open the possibility that in a future version of the program, colors of terrain may be specified by decimal fractions.
Global Map(40, 40) As Single
Global Dmap(160, 160) as Integer
The portion of code shown below is called when the Fill Gaps Button in the Data Entry form is clicked with the mouse. In the table Map(x,y), any value of zero is changed to a value intermediate between adjacent non zero values in the table. First, the rows are filled by one subprogram. Then the columns are filled in with a second one. After the calculations are completed, a third subprogram copies the new table contents to the screen display.
Instead of being called directly, function calls are made through the Control Panel, which as was described above, can be changed while the program is running. Each subprogram or group of alternative subprograms are identified by a number, which is passed to the Controls subprogram via the global variable GVinteger(1).
In the below code, there are two alternative Fill_Rows subprograms, and two alternative Fill_Columns subprograms. One can switch between them or turn them off entirely by making changes in the Control Panel form.
The value given to GVinteger(1) determines which subprogram that the Control subprogram will call. The subprogram below Calls the Controls subprogram three times. The Controls subprogram in turn, calls subprograms to fill gaps in data rows, fill gaps in data columns, and lastly, copy the table to the screen display.
Sub cmd_Fill_Gaps_Click ()
. GVinteger(1) = 1
. GVinteger(1) = 2
. GVinteger(1) = 3
This Subprogram selects and runs a subprogram specified by GVinteger(1). It and the subprograms it controls are in the Code Module of the program.
In the below code, x is the ID number of the subprogram to be called. The variable y, read from the Control Table, determines which of two subprograms shall be run. A zero value means that neither one will be called. This and all other variables in the Control Table can be changed while the program is running.
After the desired subprogram is selected, GVinteger(1) and GVinteger(2) are assigned numbers that serve as switches to control how the subprograms are run. These values can also be changed while the program is running. At the present time, these switches are not used by subprograms called in this code. Other subprograms to be added later may make use of them.
After GVinteger(1) and GVinteger(2) are no longer needed by the the subprogram, they are given zero values to indicate they are available to be used elsewhere in the program.
. x = GVinteger(1)
. y = control(x, 1)
. GVinteger(1) = control(x, 2)
. GVinteger(2) = control(x, 3)
....Select Case x
....Case 1 :Rem FILL ROWS IN GRID.
........Select Case y
....... Case 2
. End Select
. Case 2 :Rem FILL COLUMNS IN GRID.
........Select Case y
. End Select
....Case 3 :Rem MOVE MAP DATA TO SCREEN.
............Select Case y
....... End Select
....GVinteger(1) = 0: GVinteger(2) = 0 BR> End sub
A number of the variables used in drawing the surface view are generated when the program is first run. This decreases the time needed to draw the surface view, and it simplifies the code needed to translate the numerical data to a visual display. The global variables needed are displayed below.
Global Screen_Width As Single: Rem WIDTH OF DISPLAY IN TWIPS
Global Screen_Height As Single: REM HEIGHT OF DISPLAY IN TWIPS
Global Map_Width As Single: Rem WIDTH OF MAP IN FEET
Global Height_Ratio(160) As Single: Rem TWIPS PER FOOT VERTICAL
Global Width_Ratio(160) As Single: Rem TWIPS PER FEET HORIZONTAL
Global Num_of_Segments(160) As Single: Rem NO. SEGMENTS IN EA. SURFACE CONTOUR Rem THE NEAREST HAS ONE. THE FARTHEST HAS 160.
Global Len_of_Segments(160) As Single: Rem NO TWIPS PER SEGMENT
Global Direction As String: Rem THE DIRECTION THE USER IS LOOKING
Global PColor(160) As Integer: Rem DEFINES THE COLOR OF EACH SURFACE PROFILE
Global Max As Integer: Rem MAXIMUM ALTITUDE ON THE MAP
Global Min As Integer: REM MINIMUM ALTITUDE ON THE MAP
The code for drawing the surface view is shown below. At the present time it is attached to the Form.Activate form, but it will eventually be attached to the control panel as are the other major modules in this program. There will be four of these program modules, one for each of the four directions.
For X = 148 To 4 Step -1
....DY% = DYCoord% - X: Rem Y POSITION ON THE DISPLAY GRID
....If DY% < 1 Then DY% = 160 + DY%: REM WRAPAROUND IF THE VEIW GOES BEYOND THE EDGE
....If DY% > 160 Then DY% = DY% - 160
....DX% = DXCoord% - Num_of_Segments(X) / 2: Rem LEFTMOST X POS TO BE DISPLAYED
....If DX% < 1 Then DX% = DX% + 160
....Rem Screen Display Variables
....XC1% = 0: Rem FIRST PLOT IS AT FAR LEFT
....XC2% = Len_of_Segments(X): Rem POSITION OF SECOND PLOT
Rem BUILDING EACH SURFACE PROFILE LINE FROM LEFT TO RIGHT
...For Y = 0 To Num_of_Segments(X) - 1
......X1% = DX% + Y: If X1% > 160 Then X1% = X1% - 160
......X2% = DX% + Y + 1: If X2% > 160 Then X2% = X2% - 160
......YC1% = Vert_Offset(X) - (DMAP(X1%, DY%) - Altitude%) * Height_Ratio(X)
......YC2% = Vert_Offset(X) - (DMAP(X2%, DY%) - Altitude%) * Height_Ratio(X)
......XC1% = Y * Len_of_Segments(X)
......XC2% = (Y + 1) * Len_of_Segments(X)
......Z = PColor(X)
The followingt code actually does the drawing and coloring. It will probably be eventually called by the four surface veiw subprograms through the control panel. There may eventually be a number of them, each giving a different display.
......Rem DRAW CONTOUR LINE
......picSurface_View.Line (XC1%, YC1%)-(XC2%, YC2%), RGB(Z - X / 2, Z + 20, Z)
......Rem FILL IN SPACE BELOW THE LOWER OF THE TWO POINTS TO THE BOTTOM OF SCREEN
......UL% = YC2%
......If YC1% >= YC2% Then UL% = YC1%
......picSurface_View.Line (XC1%, UL%)-(XC2%, 10000), RGB(Z - X / 2, Z + 20, Z), BF
......Rem FILL IN TRIANGULAR SPACE BETWEEN THE HIGHER AND THE LOWER POINTS
......For L% = 1 To Abs(YC1% - YC2%)
..........picSurface_View.Line (XC1%, YC1% + L%)-(XC2%, YC2% + L%), RGB(Z - X / 2, Z + 20, Z) ......Next L%
......Rem DRAWING COMPLETED. BUILD NEXT LINE
To Programming Menu
To Main Menu