Forum Moderators: open

Message Too Old, No Replies

Help on Rotating a mulitdimensional Array

Little help on making script smaller

         

appi2

8:40 am on Mar 15, 2006 (gmt 0)

10+ Year Member



Ulloo
Any ideas on how to group these for loops and get the same results with less code. Brain hurts an I need sleep!

<html>
<head>
<title>ROTATING AN ARRAY</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<script type="text/javascript">
function loadit(){
var x="";
var y="";
var outputthis="";
var exampleArrayNumber="";
var exampleArray =[['<B>TL</B>','TR'],['BL','BR']];

outputthis +="<p>The Array TL TR BL BR</p>";
for (x=0;x<2;x++) {
for (y=0;y<2;y++) {
exampleArrayNumber = exampleArray[x][y];
outputthis +=exampleArrayNumber;
}
outputthis +="<br>";
}

outputthis +="<p>Rotated 90 degrees</p>";

for (y=0;y<2;y++) {
for (x=1;x>-1;x--) {
exampleArrayNumber = exampleArray[x][y]
outputthis +=exampleArrayNumber;
}
outputthis +="<br>";
}

outputthis +="<p>Rotated 180 degrees</p>";

for (x=1;x>-1;x--) {
for (y=1;y>-1;y--) {
exampleArrayNumber = exampleArray[x][y]
outputthis +=exampleArrayNumber;
}
outputthis +="<br>";
}

outputthis +="<p>Rotated 370 degrees</p>";

for (x=1;x>-1;x--) {
for (y=0;y<2;y++) {
exampleArrayNumber = exampleArray[y][x]
outputthis +=exampleArrayNumber;
}
outputthis +="<br>";
}
document.write(outputthis);
}
</script>
</head>

<body>
<script language="JavaScript" type="text/JavaScript">
loadit()
</script>

</body>
</html>

Bernard Marx

6:40 pm on Mar 15, 2006 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member




function loadit()
{
var sq =[['<B>TL</B>','TR'],['BL','BR']];
sq.rotate = rotateSquare;
sq.toString = squareToString;
var br = "<br>";
var output =
"<h4>The Array: [['<B>TL</B>','TR'],['BL','BR']]</h4>"
+sq;
for(var k=1;k<4;k++)
output+= "<p>Rotated "+(k*90)+" degrees</p>"
+ sq.rotate(1);
document.write(output);

}

function rotateSquare(n)
{
n=(4+~~n%4)%4;
while(n--){
this[1].push( this[0].pop() );
this[0].unshift( this[1].shift() );
}
return this;
}

function squareToString()
{
return this.join("<br>").replace(/,/g,"");
}


rotateSquare:

Argument n: number of 90 deg rotations.

Truncates non-integer values of n (using ~~n):

2.3, 2.78 become 2
-2.3, -2.78 become -2

Accepts negative n (although not demo'd here)

This is done the lazy way, using "clock arithmetic". The modulus operator, %, in Javascript (and some other languages) is inconvenient for this task, so the expression: n=(4+n%4)%4 ensures that eg -3 becomes 1.

squareToString:

When an object is used in alert or document.write etc, its toString method is called. We override this for the outer array with a custom method that produces the HTML.

It assumes, for convenience, that the actual elements do not contain any commas.

----------------------------------------------------------

It might be better to create a Square data type do all this.
The "square" methods could be inherited rather than directly attached.

appi2

2:16 am on Mar 16, 2006 (gmt 0)

10+ Year Member



Thanks for the reply .. new things to learn!

Another question. If I take the while loop out of the function rotateSquare the script still returns the same values.


function rotateSquare(n)
{
// n=(4+~~n%4)%4;
// while(n--){
this[1].push( this[0].pop() );
this[0].unshift( this[1].shift() );
//}
return this;
}

Whats the point of

 n=(4+~~n%4)%4;

sorry don't quite understand what thats actually doing. You can change the number of rotations through
 for(var k=1;k<8;k++)

And!
if the array was

 var sq =[[4,8,5,5,5,5,5,3,5],
[5,5,5,5,5,7,5,5,8],
[5,5,5,5,5,5,5,5,5],
[5,6,3,5,2,5,5,5,5],
[5,9,5,1,5,3,5,6,5],
[5,5,5,5,7,5,1,4,5],
[5,5,8,5,5,5,5,5,5],
[2,5,5,6,4,5,5,5,5],
[5,1,5,5,5,5,5,5,7]];

then .. lol .. sorry tried to make the original question as basic as possible. The above is what im tring to rotate.

I shall thank you scurry off and try and re-invent the wheel. Thanks.

Bernard Marx

9:22 am on Mar 16, 2006 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



If I take the while loop out of the function rotateSquare the script still returns the same values

Since we are only asking for one 90 degree rotation each time, the function's full abilities aren't actually used. If we did, say: rotateSquare(3) then it would make a difference if the loop were removed.

Whats the point of n=(4+~~n%4)%4

Perhaps it would be easier written as:

if(n > 0)  
n = Math.floor(n) % 4;
else if(n < 0)
n = (Math.ceil(n)%4) + 4;

1) Only use integer part of n

2) Restrict n to the range [0-3]

This is because eg:

- 5 90 deg rotations is the same as 1,

- 1 90 deg anti-clockwise rotation is the same as 3 clockwise.

And!
if the array was

Ah.. Now that will require something different.

I take it that "rotation" in this case is a physical one. The sort that would turn a 3 by 2 matrix into a 2 by 3 after a 90 degree rotation

appi2

11:22 am on Mar 16, 2006 (gmt 0)

10+ Year Member



I understand now, or rather I'll put that to one side and get back to it!

I take it that "rotation" in this case is a physical one. The sort that would turn a 3 by 2 matrix into a 2 by 3 after a 90 degree rotation

Yes although i'm only playing with arrays/matrices that are square at the moment. Just trying to do rotation then translation and finaly be able to choose each value/row/collumn and change it by some factor.
Long way to go.
Just realised I don't have to keep getting the value from the original array and should just pass it through a function that rotates 90 degrees and do that 3 times!

Thanks.

Bernard Marx

4:13 pm on Mar 16, 2006 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



This one uses some lazy techniques too. Seems to work though.


var arr =
[
["A","B","C","D"],
["D","E","F","G"],
["H","I","J","K"]
];

arr.toString = array2ToString;

array2Rotate(arr,1);
alert(arr);

/* change "\n" to "<br>" */
function array2ToString()
{
return this.join("\n").replace(/,/g,"");
}

function array2Rotate(A,n){

var nRows,nCols;
var rotate = {
1 : function(){
for(var k=0;k<nCols;k++)
A.push(columnReversed(k));
A.splice(0,nRows)
},

2: function(){
A.reverse();
for(var k=0;k<nRows;k++)
A[k].reverse();
},

3: function(){ this[1](); this[2](); }
}

function columnReversed(x){
var col = [], k=nRows;
while(k) col.push(A[--k][x]);
return col;
}
/* start */
n = (4+~~n%4)%4;
nCols = A[0].length;
nRows = A.length;

if(n) rotate[n]();
return A;
}

appi2

6:10 pm on Mar 16, 2006 (gmt 0)

10+ Year Member



Thank you thats great, going to go have a play and learn.

Just noticed
the cat sat on the
the mat in the array!

:)