
-----------------------------------
Raknarg
Thu Apr 12, 2012 10:01 am

Using records with Draw.FillPolygon/Polygon
-----------------------------------
So I have this:

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.

-----------------------------------
DemonWasp
Thu Apr 12, 2012 10:15 am

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
Thu Apr 12, 2012 10:21 am

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
Thu Apr 12, 2012 1:49 pm

Re: Using records with Draw.FillPolygon/Polygon
-----------------------------------
 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.
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.
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
Thu Apr 12, 2012 1:55 pm

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.


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
Thu Apr 12, 2012 2:50 pm

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 );
}
[/code]

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
Thu Apr 12, 2012 4:49 pm

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.

Oh, you mean like this?
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), "      ", int@(dyAdd), "     