ChatGPT: Attempt to Create a Mandelbrot Set Display with Zoom Functionality

Background

ChatGPT is an advanced conversational model trained through Reinforcement Learning from Human Feedback (RLHF). This tool is currently available to the public and has garnered the attention of millions of users mainly for its ability to provide accurate and creative responses. However, there are many examples of obvious shortcomings of the chatbot. This exercise is outlines one interaction I had with ChatGPT which shows both its incredible ability and some areas which require improvement.

To learn more about ChatGPT, visit the OpenAI ChatGPT Blog.

Input/Output

The following is the prompt I provided to ChatGPT: "Write JavaScript to display the Mandelbrot Set on a webpage with the ability to zoom into the the image wherever a user clicks."

Below is the entire script which was generated by ChatGPT.

// Set up canvas
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");

// Set up image data and buffer
const imgData = ctx.createImageData(canvas.width, canvas.height);
const buffer = new ArrayBuffer(imgData.data.length);
const data = new Uint8ClampedArray(buffer);

// Set up constants
const panX = -0.5;
const panY = 0;
const zoom = 1;
const maxIter = 256;

// Set up color gradient
const gradient = [];
for (let i = 0; i < maxIter; i++) {
  gradient.push([i / maxIter * 255, i / maxIter * 255, i / maxIter * 255]);
}

// Generate Mandelbrot set
function generateMandelbrot() {
  for (let x = 0; x < canvas.width; x++) {
    for (let y = 0; y < canvas.height; y++) {
      // Convert canvas coordinates to complex plane coordinates
      const cRe = (x - canvas.width / 2) * 4 / canvas.width / zoom + panX;
      const cIm = (y - canvas.height / 2) * 4 / canvas.height / zoom + panY;

      // Iterate function
      let zRe = cRe, zIm = cIm;
      let i;
      for (i = 0; i < maxIter; i++) {
        const zRe2 = zRe * zRe, zIm2 = zIm * zIm;
        if (zRe2 + zIm2 > 4) break;
        zIm = 2 * zRe * zIm + cIm;
        zRe = zRe2 - zIm2 + cRe;
      }

      // Calculate pixel color
      if (i === maxIter) {
        data[(x + y * canvas.width) * 4] = 0;
        data[(x + y * canvas.width) * 4 + 1] = 0;
        data[(x + y * canvas.width) * 4 + 2] = 0;
        data[(x + y * canvas.width) * 4 + 3] = 255;
      } else {
        const color = gradient[i];
        data[(x + y * canvas.width) * 4] = color[0];
        data[(x + y * canvas.width) * 4 + 1] = color[1];
        data[(x + y * canvas.width) * 4 + 2] = color[2];
        data[(x + y * canvas.width) * 4 + 3] = 255;
      }
    }
  }

  // Update canvas with new data
  imgData.data.set(data);
  ctx.putImageData(imgData, 0, 0);
}

// Zoom function
function zoomIn(event) {
  const rect = canvas.getBoundingClientRect();
  const x = event.clientX - rect.left;
  const y = event.clientY - rect.top;

  // Calculate new panX and panY values
  panX += (

Analysis

The output generated by ChatGPT is mostly correct but was unable to provide a working function for the zoom functionality. The generateMandelbrot() function will generate an image of the Mandelbrot Set when called, but as can be seen in the zoomIn(event) function, the code is incomplete. The response is inexplicably cut-off.

In my experience with the tool, incomplete responses are not uncommon, especially when the user input becomes more complex. What is unique about this scenario is that it is not complexity of my input (the input is not so complex anyway) that is leading to be the limitation in ChatGPT's ability to understand the request. The limitation appears to lie within its ability to create a complete method to execute zoom functionality.

I suspect the failure may be related to the tool choosing to use constants where modifiable variables are required. The panX, panY, and zoom constants must be modifiable to enable any sort of zoom feature. Therefore, it seems that the tool stops generating output when it recognizes that it is attempting to update a constant variable (panX). As the tool is not desgigned to go back and refactor responses in case of such issues arising, the response remained incomplete. Curiously, there was no error reported by the tool despite ChatGPT clearly recognizing an issue when generating the response.

ChatGPT Output

Seen below is the image created from the unaltered code provided by ChatGPT. To integrate the JavaScript with this page I simply created a canvas object and called the generateMandelbrot() method. This is a static image and there is no event handler to handle any user click events.

Updated ChatGPT Script

Seen below is my version of the completed zoom function. Note, this change also required refactoring const variables to modifiable variables to allow for changes to the zoom factor and graphical center coordinates. I also implemented the event handler that would pass the click event with the selected coordinates to the zoomIn() function.


// Zoom function
function zoomIn(event) {
  const rect = canvasupdated.getBoundingClientRect();
  const x = event.clientX - rect.left;
  const y = event.clientY - rect.top;

  // Calculate new panX and panY values based on user click location
  panX = (x - canvasupdated.width / 2) * 4 / canvasupdated.width / zoom + panX;
  panY = (y - canvasupdated.height / 2) * 4 / canvasupdated.height / zoom + panY;
  
  // Update the zoom factor and regenerate the image
  zoom = zoom * 2;
  generateMandelbrot();
  
  }
The completed Mandelbrot canvas image with zoom functionality enabled is displayed below. Simply clicking on a point anywhere in the canvas will result in a regenerated imaged with the zoom factor increased by 2 at the selected location.