Having issues with the rotation algorithm for an array-based image representation

My goal is to rotate the image represented by matrix (a) by mapping the values in the "a" coordinates to the rotated image, as shown below. However, I am puzzled as to why this method fails to produce the desired result.

a = [[1, 2, 3],
     [4, 5, 6],
     [7, 8, 9]]

// Desired output: 
//  rotateImage(a) =
//     [[7, 4, 1],
//      [8, 5, 2],
//      [9, 6, 3]]

// aCoords =  [[00,01,02],
//             [10, 11, 12],
//             [20,21,22]]

// rotatedImageCoordsRelatingToa = [[20, 10, 00],
//                                     [21, 11, 01],
//                                     [22,12,02]]

function rotateImage(a) {
const image = [...a]
const length = a.length
const rotatedImage = [...a]
for(let i=0;i<length;i++){
    for(let j=0;j<length;j++){
        let toRotateCoord = length-(1+j)
        console.log("Original coordinates:" + i,j + " should map to rotated coordinates:"+ toRotateCoord, i)
        rotatedImage[i][j] = image[toRotateCoord][i]
    }
}
return rotatedImage;
}

rotateImage(a);

Upon execution, the actual outcome differs from the expected rotation:

//[[7,4,7], 
// [8,5,4], 
// [9,4,7]]
// Instead of
//     [[7, 4, 1],
//      [8, 5, 2],
//      [9, 6, 3]]

While I understand that there may be more efficient algorithms for achieving this rotation, I am intrigued by the reasons behind the failure of this approach. It appears that the issue lies in the way the arrays are accessed.

Answer №1

Upon further investigation by Cris Luengo, it appears that using the spread operator to assign rotatedImage still references the same memory location. To resolve this issue, a for loop was added to create a new array and the problem was solved:

a = [[1, 2, 3],
     [4, 5, 6],
     [7, 8, 9]]

rotateImage(a);

function rotateImage(a) {
const image = [...a]
const length = a.length
const rotatedImage = []

for(var i = 0; i < length; i++){
        rotatedImage.push([]);
    };

for(let i=0;i<length;i++){
    for(let j=0;j<length;j++){
        let toRotateCoord = length-(1+j)
        rotatedImage[i][j] = image[toRotateCoord][i]
    }
}
return rotatedImage;
}

Answer №2

The issue lies in the fact that while rotatedImage = [...a] generates a new array, it does not produce new subarrays. Therefore, rotatedImage shares its rows with the original image array. Any changes made to rotatedImage[i][j] will impact the rows in image, influencing subsequent assignments.

To rectify this, initialize rotatedImage as follows:

const rotatedImage = Array.from({length}, _ => []);

This adjustment will solve the problem in your code.

Additionally, you can eliminate the use of the image variable since it is not being modified. Instead, simply operate on the input array a.

function rotateImage(a) {
    const length = a.length;
    const rotatedImage = Array.from({length}, _ => []);
    for (let i = 0; i < length; i++) {
        for (let j = 0; j < length; j++) {
            rotatedImage[i][j] = a[length - (1 + j)][i];
        }
    }
    return rotatedImage;
}

let a = [[1, 2, 3],
         [4, 5, 6],
         [7, 8, 9]];
let b = rotateImage(a);
for (let row of b) console.log(row+"")

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Transmit information to Vue.js component

I am encountering an issue while attempting to transfer data from one component to another. Can someone provide assistance? Below is the code snippet: <template> <div class="q-pa-md" style="max-width: 900px"> <div v-if="fields.length" ...

using javascript to initiate an ajax request

Apologies if my question seems confusing, I am currently in the process of grasping ajax, JavaScript, and jQuery. Here is my query: Below you can find a snippet of my javascript code: if (colorToCheck == gup("Player1")) { document.getElementById(&apo ...

The message sent by the node containing a large body (1.3 mb) encountered an error: 413 Request Entity Too Large

Using Fiddler, I am creating a POST message with a header. Content-Type: application/text-enriched app.post('/books',function(req,res){ var writeStream = fs.createWriteStream('C://Books.txt' ,{ flags : 'w' }); ...

Determining the total number of combinations possible from a collection of five arrays containing items

I have five massive collections filled with various strings, and each of them contains a different number of elements. Below are examples of the lists: List 1 "Jeffrey the Great", "Bean-man", "Joe", "Charles", "Flamur", "Leka", ...

The jQuery script removal functionality originated from the use of ajax

I have adapted a nested modal script (jQueryModal) to better suit the project's requirements, but I've encountered an unusual issue that I can't seem to resolve. When I invoke the modal to load some content via ajax, and the response from t ...

Header Stability TransitionAndView

I'm not very experienced with JavaScript, so please bear with me. I'm attempting to create a fixed header that transitions to 50% opacity when scrolled down and returns to full opacity (opacity: 1.0) when scrolled back to the top. Here is my cur ...

The use of the keyword 'await' was not anticipated

I'm currently working on a react-native application and I've encountered an issue with my forEach iteration. I decided to use await to pause for the result, but instead I keep receiving an error message stating "Unexpected reserved word 'awa ...

Issue with integrating PHP code within JavaScript: Unable to execute

<script> document.getElementById("comment").innerHTML="<?php echo 'hello world'; ?>"; </script> <div id="comment"></div> Even though the code above should display "hello world" in the div element, it's not wor ...

Passing onClick event to parent component during iteration in ReactJS

I am facing a challenge where I need to remove a row from a table upon a click event. I have managed to create an iteration and display a delete button, but I am struggling with passing the onClick event from the parent component to the child component in ...

Is it possible that .focus() does not function on a duplicated object?

Greetings to all! I have created a form with rows of input text fields. Users can add as many rows as needed by clicking the 'add row' button. The functionality to clone() for adding rows is working perfectly. In each row, an input field can o ...

Navigating through a multistep form in AngularJS using UI Router and arrow keys for seamless movement

Is there a way to navigate to the next or previous form step using arrow keys in AngularJS UI Router? The code provided below is currently allowing navigation with previous and next buttons. .config(function($stateProvider, $urlRouterProvider) { $stat ...

Top strategies for ensuring integrity in your frontend React game and preventing cheating

After creating a typing speed game, I am now looking to set up a backend system that can save user high scores and generate a leaderboard. However, I'm concerned about potential users faking their highscores. How can I ensure the integrity of the lead ...

Is there a way to extract data from a JavaScript file using .NET programming?

Looking for a way to extract data from a JavaScript file using .NET. Consider the following URL: http://..../xml/en/file_1.js The content of the .js file is as follows: getdate(20140802,'','','',10,5); getdate(20140802,&ap ...

Interacting with JSON data using Angular UI-Router

My goal is to create a Single Page Website that relies on a CMS to store and serve JSON data through Ajax requests. I am using ui-router (previously attempted with ngRoute) within my ng-app to handle this data. The challenge I am facing is how to display t ...

"Create a smooth transition effect in CSS by fading out one div and fading in

I've set up a grid of buttons, and my goal is to have the grid fade out when a button is clicked, then fade in with a new div in its place. This involves animating opacity from 1 to 0 and vice versa while toggling the display:none property for content ...

React Bootstrap always displays tooltips

I have integrated react-bootstrap into my project. I am currently attempting to keep a tooltip always displayed, but I am facing some challenges in achieving this. Below are the approaches I have tried so far: <Card style={{width: '10rem'}} ...

Issue: (SystemJS) XHR error (404) encountered in Angular2 Plnkrsandbox

The issue: https://i.sstatic.net/jUKBU.png https://plnkr.co/edit/910M73kwYKc8xPlSIU57?p=preview index <!DOCTYPE html> <html> <head> <base href="/"> <title>Angular 2.1.2 + TypeScript Starter Kit</title> <met ...

Localhost is unable to process AngularJS routes containing a dot in the URL

When using the route provider and setting this specific route: .when('/:name/:id', { It successfully navigates to my desired path and executes the code when I enter: https://localhost.myapp.com:9000/Paul/123 However, it fails to work with this ...

I'm puzzled as to why there is a blank space in the false element statements

Hey there! I'm noticing a blank space on the page, and when I inspect it, I see this bindings={ "ng-reflect-ng-if": "false" }. It seems like I am getting some blank cards displayed. Here is an image showing what I mean: https://i. ...

How can the value of a number in Angular be changed without altering its original value?

Imagine having the initial number 100. If I enter 50 in another input, it should add 50 to 100. However, if I then change the value from 50 to 80, the total should be 180 and not 230. The goal is always to add numbers to the original sum, not the new valu ...