Programming C, C++, Java, PHP, Ruby, Turing, VB
Computer Science Canada 
Programming C, C++, Java, PHP, Ruby, Turing, VB  

Username:   Password: 
 RegisterRegister   
 Using records with Draw.FillPolygon/Polygon
Index -> Programming, Turing -> Turing Help
View previous topic Printable versionDownload TopicSubscribe to this topicPrivate MessagesRefresh page View next topic
Author Message
Raknarg




PostPosted: Thu Apr 12, 2012 10:01 am   Post subject: Using records with Draw.FillPolygon/Polygon

So I have this:
Turing:

setscreen ("offscreenonly")
type coordinate :
    record
        x, y : real
        dx, dy : int
    end record

type square :
    record
        point : array 1 .. 4 of coordinate
    end record

var poly : square

poly.point (1).x := 50
poly.point (2).x := 50
poly.point (3).x := 100
poly.point (4).x := 100
poly.point (1).y := 50
poly.point (2).y := 100
poly.point (3).y := 100
poly.point (4).y := 50

for i : 1 .. 4
    poly.point (i).dx := round (poly.point (i).x)
    poly.point (i).dy := round (poly.point (i).y)
end for

Draw.FillPolygon (poly.point.dx, poly.point.dy, 4, brightblue)
Draw.Polygon (poly.point.dx, poly.point.dy, 4, black)
View.Update


What I want to know is if there's a way to use drawfillpolygon this way, but say that I only want to use the dx or the dy? Because I know it takes in integers, but not records, so I can't think of a way to get around that.

Unless someone can give me a better way to set this up.
Sponsor
Sponsor
Sponsor
sponsor
DemonWasp




PostPosted: Thu Apr 12, 2012 10:15 am   Post subject: RE:Using records with Draw.FillPolygon/Polygon

Nope. You're stuck writing glue code to move your data into arrays to pass to FillPolygon.

You could reorganize your data structure to use associated arrays (array x, array y, array dx, array dy, ...) internally, with the exact same public interface as normal, but I don't really recommend it.

Most languages do not provide any easier way around this, so this isn't a Turing-specific failing. You will have to write "data pumps" like this in most cases.

It sure would be nice if we could just access poly.point.x, though. It would also be nice to be able to retrieve array2d ( *, 3 ) to get the third column from a 2D array.
Raknarg




PostPosted: Thu Apr 12, 2012 10:21 am   Post subject: RE:Using records with Draw.FillPolygon/Polygon

ah well. Thanks anyways. I decided to change it though. I just use one record, and have the x and ys as arrays instead.
Dreadnought




PostPosted: Thu Apr 12, 2012 1:49 pm   Post subject: Re: Using records with Draw.FillPolygon/Polygon

DemonWasp wrote:
It would also be nice to be able to retrieve array2d ( *, 3 ) to get the third column from a 2D array.

Obtaining columns of a 2D array (or any index other than the first of a multi-dimensional array) is basically impossible without some kind of "pump code" as you call it because of the way the arrays are stored. However you can obtain rows of an array quite easily.
Turing:
var test : array 1 .. 3, 1 .. 3 of int := init (1, 2, 3, 4, 5, 6, 7, 8, 9)
var test1, test2, test3 : array 1 .. 3 of int

type arr : array 1..3 of int

test1 := cheat(arr, test(1,1))
test2 := cheat(arr, test(2,1))
test3 := cheat(arr, test(3,1))

put "test1 contents:"
for i : 1 .. 3
        put "test1(",i,") = ",test1 (i)
end for
put "test2 contents:"
for i : 1 .. 3
        put "test2(",i,") = ",test2 (i)
end for
put "test3 contents:"
for i : 1 .. 3
        put "test3(",i,") = ",test3 (i)
end for


We can take this one step further.
Turing:
type rec :
    record
        x, y, z : int
    end record

var test : rec
test.x := 1
test.y := 4
test.z := 9

type arr : array 1 .. 3 of int
var test2 : arr
test2 := cheat (arr, test.x)

for i : 1 .. 3
    put test2 (i)
end for


These don't really help with your original problem, but the idea is that as long as data is stored in consecutive memory addresses (hence why DemonWasp's desire to obtain columns doesn't work) then you can create an array. You can play around with this if you want, but I doubt it will be useful to you as it requires data to already be in the form of an array.

Note that the child array (the one I create by cheating) is not sharing data with its parent, the cheating creates a new array in memory.
copthesaint




PostPosted: Thu Apr 12, 2012 1:55 pm   Post subject: Re: Using records with Draw.FillPolygon/Polygon

You can only do this one way since drawpoly only accepts an array 1 .. * of int for the x and y points. the reason why you cant make an array of 1-4 of the type and use that because the individual values for that type arnt arrays although they are part of one.


Turing:
setscreen ("offscreenonly")

type square :
    record
        x, y : array 1 .. 4 of real
        dx, dy : array 1 .. 4 of int
    end record

var poly : square

poly.x (1) := 50
poly.x (2) := 50
poly.x (3) := 100
poly.x (4) := 100
poly.y (1) := 50
poly.y (2) := 100
poly.y (3) := 100
poly.y (4) := 50

for i : 1 .. 4
    poly.dx (i) := round (poly.x(i))
    poly.dy (i) := round (poly.y(i))
end for

Draw.FillPolygon (poly.dx, poly.dy, 4, brightblue)
Draw.Polygon (poly.dx, poly.dy, 4, black)
View.Update


This does what you wanted. argueablly faster since only one type is needed.
DemonWasp




PostPosted: Thu Apr 12, 2012 2:50 pm   Post subject: RE:Using records with Draw.FillPolygon/Polygon

In languages like C, it is actually possible to access the fields like a column when using structs. I'm not good enough at C that this will compile, but the basic idea is:

code:

struct {
    float x, y;
    int dx, dy;
} point;

struct {
    struct point[4] pts;
} square;

struct square p;

// initialize p...

// Now if you start at the address of the first x field and advance by (sizeof(point)) at each iteration, you will get each x field in order...
for (
    int i = 0, int *p = &(p.pts[0].x) ;
    i < 4 ;
    ++i, p += sizeof(struct point)
) {
    printf ( "%p -> %d\n", (void*)p, *p );
}


I know at least some APIs used to be written that way: they take a start address (&(p.pts[0].x)), a number of iterations (4) and a "step size" (sizeof(struct point)). It's relatively rare.
Dreadnought




PostPosted: Thu Apr 12, 2012 4:49 pm   Post subject: Re: Using records with Draw.FillPolygon/Polygon

DemonWasp wrote:
In languages like C, it is actually possible to access the fields like a column when using structs.

Oh, you mean like this?
Turing:
type point :
    record
        x, y : real
        dx, dy : int
    end record

type sqr : array 1 .. 4 of point

% Initialize
var mySqr : sqr
mySqr (1).x := 1
mySqr (2).x := 2
mySqr (3).x := 3
mySqr (4).x := 4
mySqr (1).y := 5
mySqr (2).y := 6
mySqr (3).y := 7
mySqr (4).y := 8 % This doesn't make a square, but it helps to see which value is printed

for i : 1 .. 4
    mySqr (i).dx := round (mySqr (i).x)
    mySqr (i).dy := round (mySqr (i).y)
end for
% Done initializing

var dxAdd : addressint := addr (mySqr (1).dx)
var dyAdd : addressint := dxAdd + sizeof (int)

% Now let's get all the dx's
var i : int := 1
put "Printing all dx"
loop
    exit when i > 4
    put dxAdd, " -> ", int@(dxAdd), "     <- mySqr(",i,").dx"
    dxAdd += sizeof (point)
    i += 1
end loop

% And now the dy's
put ""
put "Printing all dy"
i := 1
loop
    exit when i > 4
    put dyAdd, " -> ", int@(dyAdd), "     <- mySqr(",i,").dy"
    dyAdd += sizeof (point)
    i += 1
end loop


So, yes, you can get the elements in this way (and in Turing too Very Happy). But, these for loops that jump through memory addresses, they're basically "data pumps" or "glue code" (whichever of your names you prefer).

Admittedly, since Turing creates a new array when I split the rows, I lose the efficiency of simply making the array a pointer into the old one (which it is easy to do with C). But my point is that, since the data is not in a contiguous block of memory, it's not simple to create an new array. You have to use pointer arithmetic and rearrange the memory. If you want the rows of an array you don't need to do the rearranging (therefore no "data pump" or whatever).

And to raknarg, I guess I should have posted code like this earlier, but I didn't think of it at the time. (Thanks DemonWasp for making me think of it!)
DemonWasp




PostPosted: Thu Apr 12, 2012 8:55 pm   Post subject: RE:Using records with Draw.FillPolygon/Polygon

Nicely done; I wasn't aware that Turing was capable of quite that much blatant pointer abuse.

All said and done, it would be really nice if some of the syntactic sugar in higher-level languages would let you access "aggregates" like "the x coordinate of all points in square" easily. This seems like something that should be achievable...I'm just not sure how useful it would be.
Sponsor
Sponsor
Sponsor
sponsor
Dreadnought




PostPosted: Thu Apr 12, 2012 10:57 pm   Post subject: Re: Using records with Draw.FillPolygon/Polygon

I didn't know about much of them either until recently. I still prefer C pointers though, they're more flexible.

Also, I agree that it would be nice to have tools like these in some higher level languages, but I feel like it might be a performance hit (all that memory reorganizing).
Display posts from previous:   
   Index -> Programming, Turing -> Turing Help
View previous topic Tell A FriendPrintable versionDownload TopicSubscribe to this topicPrivate MessagesRefresh page View next topic

Page 1 of 1  [ 9 Posts ]
Jump to:   


Style:  
Search: