Scolring - Forum

Entraides et échanges autour de la technologie Scol - Informations and exchanges on the Scol technology

Vous pouvez changer la langue de l'interface une fois inscrit - You can change the language once registered

You are not logged in.

#1 26-Sep-2024 19:13:36

hebdemnobad
Member
From: northamerica
Registered: 20-Apr-2011
Posts: 1,527
Website

hexagon grid project wip

i figure before I mess with hexagons in 3d in os3d, I will make a hexagon grid painted into a bitmap. then i will use some of the math to position hexagon shaped meshes in 3d space.

struct XYVertex=[
	posx:	I,
	posy: I
	]mkXYVertex;;//this makes a vertex object with xy coordinates
	
struct QRSCoordinate=[
	posq:	I,
	posr: I,
	poss: I
	]mkQRSCoordinate;;//this makes a vertex object with qrs coordinates. It is easier to create a grid
//of hexagons this way and you can use xyz vector functions with your hexagons
	
	struct Hexagon=[
	VQRScenter:	QRSCoordinate,
	Isize:	I,
	//table of edge points in xy coordinate system with XYVertex objects, since we always know that there are only 6 such points we can use a table
	lxypoints:	tab [XYVertex],
	//table  of edge points in qrs (xyz) coordinate system with QRSCoordinate objects,since we always know that there are only 6 such points we can use a table
	lqrspoints: tab [QRSCoordinate],
	//send vertex and hexagon to function from a mouse click, get whether in outside, 0, or inbounds, 1
	//I probably won't need this when i make it in 3d and I may not work on this at all
	funcwithinbounds: fun [[Hexagon XYVertex]] I,
	//send hexagon to function with center and size, create vertex coordinates with some geometry math
	//so as to load return into lpoints table
	funmakevertices: fun [Hexagon] [tab [XYVertex] ],
	//send hexagon to function with xy coordinates, get back hexagon 
	//with qrs (xyz) coordinates as they are easier to work with and to store center of hex
	//in QRSCoordinate object
	funconvert_xy_to_qrs: fun [Hexagon][I I I],	
	//reverse  of funconvert_xy_to_qr so we can set hexagon center (and maybe edge points?) in xy space
	funconvert_qrs_to_xy:	fun [Hexagon][I I]


	
	]mkHexagon;;

   //this object will hold a bunch of hexagons in a grid in qrs coordinate system
   //this will be very important to build a hexagon grid with hexagon .mesh object in os3d i think
	struct Hexagongrid=[
		hexagongrid: [Hexagon r1]
			] mkHexagongrid;;
	
fun main()=
	_showconsole;
	0;;

so far so good it runs, but I haven't actually done anything yet. neutral neutral neutral



my first step will be to draw one humble hexagon into a bitmap using the information gained from a Hexagon object and the _DRAWpoly24 function.
then to paint a grid of hexagons into a bitmap (this is intimidating as you position the hexagons in qrs space and convert everything to xy space so you can put them in a bitmap that only understands xy not qrs.)

Last edited by hebdemnobad (26-Sep-2024 19:27:37)

Offline

#2 6-Oct-2024 05:31:25

hebdemnobad
Member
From: northamerica
Registered: 20-Apr-2011
Posts: 1,527
Website

Re: hexagon grid project wip

ok. i think i can create an array of hex objects in qrs space that is an arbitrary height in rows of hexes and width in columns of hexes, the size of each hex, and whether the first column is lower than the second colum or the first column is higher than the second column, where the q r and s coordinates always add to zero.

the problem is turning the qrs (like xyz coordinates) coordinates into xy coordinates so they can be drawn or be used to arrange meshes in os3d.  fortunately i have a retired math professor in the family and got him interested enough in the qrs conversion to xy conversion... (the code below has preloaded the consle.pkg from the tutorials to display everything.

hextable.scol

_load "hextable/hexload.pkg"

hexload.pkg

proto hextablemain = fun [] I;;
proto consolemain = fun[] I;;



fun main()=
_showconsole; 
_load "os3dlib/tools.pkg";
_load "hextable/console.pkg";
_load "hextable/hextable.pkg";


_fooS "in hexload main function";
consolemain;
hextablemain;
0;;

hextable.pkg

// nested table syntax typeof Globalgrid = tab [I tab [S tab F]];;



typeof Global_startvectable = tab QRSCoordinate;;
typeof Global_hextable = tab tab Hex;;//this is a table. each element in the table contains a table of hex objects. the table is total_columns long and total  rows high see makehexgrid function below
proto mygetcoordinates = fun [QRSCoordinate] [I I I];;
proto makestartvectable = fun [I I S] I;;
proto scalevector = fun [[I I I] I ] [I I I];;

//vertex object with qrs coordinates
struct QRSCoordinate=[
	posq:	I,
	posr: I,
	poss: I,
	getcoordinates: fun [QRSCoordinate] [I I I]
	]mkQRSCoordinate;;
	
struct Hex= [
	hexcenter: 	QRSCoordinate,
	hexsize:		I,
	fungethexcenter: fun [Hex]  [I I I],
	funprinthex: fun [Hex] S
	]mkHex;;
	
	
	
fun get_full_startvector_table_contents (startvectortable)= 	

fun mygetcoordinates(qrs)=
	let qrs.posq-> q in
	let qrs.posr-> r in
	let qrs.poss-> s in
	[q r s];;
	
fun getmyhexcoordinates (hex) =
	let hex.hexcenter -> qrs_center in
	mygetcoordinates qrs_center;; //this function takes hex and returns [q r s] for qrs object in its center

fun myprinthex (hex)=
	let exec hex.fungethexcenter with [hex] -> [q r s] in
	let strcatn "this hex q center is at: ":: (itoa q)::" it's r center is at: ":: (itoa r):: " and its s center is at: "::(itoa s)::nil -> string in
	(
		console_print lastcsl string;
		string);;
	
fun makeQRS(q, r, s)=
	let mkQRSCoordinate [q r s nil]-> qrs in
	(
	set qrs.getcoordinates=@mygetcoordinates;
	qrs);;
	
fun makeHex(qrs, size)=
let mkHex [qrs size  @getmyhexcoordinates @myprinthex] -> hex in
hex;;

fun scalevector (directional_vector, scale_factor)=
	let directional_vector -> [q r s] in
	let q*scale_factor -> newq in
	let r*scale_factor -> newr in
	let s*scale_factor -> news in
	[newq newr news];;


fun addvec_with_direction (inputvector, direction, distance)= //this function takes a vector and direction and returns a new vector object,the result depending on the the direction this package has already loaded the os3d tools.pkg so it can use functions from it
	
	if ((strcmp direction "northeast") ==0) then
	(
	//console_print lastcsl"adding new vector to the northeast!";
	let [1 (-1) 0] -> directional_vector in
	let distance -> factor in
	let scalevector directional_vector factor ->  scaled_directional_vector in
	let addVector inputvector scaled_directional_vector -> outputvector in

	let outputvector -> [q r s] in
	(
	//console_print lastcsl strcatn "new q is: "::(itoa q)::" new r is: "::(itoa r):: " and new s is: ":: (itoa s)::nil;
	outputvector;
	);
	)
	else if ((strcmp direction "southeast") ==0) then
	(
	let [1 0 (-1)] -> directional_vector in
	let distance -> factor in
	let scalevector directional_vector factor ->  scaled_directional_vector in
	let addVector inputvector scaled_directional_vector -> outputvector in
	
	let outputvector -> [q r s] in
	(
	//console_print lastcsl strcatn "new q is: "::(itoa q)::" new r is: "::(itoa r):: " and new s is: ":: (itoa s)::nil;
	outputvector;
	);
	)
	
	else if ((strcmp direction "north") ==0) then
	(
	//console_print lastcsl"adding new vector to the north!";
	let [0 (-1) 1] -> directional_vector in
	let distance -> factor in
	let scalevector directional_vector factor ->  scaled_directional_vector in
	let addVector inputvector scaled_directional_vector -> outputvector in
	
	let outputvector -> [q r s] in
	(
	//console_print lastcsl strcatn "new q is: "::(itoa q)::" new r is: "::(itoa r):: " and new s is: ":: (itoa s)::nil;
	let q+r+s -> result in
	if (result == 0) then console_print lastcsl"no error" else console_print lastcsl"error!!";
	outputvector;
	);
	)
	
	
	else
	(
	nil
	);;




fun make_column (hexgrid, hexlist, currentcolumn_number, currentrow_number, inputqrs, total_rows, hexsize)=
console_print lastcsl strcatn "presently in column number: ":: (itoa currentcolumn_number)::nil;
if (currentrow_number<total_rows)  then
(

console_print lastcsl strcatn "currently in row number: ":: (itoa currentrow_number):: " and we will take the inputqrs and make a hex here!":: "\n":: "then we will feed a new QRS object into the function"::nil;
let makeHex inputqrs hexsize-> hex in
let lcat hexlist hex::nil -> hexlist in
let exec inputqrs.getcoordinates with [inputqrs] -> inputvec in
let addvec_with_direction inputvec "north" hexsize -> newvec in
let newvec -> [q r s] in
let makeQRS q r s -> newqrs in
(
 myprinthex hex;
set currentrow_number=currentrow_number+1;
make_column hexgrid hexlist currentcolumn_number currentrow_number newqrs total_rows hexsize;
hexlist;
);
)

else //we are done with the column, turn the list into a table, and put it in the currentcolumn_number of the Global_hextable
(
console_print lastcsl strcatn "done with column number: " ::(itoa currentcolumn_number):: nil;
let sizelist hexlist -> size in
let listtotab hexlist -> hextable in
let sizetab hextable -> tablesize in
(
console_print lastcsl strcatn "there are : ":: (itoa size):: " items inthe hexlist"::nil;
console_print lastcsl strcatn "there are : ":: (itoa tablesize):: " items inthe hextable"::nil;
set Global_hextable.currentcolumn_number = hextable;
let sizetab Global_hextable.currentcolumn_number -> sizable2 in
console_print lastcsl strcatn "there are :" :: (itoa sizable2):: " elements in column number"::(itoa currentcolumn_number)::nil;
hexlist;
//todo test contents of table of tables of hexes and validate their  coordintaes
);
);;
	



	
	
fun fillvectortable (vector, hexsize, qrstable, startstate, rownumber)=
	if (rownumber ==0) then
	(
	console_print lastcsl "we are at start vecdtor table item zero;Global_startvectable.0  has already been set, the only thing left it to determine whether to go southeast (evens up) or northeast (odds up)";
	if ((strcmp startstate "evens up") ==0) then 
	(
		//go southeast, and feed in vector of this item to form next item
		//we want to make vector for first odd number to feed into function
		let addvec_with_direction  vector "southeast" hexsize-> newvector in
		(
		 set rownumber = rownumber+1;
	    fillvectortable newvector hexsize qrstable startstate rownumber;
		0;
		);
		
	0;
	) else
	(
		let addvec_with_direction  vector "northeast" hexsize-> newvector in
		(
		 set rownumber = rownumber+1;
	    fillvectortable newvector hexsize qrstable startstate rownumber;
		0;
		);
		
		//go northeast and feed in vector of this item to form next item
		//we want to make vector for first odd number to feed into function
		
	0;
	);
		
	0;
	)
	
	
	
	else if (rownumber == (sizetab qrstable)) then
	(
	console_print lastcsl"we are at end of table; ";
	get_full_startvector_table_contents Global_startvectable;
	0;
	)
	else
	(
	if ((mod rownumber  2)!= 0) then//odd number fork 
	(
			console_print lastcsl"we have an odd  number";
			if ((strcmp startstate "evens up") ==0) then //if evens up then odd numbers make a new vector to the northeast
			(
					console_print lastcsl"go northeast because evens are up and odds are down";
					let addvec_with_direction  vector "northeast" hexsize-> newvector in
					let vector -> [q r s] in
					let makeQRS q r s -> newqrs in
					(
               set Global_startvectable.rownumber = newqrs;
               set rownumber= rownumber+1;
               fillvectortable newvector hexsize Global_startvectable startstate rownumber;
					);
			0;
			)
			else
			(
					console_print lastcsl"go southeast because odds are above evens"; //if evens down then odd numbers make a new vector to the southeast
					let addvec_with_direction  vector "southeast" hexsize -> newvector in
					let vector -> [q r s] in
					let makeQRS q r s -> newqrs in
					(
               set Global_startvectable.rownumber = newqrs;
               set rownumber= rownumber+1;
               fillvectortable newvector hexsize Global_startvectable startstate rownumber;
					);
			0;
			); 
	0;
   )
   
   ///even number fork
  else
   (
   console_print lastcsl"we have an even number";
   if ((strcmp startstate "evens up") ==0) then
			(
					console_print lastcsl"go southeast because evens are up and odds are down";//if evens up then even numbers make a new vector to the southheast
					let addvec_with_direction  vector "southeast" hexsize-> newvector in
					let vector -> [q r s] in
					let makeQRS q r s -> newqrs in
					(
               set Global_startvectable.rownumber = newqrs;
               set rownumber= rownumber+1;
               fillvectortable newvector hexsize Global_startvectable startstate rownumber;
					);
			0;
			)
			else
			(
					console_print lastcsl"go northeast because odds are above evens"; //if odds up then even numbers make a new vector to the norththheast
					let addvec_with_direction  vector "northeast" hexsize-> newvector in
					let vector -> [q r s] in
					let makeQRS q r s -> newqrs in
			
					(
               set Global_startvectable.rownumber = newqrs;
               set rownumber= rownumber+1;
               fillvectortable newvector hexsize Global_startvectable startstate rownumber;
					);
			0;
			); 
	0;
   );
   0;
 	);
  	0;;


	
fun makestartvectable(size, hexsize, startstate)=
	set Global_startvectable = mktab size nil;
	let makeQRS 0 0 0 -> r in
	let 0 -> rownumber in
	let mygetcoordinates r -> startcoordiantes in//this will be [0 0 0]
	(
	set Global_startvectable.0 = r;
	fillvectortable  startcoordiantes hexsize Global_startvectable startstate rownumber;
	0;
	);
	0;;
	
	fun makehexgrid (total_columns, total_rows, hexsize, startstate)=
	makestartvectable total_columns hexsize startstate;
	let mktab total_columns nil-> table in
	let 0-> column_counter in
	let 0-> column_number in
	(
	set Global_hextable= table;
	while (column_counter < total_columns) do
	(
	let Global_startvectable.column_counter -> initialqrs in
	//make_column arguments: hexgrid, hexlist, currentcolumn_number, currentrow_number, inputvec, total_row, hex size
  make_column table nil column_counter 0 initialqrs total_rows hexsize;
  set column_counter= column_counter +1;
  );
  0;
  );
	0;;

fun hextablemain()=
_showconsole;
//the number after the function call is the number of vectors in the vector table which will be the number of columns in the hex table

makehexgrid  3 3 1 "evens up";
//do some tests
myprinthex Global_hextable.0.0; 
myprinthex Global_hextable.1.2; 
myprinthex Global_hextable.2.2;
0;;

Last edited by hebdemnobad (6-Oct-2024 17:37:00)

Offline

#3 8-Oct-2024 02:19:37

hebdemnobad
Member
From: northamerica
Registered: 20-Apr-2011
Posts: 1,527
Website

Re: hexagon grid project wip

i've gotten it all working (in text, next step to draw these things...i know for os3d you don't have to draw hexagons but will use meshes but I wanted to make sure that the hexagons all fit together before I build the plugit. the goal here is to make 2d maps for table top games to keep track of where the players (and monsters) are, without having to look through rulebooks all the time.


the code builds a rectangular array of hexagons in q r s (like xyz) space, and then when needed translates the qrs coordinates into xy coordinates to draw in 2d eventually. the code can create rectangular arrays of arbitrary size, with hexagons of arbitrary size with arbitrary starting qrs coordinates (although the coordinates have to make sense in qrs space; if they don't, all the subsequent calculations will be wrong.)


note: y is calculated with a -1 so it makes sense like a mathematical graph where y is 0 at the bottom left. since with drawing apps including scol you start drawing at the top left, remove the -1.

[edit on 10.17.2024---i removed the global variables and redid the same functionality with structs and local variables]

// nested table syntax typeof Globalgrid = tab [I tab [S tab F]];;

proto mygetcoordinates = fun [QRSCoordinate] [I I I];;
proto makestartvectable = fun [I I S [I I I]] I;;
proto scalevector = fun [[I I I] I ] [I I I];;
proto hex_to_pixel = fun [Hex] [I I];;
proto initializevectortable = fun [tab QRSCoordinate I S QRSCoordinate I] Vectortable;;
proto fillvectortable = fun [[I I I] I Vectortable S I] Vectortable;;

proto makehexgrid = fun [I I I S [I I I]] Hexgrid;;
//vertex object with qrs coordinates
struct QRSCoordinate=[
	posq:	I,
	posr: I,
	poss: I,
	getcoordinates: fun [QRSCoordinate] [I I I]
	]mkQRSCoordinate;;
	
struct Hex= [
	hexcenter: 	QRSCoordinate,
	hexheight:		I,
	fungethexcenter: fun [Hex]  [I I I],
	funprinthex: fun [Hex] S,
	funhextopixel: fun [Hex] [F F],
	hex_xy: [F F]
	]mkHex;;
	

struct Vectortable=[
	vectortable:	tab QRSCoordinate,
	rows:			I,
	start:			S,
	startvec:		QRSCoordinate
	
	] mkVectortable;;		
	
struct Hexgrid =[
	hextable:				tab tab Hex,// each element of the hexgrid table has a table of hexes (which is a column in the hex grid)
	hexgridrows:			I,
	columns:				I,
	hexsize:				I
	]mkHexgrid;;
	
	

	
//function below: fun [Vectortable] returns I utility to make sure vector table is correct, this is a table of qrs objects that forms row 0 of every column in a rectangular array of hexes
fun print_full_startvector_table_contents (startvectortable)= 
	_fooS "the Vectortable object is complete, reading out full contents of  Vectortable.vectortable which is in the format of tab QRSCoordinate";
	let sizetab startvectortable ->table_total in
	let 0-> counter in
	(
	while (counter< table_total) do
	(
	
	let startvectortable.counter-> qrsobject in
	let  mygetcoordinates qrsobject -> [q r s] in
	(
	console_print lastcsl strcatn "present q r s coordinates in start vector table are: ":: (itoa q)::"  "::(itoa r):: "  ":: (itoa s)::nil;
	0;
	);
	set counter = counter+1;
	);
	console_print lastcsl strcatn "at end of table, finally!  the table had a total of: ":: (itoa table_total)::" items in it"::nil;
	);
			0;;
	
//function below: fun [QRSCoordinate] returns [I I I]
fun mygetcoordinates(qrs)=
	let qrs.posq-> q in
	let qrs.posr-> r in
	let qrs.poss-> s in
	[q r s];;

//function below: fun [Hex] returns [I I I], function to get I I I qrs coordinates from a hex
fun getmyhexcoordinates (hex) =
	let hex.hexcenter -> qrs_center in
	mygetcoordinates qrs_center;; //this function takes hex and returns [q r s] for qrs object in its center
//function below: fun [Hex] returns S, utility to verify hex is at right place
fun myprinthex (hex)=
	let exec hex.fungethexcenter with [hex] -> [q r s] in
	let hex.	hex_xy -> [x y] in
	let strcatn "this hex q center is at: ":: (itoa q)::" it's r center is at: ":: (itoa r):: " and its s center is at: "::(itoa s)::"\n"::" the converted hex x coordinate is: ":: (ftoa x)::" and the converted hex y coordinate is:"  :: (ftoa y)::nil -> string in
	(
		string);;

//todo fun below takes tab Hex and calls printhex for every hex in the column
fun printcolumn (column_number, total_columns, columnobject)= 
let sizetab columnobject -> size in
let 0 -> counter in
while (counter< size) do
(
let columnobject.counter -> hex in
_fooS strcatn "this is hex in row number: " :: (itoa counter):: " and and the information for this hex is: " :: (myprinthex hex)::nil;
set counter = counter +1;
);;	


 // fun [I F I] returns F we use this function so to prevent any division by 0 which scol doesn't like
fun resolve_q_to_x (lhexheight, finalfloatsize, q)=
	
if (q == 0) then
	(
	let itof q -> xfloat in
	xfloat;
	)
	else
	(
	let finalfloatsize *. (3.0 /. 2.0) *. (itof q) -> xfloat in
	let xfloat *. (itof lhexheight) -> xfloat in	
	xfloat;
	);;
	
fun myhextopixel (hex) = //proto fun [hex]  [F F]
	let getmyhexcoordinates hex -> [q r s] in
	let hex.hexheight -> lhexheight in
	let lhexheight -> height in
	let (itof height) -> float_height in
	let ((float_height *. 2.0) *. sqrt (3.0)) /. 3.0 -> float_final_size in
	let resolve_q_to_x lhexheight float_final_size q -> xfloat in
   let (sqrt (3.0) /. (2.0)) *.  (itof q) -> addendum1 in
	let sqrt (3.0) *. (itof r) -> addendum2 in
	let float_final_size *.  (sqrt 3.0) *. (itof q) /. (2.0) -> test_addenda1 in
	let float_final_size *. (sqrt 3.0) *. (itof r) -> test_addenda2 in
	let test_addenda1 +. test_addenda2 -> sum in 
	let sum *. (-.1.0)-> yfloat in // multiply by (1.0) or (-.1.0) depending on whther y axis goes up or down, it usually goes up as you go downt the screen but for initial debuggin i like y going up from bottom of screen like an xy graph
	let xfloat -> x in
	let  yfloat -> y in
	[x y];;
	
 // fun [I I I] returns QRSCoordinate	
fun makeQRS(q, r, s)=
	let mkQRSCoordinate [q r s nil]-> qrs in
	(
	set qrs.getcoordinates=@mygetcoordinates;
	qrs);;
	
// fun [QRSCoordinate I] returns Hex		
fun makeHex(qrs, size)=
let mkHex [qrs size  @getmyhexcoordinates @myprinthex @myhextopixel nil ] -> hex in
let exec hex.funhextopixel with [hex] -> [x y] in
(
set hex.hex_xy = [x y];
hex);;


// fun [[I I I] I ] returns [I I I]	
fun scalevector (directional_vector, scale_factor)=
	let directional_vector -> [q r s] in
	let q*scale_factor -> newq in
	let r*scale_factor -> newr in
	let s*scale_factor -> news in
	[newq newr news];;

// fun [[I I I] S I] returns [I I I]	
fun addvec_with_direction (inputvector, direction, distance)= //this function takes a vector and direction and returns a new vector object,the result depending on the the direction this package has already loaded the os3d tools.pkg so it can use functions from it
	
	if ((strcmp direction "northeast") ==0) then
	(
	//console_print lastcsl"adding new vector to the northeast!";
	let [1 (-1) 0] -> directional_vector in
	let distance -> factor in
	let scalevector directional_vector factor ->  scaled_directional_vector in
	let addVector inputvector scaled_directional_vector -> outputvector in

	let outputvector -> [q r s] in
	(
	//console_print lastcsl strcatn "new q is: "::(itoa q)::" new r is: "::(itoa r):: " and new s is: ":: (itoa s)::nil;
	outputvector;
	);
	)
	else if ((strcmp direction "southeast") ==0) then
	(
	let [1 0 (-1)] -> directional_vector in
	let distance -> factor in
	let scalevector directional_vector factor ->  scaled_directional_vector in
	let addVector inputvector scaled_directional_vector -> outputvector in
	
	let outputvector -> [q r s] in
	(
	//console_print lastcsl strcatn "new q is: "::(itoa q)::" new r is: "::(itoa r):: " and new s is: ":: (itoa s)::nil;
	outputvector;
	);
	)
	
	else if ((strcmp direction "north") ==0) then
	(
	//console_print lastcsl"adding new vector to the north!";
	let [0 (-1) 1] -> directional_vector in
	let distance -> factor in
	let scalevector directional_vector factor ->  scaled_directional_vector in
	let addVector inputvector scaled_directional_vector -> outputvector in
	
	let outputvector -> [q r s] in
	(
	//console_print lastcsl strcatn "new q is: "::(itoa q)::" new r is: "::(itoa r):: " and new s is: ":: (itoa s)::nil;
	let q+r+s -> result in
	if (result == 0) then console_print lastcsl"no error" else console_print lastcsl"error!!";
	outputvector;
	);
	)
	
	
	else
	(
	_fooS "INPUT QRS COORDINATES ERROR!";	
	nil
	);;



// fun [Hexgrid Hex r1 I I QRSCoordinate I I ] returns tab Hex	
fun make_column ( hexgrid, hexlist, currentcolumn_number, currentrow_number, inputqrs, total_rows, hexsize)= //fun [ Hexgrid hex r1 I I QRSCoordinate, I I ] returns tab Hex
console_print lastcsl strcatn "presently in column number: ":: (itoa currentcolumn_number)::nil;
if (currentrow_number<total_rows)  then
(
let exec inputqrs.getcoordinates with [inputqrs] -> inputvec in
let inputvec -> [inputq inputr inputs] in
let makeHex inputqrs hexsize-> hex in
let lcat hexlist hex::nil -> hexlist in
let exec inputqrs.getcoordinates with [inputqrs] -> inputvec in
let addvec_with_direction inputvec "north" hexsize -> newvec in
let newvec -> [q r s] in
let makeQRS q r s -> newqrs in
(
 myprinthex hex;
set currentrow_number=currentrow_number+1;
//we are not done with column so recursively call function and in that we this branch of if then else doesn't return anything
make_column hexgrid hexlist currentcolumn_number currentrow_number newqrs total_rows hexsize;
);
)

else //we are done with the column, turn the list into a table, and put it in the currentcolumn_number of the Global_hextable
(
let sizelist hexlist -> size in
let listtotab hexlist -> thisfunctionhextable in
let sizetab thisfunctionhextable -> tablesize in
let sizetab hexgrid.hextable.currentcolumn_number -> sizable2 in
thisfunctionhextable;

);;


// fun [[I I I] I Vectortable S I] returns Vectortable,m given a start qrs coordinate, [I I] generate a table of QRSCoordinate objects of arbitrary size and lenght, with either evens higher or odds higher
fun fillvectortable (vector, hexsize, qrstable , startstate, rownumber)= //fun [I I I] I Vectortable S I RETURN: Vectortable
	_fooS "in fillvectortable funtion!";
	if (rownumber ==0) then
	(
		if ((strcmp startstate "evens up") ==0) then
		( //since evens are up we go southeast to element 1, which is odd
		//go southeast, and feed in vector of this item to form next item
		//we want to make vector for first odd number to feed into function
		let addvec_with_direction  vector "southeast" hexsize-> newvector in
		(
		 set rownumber = rownumber+1;
	    fillvectortable newvector hexsize qrstable startstate rownumber;
		);
		
		) 
	else //state is "odds up", we go northeast to element 1, which is odd
		(
		let addvec_with_direction  vector "northeast" hexsize-> newvector in
		(
		 set rownumber = rownumber+1;
	    fillvectortable newvector hexsize qrstable startstate rownumber;
		);
		
		//go northeast and feed in vector of this item to form next item
		//we want to make vector for first odd number to feed into function
		
	);
	)
	else if (rownumber == (sizetab qrstable.vectortable)) then
	(
	//return finalized and filled up qrstable which is a Vectortable object
	let _fooS strcat "total size of qrstable is" (itoa (sizetab qrstable.vectortable)) -> string in
	print_full_startvector_table_contents qrstable.vectortable; //call function to read out values of the created Vectortable.vectortable, which is tab QRSCoordinate
	qrstable;
	)
	
	
	else if (rownumber < (sizetab qrstable.vectortable)) then
	(
	if ((mod rownumber  2)!= 0) then//odd number fork 
	(
			console_print lastcsl"we have an odd  number";
			if ((strcmp startstate "evens up") ==0) then //if evens up then odd numbers make a new vector to the northeast
			(
					console_print lastcsl"go northeast because evens are up and odds are down";
					let addvec_with_direction  vector "northeast" hexsize-> newvector in
					let vector -> [q r s] in
					let makeQRS q r s -> newqrs in
					(
               set qrstable.vectortable.rownumber = newqrs;
               set rownumber= rownumber+1;
               fillvectortable newvector hexsize qrstable startstate rownumber;
					);

			)
			else
			(
					console_print lastcsl"go southeast because odds are above evens"; //if evens down then odd numbers make a new vector to the southeast
					let addvec_with_direction  vector "southeast" hexsize -> newvector in
					let vector -> [q r s] in
					let makeQRS q r s -> newqrs in
					(
               set qrstable.vectortable.rownumber = newqrs;
               set rownumber= rownumber+1;
               fillvectortable newvector hexsize qrstable startstate rownumber;
					);
			); 

   )
   
   ///even number fork
  else
   (
   console_print lastcsl"we have an even number";
   if ((strcmp startstate "evens up") ==0) then
			(
					console_print lastcsl"go southeast because evens are up and odds are down";//if evens up then even numbers make a new vector to the southheast
					let addvec_with_direction  vector "southeast" hexsize-> newvector in
					let vector -> [q r s] in
					let makeQRS q r s -> newqrs in
					(
               set qrstable.vectortable.rownumber = newqrs;
               set rownumber= rownumber+1;
               fillvectortable newvector hexsize qrstable  startstate rownumber;
					);

			)
			else
			(
					console_print lastcsl"go northeast because odds are above evens"; //if odds up then even numbers make a new vector to the norththheast
					let addvec_with_direction  vector "northeast" hexsize-> newvector in
					let vector -> [q r s] in
					let makeQRS q r s -> newqrs in
			
					(
               set qrstable.vectortable.rownumber = newqrs;
               set rownumber= rownumber+1;
               fillvectortable newvector hexsize qrstable startstate rownumber;
					);

			); 

   );

 	)
 	
	
	
	else
	(
		nil;
	);;


	
// fun initializevectortable = fun [tab QRSCoordinate I S QRSCoordinate I] Vectortable;;	
fun initializevectortable (initialvectable, columns, startstate2, startqrs, hexsize)=
 	let mkVectortable [initialvectable  columns  startstate2 startqrs] -> vectable in
	let mygetcoordinates startqrs -> startcoordiantes in
	let 0 -> rownumber in
	(
	set vectable.vectortable.0 = startqrs; //set the initial qrs element of the Vectortable.vectortable table, which is made of qrs objects
	let fillvectortable  startcoordiantes hexsize vectable  startstate2 rownumber -> vectable2 in
	vectable2);;
	

// fun [I I I S [I I I] returns i
fun makehexgrid (total_columns, total_rows, hexsize, startstate, startingvec)=
	let mktab total_columns nil -> initialvectable in
	let startingvec ->  [q r s] in
	let makeQRS q r s -> starqrs in
	let initializevectortable initialvectable total_columns  startstate starqrs hexsize -> vectable2 in
	let vectable2.rows -> rows in
	let mktab total_columns nil-> hexgridtable in
	let mkHexgrid [hexgridtable total_rows total_columns hexsize] -> hexgrid_object in
	(
	//set Global_hextable= hexgrid_object ;
	let 0-> column_counter in
	let 0-> column_number in
	(
	while (column_counter < total_columns) do //redo with strucs not global variables
	(
	let vectable2.vectortable.column_counter -> initialqrs in
	//make_column arguments: Hexgrid, hexlist (set at nil until function begins to resurviely, currentcolumn_number, currentrow_number, inputvec, total_row, hex size
   let make_column hexgrid_object nil column_counter 0 initialqrs total_rows hexsize -> this_column in //make_column returns tab Hex
   // load completed column (which is a table of hexes) into first element of Hexgrid.hextable
  	set hexgrid_object.hextable.column_counter = this_column;
  	set column_counter= column_counter +1;
  );
  0;
  //return a completed Hexgrid object
 hexgrid_object;
  );
  );;

fun hextablemain()=
_showconsole;
//the number after the function call is the number of vectors in the vector table which will be the number of columns in the hex table
// fun makehexgrid: columns, rows, hexsize (vertical height for flat top), start state evens up or odds up, returns a Hexgrid object
let makehexgrid  5 3 1 "odds up" [0 0 0] -> hexgrid in
(
//testing code below, grab a hex and print its x y coordinates
let exec hexgrid.hextable.3.0.funhextopixel with [ hexgrid.hextable.3.0] -> [xpixel ypixel] in
_fooS strcatn "the xpixel of this hex is: " :: (ftoa xpixel):: " and the ypixel of this hex is: ":: (ftoa ypixel):: nil;
//testing code, grab a column and print info for each hex in column
exec  @printcolumn  with [3  hexgrid.columns  hexgrid.hextable.0];

0);;

Last edited by hebdemnobad (19-Oct-2024 23:30:42)

Offline

#4 14-Oct-2024 01:25:49

hebdemnobad
Member
From: northamerica
Registered: 20-Apr-2011
Posts: 1,527
Website

Re: hexagon grid project wip

on the drawing end, I'm able to get the voyager to draw a hexagon in xy space on a bitmap, a small step, but since I can do that, after cleaning things up I'll try to draw a whole grid of them using the weird qrs coordinates used above



typeof drawwindow = ObjWin;;
typeof drawbitmap = ObjBitmap;;
typeof shapetable = tab tab Shape;; // a table of elements, and each elementt contains a one dimensional table of shapes
proto test_point_table  = fun [Mypolygon] I;;

struct Shape =[
	shapesides: I, //number of sides for each chape
	shaptepoints: tab [I I]
		] mkShape;;




struct Point =[
	x:	F,
	y:	F,
	fungetvalues: fun [Point] [F F] ///function to return x and y properties of Point
	] mkPoint;;
	

struct Mypolygon =[
numsides:			I,
center:				[F F], 	//center of polygon
sidelength:			F,
height:				F,
points:				tab Point, //table of point objects in polygon
funmakepoints:		fun [Mypolygon] tab  Point,
drawpointstable:	tab [I I], //function to create table of points to put in points table
hextype :			S,//for hexes, if "flat" then flat top, if "pointy" then pointy top
parentebitmap:		Objbitmap,
hexheight:			F //hexheight is vertical radius if flat and norizontal radius if pointy
	
	] mkMypolygon;;
	
	
fun paint (win, bitmap)=
		
		_PAINTwindow drawwindow;
		_BLTbitmap  drawwindow drawbitmap 0 0;
		
	
	0;;
	
fun end (window, parameter)=
	_DSbitmap  drawbitmap;
	_DSwindow  drawwindow;
	_closemachine;
	0;;

fun createinterface ()=
	_fooS "in createinterface function";
	set drawwindow = _CRwindow _channel nil 0 0 512 512 WN_NORMAL "image window"; 
	set drawbitmap = _CRbitmap _channel 512 512;
	_FILLbitmap drawbitmap 0xFFFFFF;
	_BLTbitmap  drawwindow drawbitmap 0 0;
	_CBwinDestroy drawwindow @end nil;
	_CBwinPaint  drawwindow @paint drawwindow;
	0;;

fun myfungetvalues(point)=
	let point.x -> x in
	let point.y -> y in
	[x y];;

fun initpoint (x, y)=
	let mkPoint [x y @myfungetvalues] -> point in
	point;;
	
fun makeflattophexpoints (polygon)=
	let ((polygon.hexheight *. 2.0) *. (sqrt 3.0)) /. 3.0 -> float_final_size in
	let _fooS strcat "at first generation, float_final_size  is" (ftoa float_final_size ) -> string in
   (
   let 0 -> counter in
	let polygon.center -> [functionx functiony] in
   while (counter < (sizetab polygon.points)) do
   (
   if (counter == 0) then
   (
	let 0.0 -> radians in
	let functionx +. (float_final_size *. (cos radians)) -> xpoint in
	let functiony +. (float_final_size *. (sin radians)) -> ypoint in
	let initpoint xpoint ypoint -> point in
	set polygon.points.counter = point;
	set counter = counter+1;
   )
   else
   (
   
   let 60.0 *. (itof counter) -> angle_degrees in
   let (PIf /. 180.0) *. angle_degrees -> radians in
   let functionx +. (float_final_size *. (cos radians)) -> xpoint in
	let functiony +. (float_final_size *. (sin radians)) -> ypoint in
	let initpoint xpoint ypoint -> point in
	set polygon.points.counter = point;
	set counter = counter+1;
	
   );
   );
   );
   0;;

fun hexmakepoints (polygon)=	
fun trianglemakepoints (polygon) = //this is only good for a triangle//return completed table of the three points in the triangle



fun test_point_table (polygon)=
	let polygon.points -> pointtable in
	let sizetab pointtable -> size in
	let 0 -> counter in
	while (counter < size) do
	(
 	let polygon.points.counter -> point in
	let exec point.fungetvalues with [point]-> [x y] in
	let _fooS strcatn "this is point number: ":: (itoa counter)::"\n":: "this point x is":: (ftoa x)::" and this point y is: ":: (ftoa y):: nil -> string in
	set counter = counter + 1;
	);
	0;;
	
fun test_polygon_drawpoints (polygon)=
	let sizetab polygon.drawpointstable -> size in
	let 0 -> counter in
	while (counter < size) do
	(
	let polygon.drawpointstable.counter -> [x y] in
	let _fooS strcatn "this is drawpoint number: ":: (itoa counter):: " its interger x is: ":: (itoa x):: " and its interger y is: ":: (itoa y):: nil -> string in
	set counter = counter +1;
	);
	polygon;;
	
fun draw_polygon_points (polygon)=
		
	_fooS "in draw_polygon_points function";
let 0 -> counter in
while (counter < (sizetab polygon.drawpointstable)) do
(
let polygon.points.counter -> point in
let exec point.fungetvalues with [point]-> [x y] in 
let _fooS strcatn "drawpoint number: ":: (itoa counter):: " has an x of: ":: (ftoa x):: " and a y of: " :: (ftoa y):: nil -> string in
set polygon.drawpointstable.counter  = [ (ftoi x) (ftoi y)];

set counter = counter +1;
0;
);
//test_polygon_drawpoints polygon;
let sizetab polygon.drawpointstable -> size in
let _fooS strcat "size of drawpointstable is: " (itoa size) -> string in
//the shape is done, along with it's drawpoints now we can create interface
createinterface;



let _fooS "about to blit bitmap!" -> string in
set drawbitmap = _CRbitmap _channel 512 512;
_FILLbitmap drawbitmap 0xFFFFFF;
let _DRAWpoly24 drawbitmap  (sizetab polygon.drawpointstable) polygon.drawpointstable DRAW_SOLID 1 0x000000 DRAW_INVISIBLE 0x99FFFF -> bmp in
_BLTbitmap  drawwindow drawbitmap 0 0; 
_PAINTwindow drawwindow;
paint drawwindow drawbitmap;




0;;

fun initpolygon (numsides, center, sidelength, hextype, hexheight ) =
let center -> [centerx centery] in
let mktab numsides nil -> pointstable in
let mktab numsides nil -> drawpointstable in //initialize empty points table to put in polygon.points property WARNING: YOU MUST CREAT EMPTY TABLE BEFORE YOU CAN START FILLING TABLE UP WITH ELEMENTS WITH VALUES!!!!
let mkMypolygon [numsides center sidelength nil pointstable nil drawpointstable hextype nil hexheight] -> polygon in
(
	if (numsides == 3) then // MAKE A TRIANGLE

	(
		let ((sqrt 3.0)/. 2.0) *. sidelength -> fheight in //CALCULATE HEIGHT OF TRIANGLE FROM SIDE LENGTH only works for TRIANGLES
		set polygon.height = fheight;
		set polygon.funmakepoints = @trianglemakepoints;
		trianglemakepoints polygon;
		polygon;
	) 
	else if (numsides == 6) then //MAKE A HEXAGON
	(
		
		
		
		
		set polygon.funmakepoints = @hexmakepoints;
	
		hexmakepoints polygon;
		polygon;
	)
	else
	
	(
	nil;
	);
	draw_polygon_points polygon;
	polygon;
	);;
	
fun main ()=
_showconsole;
///for a triangle, height is height from centroid to apex, for hex height is vertical radius tto flat top if flat top or to top point if pointytop
   let [256.0 256.0]-> center in
	test_point_table (initpolygon 6 center nil "flattop" 120.0);

    0;;

Offline

#5 Today 02:25:38

hebdemnobad
Member
From: northamerica
Registered: 20-Apr-2011
Posts: 1,527
Website

Re: hexagon grid project wip

here is the scol code: (edit paths for your file structure)...go to

_load "hextopixelanddrawintobitmap/hexload.pkg"
main

this code loads the necessary packages: (hexload.pkg)

var iMinVoyagerVersion = 0xe5685457;;

proto getOs3dVersion = fun [] I;;
proto getVersionS = fun [] S;;
proto hextablemain = fun [] I;;


//Navigator window
typeof winAX = ObjWin;;
typeof APPBASEDIR = S;;

fun cbCloseTimer(trm, p)=
  _deltimer trm;
  _closemachine;
  0;;


fun getVoyagerVersionS()=
  let strextr _getpack _checkpack "locked/etc/version.txt" -> lver in
  let sizelist lver -> size in
  let nil -> curver in
  let 0 -> i in
  (
    while (i < size) && (curver == nil) do
    (
      let nth_list lver i -> elem in
      if strcmpi "version" hd elem then nil else
        set curver = hd tl elem;
      
      set i = i + 1;
    );
    curver;
  );;
  
  



fun main()=
_showconsole; 
_load"os3dlib/tools.pkg";
_load "hextopixelanddrawintobitmap/hextopixelanddrawintobitmap.pkg";
_load "hextopixelanddrawintobitmap/bitmap2.pkg";
hextablemain;

0;;

this code does the math to make a grid of hexes in 3 coordinate space (as well as converting those into xy coodrindates, hextopixelanddrawintobitmap.pkg:

// nested table syntax typeof Globalgrid = tab [I tab [S tab F]];;

proto mygetcoordinates = fun [QRSCoordinate] [I I I];;
proto makestartvectable = fun [I I S [I I I]] I;;
proto hex_to_pixel = fun [Hex] [I I];;
proto initializevectortable = fun [tab QRSCoordinate I S QRSCoordinate I] Vectortable;;
proto fillvectortable = fun [[I I I] I Vectortable S I] Vectortable;;
proto mypolygonmain = fun[Hexgrid] I;;

proto makehexgrid = fun [I I I S [I I I]] Hexgrid;;
//vertex object with qrs coordinates
struct QRSCoordinate=[
	posq:	I,
	posr: I,
	poss: I,
	getcoordinates: fun [QRSCoordinate] [I I I]
	]mkQRSCoordinate;;
	
struct Hex= [
	hexcenter: 	QRSCoordinate,
	hexheight:		I,
	fungethexcenter: fun [Hex]  [I I I],
	funprinthex: fun [Hex] S,
	funhextopixel: fun [Hex] [F F],
	hex_xy: [F F]
	]mkHex;;
	

struct Vectortable=[
	vectortable:	tab QRSCoordinate,
	rows:			I,
	start:			S,
	startvec:		QRSCoordinate
	
	] mkVectortable;;		
	
struct Hexgrid =[
	hextable:				tab tab Hex,// each element of the hexgrid table has a table of hexes (which is a column in the hex grid)
	hexgridrows:			I,
	columns:				I,
	hexsize:				I
	]mkHexgrid;;
	
	

	
//function below: fun [Vectortable] returns I ; utility to make sure vector table is correct, this is a table of QRSCoordinate objects that forms row 0 of every column in a rectangular array of hexes
fun print_full_startvector_table_contents (startvectortable)= 
	_fooS "the Vectortable object is complete, reading out full contents of  Vectortable.vectortable which is in the format of tab QRSCoordinate";
	let sizetab startvectortable ->table_total in
	let 0-> counter in
	(
	while (counter< table_total) do
	(
	
	let startvectortable.counter-> qrsobject in
	let  mygetcoordinates qrsobject -> [q r s] in
	(
0;
	);
	set counter = counter+1;
	);
	);
			0;;
	
//function below: fun [QRSCoordinate] returns [I I I]
fun mygetcoordinates(qrs)=
	let qrs.posq-> q in
	let qrs.posr-> r in
	let qrs.poss-> s in
	[q r s];;

//function below: fun [Hex] returns [I I I], function to get I I I qrs coordinates from a hex
fun getmyhexcoordinates (hex) =
	let hex.hexcenter -> qrs_center in
	mygetcoordinates qrs_center;; //this function takes hex and returns [q r s] for qrs object in its center


//function below: fun [Hex] returns S, utility to verify hex is at right place
fun myprinthex (hex)=
	let exec hex.fungethexcenter with [hex] -> [q r s] in
	let hex.	hex_xy -> [x y] in
	let strcatn "this hex q center is at: ":: (itoa q)::" it's r center is at: ":: (itoa r):: " and its s center is at: "::(itoa s)::"\n"::" the converted hex x coordinate is: ":: (ftoa x)::" and the converted hex y coordinate is:"  :: (ftoa y)::nil -> string in
	(
		string);;

//utility funntion below takes tab Hex and calls printhex for every hex in the column
fun printcolumn (column_number, total_columns, columnobject)= 
let sizetab columnobject -> size in
let 0 -> counter in
while (counter< size) do
(
let columnobject.counter -> hex in
_fooS strcatn "this hex is in column number: ":: (itoa column_number):: " and this is hex in row number: " :: (itoa counter):: " and and the information for this hex is: " :: (myprinthex hex)::nil;
set counter = counter +1;
);;	


	
fun myhextopixel(hex)=
	let getmyhexcoordinates hex -> [q r s] in
	let hex.hexheight -> height in
	let (itof height) -> float_height in
	let ((float_height *. 2.0) *. sqrt (3.0)) /. 3.0 -> float_final_size in
	let float_final_size *. (3.0 /. 2.0) *. (itof q) -> xfloataddend1 in
	let 0.0 -> xfloataddend2 in
	let xfloataddend1 +. xfloataddend2 -> xfloat in
	let float_final_size *.  (sqrt 3.0) *. (itof q) /. (2.0) -> test_addenda1 in
	let float_final_size *. (sqrt 3.0) *. (itof r) -> test_addenda2 in
	let test_addenda1 +. test_addenda2 -> sum in 
	let sum *. (-.1.0)-> sum in
	let  sum -> y in
	let xfloat -> x in
	[x y];;
	
 // fun [I I I] returns QRSCoordinate	
fun makeQRS(q, r, s)=
	let mkQRSCoordinate [q r s nil]-> qrs in
	(
	set qrs.getcoordinates=@mygetcoordinates;
	qrs);;
	
// fun [QRSCoordinate I] returns Hex		
fun makeHex(qrs, size)=
let mkHex [qrs size  @getmyhexcoordinates @myprinthex @myhextopixel nil ] -> hex in
//create xy coordinates of x and load into hexobject
let exec hex.funhextopixel with [hex] -> [x y] in
(
set hex.hex_xy = [x y];
hex);;



// fun [[I I I] S I] returns [I I I]	
fun addvec_with_direction (inputvector, direction)= //this function takes a vector and direction and returns a new vector object,the result depending on the the direction this package has already loaded the os3d tools.pkg so it can use functions from it
	
	if ((strcmp direction "northeast") ==0) then
	(
let [1 (-1) 0] -> directional_vector in
	let addVector inputvector directional_vector -> outputvector in

	let outputvector -> [q r s] in
	(
	outputvector;
	);
	)
	else if ((strcmp direction "southeast") ==0) then
	(
	let [1 0 (-1)] -> directional_vector in
	let addVector inputvector directional_vector -> outputvector in
	
	let outputvector -> [q r s] in
	(
	outputvector;
	);
	)
	
	else if ((strcmp direction "north") ==0) then
	(
	let [0 (-1) 1] -> directional_vector in
	
	let addVector inputvector directional_vector -> outputvector in
	
	let outputvector -> [q r s] in
	(
	let q+r+s -> result in
	if (result == 0) then //console_print lastcsl"no error" else //console_print lastcsl"error!!";
	outputvector;
	);
	)
	
	
	else
	(
	_fooS "INPUT QRS COORDINATES ERROR!";	
	nil
	);;



// fun [Hexgrid Hex r1 I I QRSCoordinate I I ] returns tab Hex. this function creates a rectangular grid of hexes with several settable parameters, but the grid will always be a rectangle
fun make_column ( hexgrid, hexlist, currentcolumn_number, currentrow_number, inputqrs, total_rows, hexsize)= //fun [ Hexgrid hex r1 I I QRSCoordinate, I I ] returns tab Hex
if (currentrow_number<total_rows)  then //we are not finished with the colum, take inputvec, make a hex, add it to hexlist. when we are done with the hexlist and the column we will turn it from Hex r1 to tab Hex
(
let exec inputqrs.getcoordinates with [inputqrs] -> inputvec in
let inputvec -> [inputq inputr inputs] in
let makeHex inputqrs hexsize-> hex in
let lcat hexlist hex::nil -> hexlist in
let exec inputqrs.getcoordinates with [inputqrs] -> inputvec in
let addvec_with_direction inputvec "north"  -> newvec in
let newvec -> [q r s] in
let makeQRS q r s -> newqrs in
(
 myprinthex hex;
set currentrow_number=currentrow_number+1;
//we are not done with column so recursively call function and in that we this branch of if then else doesn't return anything
make_column hexgrid hexlist currentcolumn_number currentrow_number newqrs total_rows hexsize;
);
)

else //we are done with the column, turn the list into a table, and put it in the currentcolumn_number of the Global_hextable
(
let sizelist hexlist -> size in
let listtotab hexlist -> thisfunctionhextable in
let sizetab thisfunctionhextable -> tablesize in
let sizetab hexgrid.hextable.currentcolumn_number -> sizable2 in
thisfunctionhextable;

);;


// fun [[I I I] I Vectortable S I] returns Vectortable,m given a start qrs coordinate, [I I] generate a table of QRSCoordinate objects of arbitrary size and lenght, with either evens higher or odds higher
fun fillvectortable (vector, hexsize, qrstable , startstate, rownumber)= //fun [I I I] I Vectortable S I RETURN: Vectortable
if (rownumber ==0) then
	(
		if ((strcmp startstate "evens up") ==0) then
		( //since evens are up we go southeast to element 1, which is odd
		//go southeast, and feed in vector of this item to form next item
		//we want to make vector for first odd number to feed into function
		let addvec_with_direction  vector "southeast" -> newvector in
		(
		 set rownumber = rownumber+1;
	    fillvectortable newvector hexsize qrstable startstate rownumber;
		);
		
		) 
	else //state is "odds up", we go northeast to element 1, which is odd
		(
		let addvec_with_direction  vector "northeast" -> newvector in
		(
		 set rownumber = rownumber+1;
	    fillvectortable newvector hexsize qrstable startstate rownumber;
		);
		
		//go northeast and feed in vector of this item to form next item
		//we want to make vector for first odd number to feed into function
		
	);
	)
	else if (rownumber == (sizetab qrstable.vectortable)) then
	(
	//return finalized and filled up qrstable which is a Vectortable object
	//print_full_startvector_table_contents qrstable.vectortable; //call function to read out values of the created Vectortable.vectortable, which is tab QRSCoordinate
	qrstable;
	)
	
	
	else if (rownumber < (sizetab qrstable.vectortable)) then
	(
	if ((mod rownumber  2)!= 0) then//odd number fork 
	(
			if ((strcmp startstate "evens up") ==0) then //if evens up then odd numbers make a new vector to the northeast
			(
					let addvec_with_direction  vector "northeast" -> newvector in
					let vector -> [q r s] in
					let makeQRS q r s -> newqrs in
					(
               set qrstable.vectortable.rownumber = newqrs;
               set rownumber= rownumber+1;
               fillvectortable newvector hexsize qrstable startstate rownumber;
					);

			)
			else
			(
					let addvec_with_direction  vector "southeast"  -> newvector in
					let vector -> [q r s] in
					let makeQRS q r s -> newqrs in
					(
               set qrstable.vectortable.rownumber = newqrs;
               set rownumber= rownumber+1;
               fillvectortable newvector hexsize qrstable startstate rownumber;
					);
			); 

   )
   
   ///even number fork
  else
   (
   //console_print lastcsl"we have an even number";
   if ((strcmp startstate "evens up") ==0) then
			(
					//console_print lastcsl"go southeast because evens are up and odds are down";//if evens up then even numbers make a new vector to the southheast
					let addvec_with_direction  vector "southeast" -> newvector in
					let vector -> [q r s] in
					let makeQRS q r s -> newqrs in
					(
               		set qrstable.vectortable.rownumber = newqrs;
               		set rownumber= rownumber+1;
               		fillvectortable newvector hexsize qrstable  startstate rownumber;
					);

			)
			else
			(
					let addvec_with_direction  vector "northeast" -> newvector in
					let vector -> [q r s] in
					let makeQRS q r s -> newqrs in
			
					(
               set qrstable.vectortable.rownumber = newqrs;
               set rownumber= rownumber+1;
               fillvectortable newvector hexsize qrstable startstate rownumber;
					);

			); 

   );

 	)
 	
	
	
	else
	(
		nil;
	);;


	
// fun initializevectortable = fun [tab QRSCoordinate I S QRSCoordinate I] Vectortable;;	
fun initializevectortable (initialvectable, columns, startstate2, startqrs, hexsize)=
 	let mkVectortable [initialvectable  columns  startstate2 startqrs] -> vectable in
	let mygetcoordinates startqrs -> startcoordiantes in
	let 0 -> rownumber in
	(
	set vectable.vectortable.0 = startqrs; //set the initial qrs element of the Vectortable.vectortable table, which is made of qrs objects
	let fillvectortable  startcoordiantes hexsize vectable  startstate2 rownumber -> vectable2 in
	vectable2);;
	

// fun [I I I S [I I I] returns i
fun makehexgrid (total_columns, total_rows, hexsize, startstate, startingvec)=
	let mktab total_columns nil -> initialvectable in
	let startingvec ->  [q r s] in
	let makeQRS q r s -> starqrs in
	let initializevectortable initialvectable total_columns  startstate starqrs hexsize -> vectable2 in
	let vectable2.rows -> rows in
	let mktab total_columns nil-> hexgridtable in
	let mkHexgrid [hexgridtable total_rows total_columns hexsize] -> hexgrid_object in
	(
	//set Global_hextable= hexgrid_object ;
	let 0-> column_counter in
	let 0-> column_number in
	(
	while (column_counter < total_columns) do //redo with strucs not global variables
	(
	let vectable2.vectortable.column_counter -> initialqrs in
	//make_column arguments: Hexgrid, hexlist (set at nil until function begins to resurviely, currentcolumn_number, currentrow_number, inputvec, total_row, hex size
   let make_column hexgrid_object nil column_counter 0 initialqrs total_rows hexsize -> this_column in //make_column returns tab Hex
   // load completed column (which is a table of hexes) into first element of Hexgrid.hextable
  	set hexgrid_object.hextable.column_counter = this_column;
  	set column_counter= column_counter +1;
  );
  0;
  //return a completed Hexgrid object
 hexgrid_object;
  );
  );;

fun hextablemain()=
//_showconsole;
//the number after the function call is the number of vectors in the vector table which will be the number of columns in the hex table
// fun makehexgrid: columns, rows, hexsize (vertical height for flat top), start state evens up or odds up, returns a Hexgrid object

// RIGHT BELOW IS THE FUNCTIONTHAT MAKES A GRID OF HEXES... THe PARAMETERS ARE COLUMNS (I) ROWS (I) HEXSIZE (I) QRS origin [I I I] AND "evens up" or "odds up" to determine whether odd columns are a half hex higher or even columns are a half hex higher
let makehexgrid 12 12 100 "odds up" [0 0 0] -> hexgrid in
(
//testing code below, grab a hex and print its x y coordinates
//let exec hexgrid.hextable.3.0.funhextopixel with [ hexgrid.hextable.3.0] -> [xpixel ypixel] in
//testing code, grab a column and print info for each hex in column
//exec  @printcolumn  with [0  hexgrid.columns  hexgrid.hextable.0];

mypolygonmain hexgrid; //send hexgrid to subequently loaded pagkage to draw hexes 
0);;

and this code creates a window and draws the polygons into the bitmap, bitmap.2.pkg

typeof drawwindow = ObjWin;;
typeof drawbitmap = ObjBitmap;;
proto test_point_table  = fun [Mypolygon] Mypolygon;;
proto hextablemain = fun[] I;;





struct Point =[
	x:	F,
	y:	F,
	fungetvalues: fun [Point] [F F] ///function to return x and y properties of Point
	] mkPoint;;
	

struct Mypolygon =[
numsides:			I,
center:				[F F], 	//center of polygon
sidelength:			F,
height:				F,
points:				tab Point, //table of point objects in polygon
funmakepoints:		fun [Mypolygon] tab  Point,
funmakedrawpointtable:	fun [Mypolygon] tab [I I],
strucdrawpointstable:	tab [I I], //function to create table of points to put in points table
hextype :			S,//for hexes, if "flat" then flat top, if "pointy" then pointy top
structpolygonhexheight:			F //hexheight is vertical radius if flat and norizontal radius if pointy
	
	] mkMypolygon;;//this is each individual shape that will fit into the shapetable
	
	
struct Mypolygontable = [
Mypolygontable_rows:								I,
Mypolygontable_columns: 	I,
polygontable: 					tab tab Mypolygon,
originpoint: 					[I I], //this will set the origin of the table at x 0 y height of the parent bitmap. "up" in y will be negative as y increases as you go to the bottom of the screen
totalsize: 						[F F],
funcalctotalsize: 			fun [Mypolygontable] [F F],
parentbitmap: 					ObjBitmap 
	] mkMypolygontable;;
	
	//recreate hextopixel with loadallfiles. then combine hextopixel with thi file and have one interface!
	//todo, take each element of the hextgrid, create a Mypolygon, and load the Mypolygon into a Mypolygontable
	
fun paint (win, bitmap)=
		
		_PAINTwindow drawwindow;
		_BLTbitmap  drawwindow drawbitmap 0 0;
		
	
	0;;
	
fun end (window, parameter)=
	_DSbitmap  drawbitmap;
	_DSwindow  drawwindow;
	_closemachine;
	0;;

fun createinterface ()=
	_fooS "in createinterface function";
	set drawwindow = _CRwindow _channel nil 0 0 1024 1024 WN_NORMAL "image window"; 
	
	_BLTbitmap  drawwindow drawbitmap 0 0;
	_CBwinDestroy drawwindow @end nil;
	_CBwinPaint  drawwindow @paint drawwindow;
	0;;

fun myfungetvalues(point)=
	let point.x -> x in
	let point.y -> y in
	[x y];;

fun initpoint (x, y)=
	let mkPoint [x y @myfungetvalues] -> point in
	point;;
	
fun makeflattophexpoints (polygon)=
	let (polygon.structpolygonhexheight *. 2.0)  /. (sqrt 3.0)-> float_final_size in
	(
   let 0 -> counter in
	let polygon.center -> [functionx functiony] in
   while (counter < (sizetab polygon.points)) do
   (
   if (counter == 0) then
   (
	let 0.0 -> radians in
	let functionx +. (float_final_size *. (cos radians)) -> xpoint in
	let functiony +. (float_final_size *. (sin radians)) -> ypoint in
	let initpoint xpoint ypoint -> point in
	set polygon.points.counter = point;
	set counter = counter+1;
   )
   else
   (
   
   let 60.0 *. (itof counter) -> angle_degrees in
   let (PIf /. 180.0) *. angle_degrees -> radians in
   let functionx +. (float_final_size *. (cos radians)) -> xpoint in
	let functiony +. (float_final_size *. (sin radians)) -> ypoint in
	let initpoint xpoint ypoint -> point in
	set polygon.points.counter = point;
	set counter = counter+1;
	
   );
   );
   );
   0;;

fun hexmakepoints (polygon)=
	if ((strcmp polygon.hextype "flattop")==0) then
	(

	makeflattophexpoints polygon;

)
	else if ((strcmp polygon.hextype "pointytop")==0) then
	(
	_fooS "you are making a pointytop hexagon!!!";
	0;
	)
	else
	(
	_fooS "bad input data, not flattop or pointytop!";
 	0;
	);

	polygon.points;;
	
fun trianglemakepoints (polygon) = //this is only good for a triangle
	_fooS "you are making a triangle!!!";
	let polygon.points -> pointtable in
	let polygon.center -> [centerx centery] in
	let polygon.height -> height in
	let height *. (-. 1.0) -> height in // convert positive height to negative height as negative values point "up" on the screen
	let polygon.sidelength -> sidelength in
	
	(
	//make first point at the top of the triangle, x will be the same as triangle.center's x coordinate, calculate y coordinate
	let centery +. ((2.0 *. height)/. 3.0) -> y1 in //this is y coordinate of apex of equilateral triangle
	let (initpoint  centerx y1) -> point1 in //we use centerx for x coordinate at top of triangle
	set polygon.points.0 = point1; //load first point of triangle into triangle.points table

	//make second point
	//we need sidelength for second point so get it
	let centerx -. (sidelength /. 2.0) -> secondx in
	let centery -. (height /. 3.0) -> secondy in
	let  (initpoint  secondx secondy) -> point2 in
	set polygon.points.1 = point2;//load second point of triangle into triangle.points table
 
	//make make third point
	//we need sidelength for third point so get it

	let centerx +. (sidelength /. 2.0) -> thirdx in
	let centery -. (height /. 3.0) -> thirdy in
	let  (initpoint  thirdx thirdy) -> point3 in
	set polygon.points.2 = point3; //load third point of triangle into triangle.points table
 	
	pointtable;
	);;//return completed table of the three points in the triangle



fun test_point_table (polygon)=
	let polygon.points -> pointtable in
	let sizetab pointtable -> size in
	let 0 -> counter in
	while (counter < size) do
	(
 	let polygon.points.counter -> point in
	let exec point.fungetvalues with [point]-> [x y] in
	set counter = counter + 1;
	);
	polygon;;
	
fun test_polygon_drawpoints (polygon)=
	_fooS "in test_point_table function!";
	let sizetab polygon.strucdrawpointstable -> size in
	let 0 -> counter in
	while (counter < size) do
	(
	let polygon.strucdrawpointstable.counter -> [x y] in
	set counter = counter +1;
	);
	polygon;;
	
fun create_drawpoint_table (polygon)=
let 0 -> counter in
let mktab (sizetab polygon.strucdrawpointstable) nil -> ltable in
(
while (counter < (sizetab polygon.strucdrawpointstable)) do
(
let polygon.points.counter -> point in
let exec point.fungetvalues with [point]-> [x y] in 
//let _fooS strcatn "drawpoint number: ":: (itoa counter):: " has an x of: ":: (ftoa x):: " and a y of: " :: (ftoa y):: nil -> string in
//set element.counter in ltable:
set ltable.counter  = [ (ftoi x) (ftoi y)];

set counter = counter +1;
0;
);
//return table of [I I]


ltable;
);;

fun initpolygon (hexgrid, numsides, center, sidelength, hextype, hexheight ) =
let center -> [centerx centery] in
let mktab numsides nil -> pointstable in
let mktab numsides nil -> drawpointstable in //initialize empty points table to put in polygon.points property WARNING: YOU MUST CREAT EMPTY TABLE BEFORE YOU CAN START FILLING TABLE UP WITH ELEMENTS WITH VALUES!!!!
let mkMypolygon [numsides center sidelength nil pointstable nil @create_drawpoint_table drawpointstable hextype  hexheight] -> polygon in
(
	if (numsides == 3) then // MAKE A TRIANGLE

	(
		let ((sqrt 3.0)/. 2.0) *. sidelength -> fheight in //CALCULATE HEIGHT OF TRIANGLE FROM SIDE LENGTH only works for TRIANGLES
		set polygon.height = fheight;
		set polygon.funmakepoints = @trianglemakepoints;
		trianglemakepoints polygon;
		polygon;
	) 
	else if (numsides == 6) then //MAKE A HEXAGON
	(
		
		
		
		
		set polygon.funmakepoints = @hexmakepoints;
	
		hexmakepoints polygon;
		create_drawpoint_table polygon;
		//todo: write some code to test that drawpoint table has been created
		polygon;
	)
	else
	
	(
	nil;
	);
	let create_drawpoint_table polygon -> ltable in
	(
	 set polygon.strucdrawpointstable	= ltable;
	 //let polygon.strucdrawpointstable.2 -> [xx yy] in
	//_fooS strcatn "x from polygon.strucdrawpointstable.2 is: "::(itoa xx)::" and y from polygon.strucdrawpointstable.2 is: ":: (itoa yy):: nil;		


	);
	polygon;
	);;
	
	
//return tab polygons; this only makes hexagons and polygons don't need height property and only makes polygons with six sides

fun hex_make_row_of_polygons (hexgrid, polygontable, columnnumber)= 
//get column of hexes
let hexgrid.hextable.columnnumber -> lthishexcolumn in
let (itof hexgrid.hexsize) -> lthishexsize in
let polygontable.Mypolygontable_rows -> ltotal_rows in
let mktab ltotal_rows nil -> polygon_column in
let polygontable.parentbitmap -> lthisbitmap in
let 	_GETbitmapSize lthisbitmap -> [thisbitmapx thisbitmapy] in
let 0 -> row_counter in
(
while (row_counter < ltotal_rows) do
	(
// get xy of current hex, then set frtoa x to bitmap - x, and y to bitmap y	
	let lthishexcolumn.row_counter -> this_hex in
	//get center of hex
	let this_hex.hex_xy -> [floatx floaty] in
	//set center of y to be hiehgt of polygontable's bitmap - iy
	let (itof thisbitmapy) -. floaty -> final_float_y in //this is final y coordinate of the polygon we are about to create
	//create polygon, and draw it's table of points into bitmap!
	let (itof hexgrid.hexsize) -> lthishexheight in
	let initpolygon hexgrid 6 [floatx final_float_y  ] nil "flattop" lthishexheight -> polygon in
	(
	set polygon_column.row_counter = polygon;
	// drawa polygon into the bitmap
	_DRAWpoly24 drawbitmap  (sizetab polygon.strucdrawpointstable) polygon.strucdrawpointstable DRAW_SOLID 1   0x000000 DRAW_INVISIBLE 0x99FFFF;
	set 	row_counter = row_counter +1;
	);
	);
//return  completed column, with all rows filled, into 	
	
	

	 polygon_column);;
	
fun initpolygontable (hexgrid)= //this function will load [x y] tuples from hexes in hexgrid into polygons in polygongrid. when all the polygons are created in the polygongrid and their shapes darwn into bitmap, function will blit blitmap
	//create bitmap to draw polygons into
	set drawbitmap = _CRbitmap _channel 1024 1024;
	_FILLbitmap drawbitmap 0xFFFFFF;
	let hexgrid.hexgridrows -> ptable_rows in
	let hexgrid.columns -> ptable_columns in
	//get hexgrid origin, which is center of first hex in first row and column of hexgrid
	let hexgrid.hextable.0.0.hex_xy ->[floatx floaty] in
	let (ftoi floatx) -> ioriginx in
	let (ftoi floaty) -> ioriginy in
	let mktab ptable_rows nil -> ltableofpolygons in
	let mkMypolygontable [ptable_rows ptable_columns ltableofpolygons [ioriginx ioriginy] nil nil drawbitmap] -> lpolygontable in
	let 0 -> polygontablecounter_for_column_number in
	(
	while (polygontablecounter_for_column_number < ptable_columns) do
	(
	let hex_make_row_of_polygons hexgrid lpolygontable polygontablecounter_for_column_number -> this_pcolumn in
	//inser this column, which is a table of polygons, into the ltableofpolygons
	set lpolygontable.polygontable.polygontablecounter_for_column_number = this_pcolumn;
		
	set polygontablecounter_for_column_number = polygontablecounter_for_column_number +1;
	);
	//when we are done building polygon table, blit the finalized bitmap!
	createinterface;
	);
		0;;

fun mypolygonmain (hexgrid_object)=
_showconsole;
	_fooS "calling mypolygonmain!";
_fooS strcat "we are in bitmap2 package because we have a valid hexgrid object, it has this amount of rows in its hexgridrows property: "(itoa hexgrid_object.hexgridrows);
///for a triangle, height is height from centroid to apex, for hex height is vertical radius tto flat top if flat top or to top point if pointytop
   let [256.0 256.0]-> center in
   let (itof hexgrid_object.hexsize) -> mypolygonmain_hexheihgt in
	initpolygontable hexgrid_object;
    0;;

Offline

Board footer

Powered by FluxBB