Problem Graphing Data
Author |
Message |
GlobeTrotter
|
Posted: Fri Nov 11, 2005 9:21 pm Post subject: Problem Graphing Data |
|
|
edit: added comments to the code to make it easier to understand
Turing: |
const RUN_UPTO := 500 %The largest x-coordinate of the graph we will create
var count := 0
%Array that will hold the number of primes up to the index number of the array.
%For example, arrPrimesUpto (8) will be 4 because 2, 3, 5, and 7 are prime.
var arrPrimesUpto : array 1 .. RUN_UPTO of int
%Function that will take in the array to plotted, and coordinates describing the rectangle it will fit in, and whether it
%should connect the points with lines, or just draw dots.
proc plotArray (arr : array 1 .. * of int, Temp_x1, Temp_y1, Temp_x2, Temp_y2 : int, drawLine : boolean)
const AXIS_DISTANCE := 20 %How far from the bottom-left corner of the graph rectangle the axis will be.
var x1, x2, y1, y2 : int %The coordinates describing the rectangle of the graph.
var maxNum : int := minint %Used to find the largest y-value in the array so that the graph can be fitted accordingly
var xDiv, yDiv : real %What ratio the x and y must be multiplied by to fit the pixels of the screen.
var mx, my, mb : int
var dragx1, dragy1, dragx2, dragy2 : int %The coordinates of the rectangle the user drags
var newArray : flexible array 1 .. 0 of int %Used to recurse the function/zoom in
var count : int := 0 %Used when assigning newArray's values
%To make things easier, we make sure the user inputted x1,y1 as the bottom-left and x2,y2 as top-right
x1 := min (Temp_x1, Temp_x2 )
x2 := max (Temp_x1, Temp_x2 )
y1 := min (Temp_y1, Temp_y2 )
y2 := max (Temp_y1, Temp_y2 )
drawbox (x1, y1, x2, y2, 7) %Draw a box which the graph should fit in
%Draw the axes
drawline (x1 + AXIS_DISTANCE, y1 + AXIS_DISTANCE, x1 + AXIS_DISTANCE, y2, 7)
drawline (x1 + AXIS_DISTANCE, y1 + AXIS_DISTANCE, x2, y1 + AXIS_DISTANCE, 7)
%Find the maximum y-value
for i : 1 .. upper (arr )
maxNum := max (arr (i ), maxNum )
end for
%abs (x2 - x1) - AXIS_DISTANCE) is the width in pixels of the graphing area. We divide that by the maximum x-value
%To find the ratio between array and x-coordinate
xDiv := (abs (x2 - x1 ) - AXIS_DISTANCE ) / (upper (arr ))
%Same thing for y
yDiv := (abs (y2 - y1 ) - AXIS_DISTANCE ) / (maxNum )
%The actual drawing of the graph
for xCount : 1 .. upper (arr ) %Loop through each element
if drawLine then %If true was entered as a parameter for drawing a line
if xCount ~ = 1 then %Since we check arr(xCount - 1) to draw the line
%Draw a line between the previous index and this index, the coordinate is found by multiplying by the ratio
%and adding the axis distance
drawline (round ((xCount - 1) * xDiv ) + AXIS_DISTANCE, AXIS_DISTANCE + round (yDiv * arr (xCount - 1)), round (xCount * xDiv ) + AXIS_DISTANCE, AXIS_DISTANCE + round (yDiv *
arr (xCount )), 7)
end if
else
%Same as before, except we're not checking arr(xCount - 1), and just drawing a dot
drawdot (round (xCount * xDiv ) + AXIS_DISTANCE, AXIS_DISTANCE + round (yDiv * arr (xCount )), 7)
end if
end for
%The interactive portion of the graph
loop
delay (10)
Mouse.Where (mx, my, mb )
%Check if the mouse is within the graph, and inside the axis
if ~ (mx < x1 + AXIS_DISTANCE + 1 or mx > x2 or my < y1 + AXIS_DISTANCE or my > y2 ) then
%Put the (x,y) at their mouse's x-position
locate (1, 1)
put "(", ceil ((mx - x1 - AXIS_DISTANCE ) / xDiv ), ",", arr (ceil ((mx - x1 - AXIS_DISTANCE ) / xDiv )), ")"
if mb = 1 then %If they click, allow them to drag
%set the coordinates for one corner of the rectangle
dragx1 := mx
dragy1 := my
%Allow them to move their mouse, and pick the other corner
loop
delay (10)
Mouse.Where (mx, my, mb )
exit when mb = 0
end loop
%Set the other coordinate of the rectangle
dragx2 := mx
dragy2 := my
%If the rectangle they described is within the graph area and it isn't just a point
if (dragx1 ~ = dragx2 ) and ~ (dragx2 < x1 + AXIS_DISTANCE + 1 or dragx2 > x2 or dragy2 < y1 + AXIS_DISTANCE or dragy2 > y2 ) then
drawbox (dragx1, dragy1, dragx2, dragy2, 7) %Draw a box around where they chose
%THe new array should go up to the difference between the x-values of the rectangle, fitted to the graph
new newArray, round (abs (dragx1 - dragx2 ) / xDiv )
%I suspect this is what is causing the problems in my program.
%Go from the left to the right, fitted to the screen
for i : round ((min (dragx1, dragx2 ) - x1 - AXIS_DISTANCE ) / xDiv ) .. round ((max (dragx1, dragx2 ) - x1 - AXIS_DISTANCE ) / xDiv ) - 1
count + = 1
%Assign the new array to the rectangle's array values
newArray (count ) := arr (i )
end for
count := 0
cls
%Plot a new array with the new Array, and the same other parameters.
plotArray (newArray, x1, x2, y1, y2, drawLine )
end if
end if
else
%Erase the (x,y)
locate (1, 1)
put ""
end if
end loop
end plotArray
%Simple function that outputs true if the inputted number is prime, and false if it isn't
fcn isPrime (n : int) : boolean
if n mod 2 = 0 and n ~ = 2 then
result false
end if
for i : 3 .. round (sqrt (n )) by 2
if n mod i = 0 then
result false
end if
end for
result true
end isPrime
arrPrimesUpto (1) := 0
%This is necessary since 1 isn't really a prime number, but our isPrime function thinks it is.
%It also allows us to check the index number - 1 in our for loop.
%Fill the array.
%Rather than checking every number, up to each index, we check if it should have one more than the one before it.
for i : 2 .. RUN_UPTO
if isPrime (i ) then
count + = 1
end if
arrPrimesUpto (i ) := count
end for
plotArray (arrPrimesUpto, 0, 0, maxx div 2, maxy div 2, true)
|
All the stuff about primes, and GCD has nothing to do with my problem, that is just to generate sample data to graph. The main procedure takes the array as a parameter and plots the array value vs. the index number. I tried making the graph somewhat interactive. When you drag a box over the graph, it should zoom in into that section. For some reason some weird stuff is drawn, or sometimes, there's an array out of bounds error.
I believe the problem code lies in here:
code: |
if (dragx1 ~= dragx2 and dragy1 ~= dragy2) and ~ (dragx2 < x1 + AXIS_DISTANCE + 1 or dragx2 > x2 or dragy2 < y1 + AXIS_DISTANCE or dragy2 > y2) then
drawbox (dragx1, dragy1, dragx2, dragy2, 7)
new newArray, round (abs (dragx1 - dragx2) / xDiv)
for i : round ((min (dragx1, dragx2) - x1 - AXIS_DISTANCE) / xDiv) .. round ((max (dragx1, dragx2) - x1 - AXIS_DISTANCE) / xDiv) - 1
count += 1
newArray (count) := arr (i)
end for
count := 0
cls
plotArray (newArray, x1, x2, y1, y2, drawLine)
end if
|
|
|
|
|
|
|
Sponsor Sponsor
|
|
|
MysticVegeta
|
Posted: Sat Nov 12, 2005 1:01 pm Post subject: (No subject) |
|
|
why not make it so that when you click on the graph, it zooms in rather than drag, and clicking making it dragable which is easier for the user to interact and easier for you to code because I cant understand a thing you are doing with no comments. |
|
|
|
|
|
GlobeTrotter
|
Posted: Sat Nov 12, 2005 2:22 pm Post subject: (No subject) |
|
|
The thing with drag-zoom is that it will allow you to specify the data included in the zoomed graph. Click zoom wouldn't really work since you wouldn't know how far to zoom.
I will add comments. |
|
|
|
|
|
GlobeTrotter
|
Posted: Tue Nov 15, 2005 8:52 pm Post subject: (No subject) |
|
|
Any help? I added comments. |
|
|
|
|
|
beard0
|
|
|
|
|
|
|