Posted in

How to draw a Voronoi diagram on a Canvas?

Hey there, art enthusiasts and fellow tech lovers! I’m super stoked to share this in – depth guide on how to draw a Voronoi diagram on a Canvas. And a little about me, I’m from a Canvas supplier, and I’ve been on this amazing journey exploring the countless possibilities of Canvas. Canvas

What’s a Voronoi Diagram Anyway?

Before we jump into the nitty – gritty of drawing, let’s quickly chat about what a Voronoi diagram is. It’s a really cool mathematical construct that divides a plane into regions based on the distance to a set of points. Each region, or cell, is made up of all the points that are closer to a specific "seed" point than to any other. Think of it like a bunch of neighborhoods, where each house belongs to the neighborhood whose center (the seed point) is closest.

Voronoi diagrams have a ton of real – world applications. You can see them in things like mapping out cell phone tower coverage areas, analyzing crystal growth patterns, and even in cool graphic designs.

Why Use Canvas?

Canvas is the bomb when it comes to creating graphics on the web. It’s super flexible and gives you direct control over every single pixel on the screen. Unlike SVG, which is more about defining shapes with XML, Canvas is all about painting and drawing dynamically. You can animate, change colors on the fly, and create some seriously eye – popping visual effects.

As a Canvas supplier, I’ve seen firsthand how it can take a simple web page and turn it into a visual masterpiece. Whether you’re a web developer looking to add some flair to your site or an artist wanting to showcase your work online, Canvas has got you covered.

Getting Started

First things first, you need to set up your HTML file. Create a basic HTML structure with a <canvas> element. Here’s a quick example:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF - 8">
    <meta name="viewport" content="width=device - width, initial - scale=1.0">
    <title>Voronoi Diagram on Canvas</title>
</head>

<body>
    <canvas id="myCanvas" width="800" height="600"></canvas>
    <script src="script.js"></script>
</body>

</html>

In this code, we’ve set up a canvas with an ID of myCanvas and given it a width of 800 pixels and a height of 600 pixels. The script.js file is where we’ll write all our JavaScript code to draw the Voronoi diagram.

Generating Seed Points

The next step is to generate some seed points. These are the points that will define the regions of our Voronoi diagram. You can generate them randomly within the bounds of the canvas.

// Get the canvas element and its 2D context
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');

// Number of seed points
const numPoints = 20;

// Array to store the seed points
const points = [];

// Generate random points within the canvas bounds
for (let i = 0; i < numPoints; i++) {
    const x = Math.random() * canvas.width;
    const y = Math.random() * canvas.height;
    points.push({ x, y });
}

In this code, we first get the canvas element and its 2D context. Then we decide on the number of seed points we want (in this case, 20). We create an empty array to store the points and then use a for loop to generate random x and y coordinates within the canvas bounds. Each point is an object with x and y properties, and we push these objects into the points array.

Calculating Voronoi Regions

Now comes the tricky part – calculating the Voronoi regions. There are a few algorithms out there to do this, but one of the most common is the Fortune’s algorithm. However, for simplicity, we’ll use a brute – force approach that works well for a small number of points.

The idea behind the brute – force approach is to loop through every pixel on the canvas and calculate the distance to each seed point. The pixel will then belong to the region of the closest seed point.

// Loop through every pixel on the canvas
for (let x = 0; x < canvas.width; x++) {
    for (let y = 0; y < canvas.height; y++) {
        let minDistance = Infinity;
        let closestPointIndex = 0;

        // Calculate the distance to each seed point
        for (let i = 0; i < points.length; i++) {
            const dx = x - points[i].x;
            const dy = y - points[i].y;
            const distance = Math.sqrt(dx * dx + dy * dy);

            if (distance < minDistance) {
                minDistance = distance;
                closestPointIndex = i;
            }
        }

        // Set the color based on the closest seed point
        ctx.fillStyle = getColorForPoint(closestPointIndex);
        ctx.fillRect(x, y, 1, 1);
    }
}

// Function to get a color for each seed point
function getColorForPoint(index) {
    const colors = [
        'red', 'blue', 'green', 'yellow', 'orange', 'purple',
        'pink', 'brown', 'cyan', 'magenta'
    ];
    return colors[index % colors.length];
}

In this code, we have two nested for loops to iterate through every pixel on the canvas. For each pixel, we calculate the distance to each seed point using the Pythagorean theorem. We keep track of the minimum distance and the index of the closest seed point.

The getColorForPoint function is used to assign a color to each Voronoi region. It simply cycles through an array of colors based on the index of the closest seed point. Then we use ctx.fillRect to fill each pixel with the appropriate color.

Adding Some Style

Our Voronoi diagram looks pretty basic right now. Let’s add some style to make it stand out. We can add outlines to the regions, change the colors, or even add some transparency.

// Draw outlines for each region
for (let x = 0; x < canvas.width; x++) {
    for (let y = 0; y < canvas.height; y++) {
        let minDistance = Infinity;
        let closestPointIndex = 0;

        // Calculate the distance to each seed point
        for (let i = 0; i < points.length; i++) {
            const dx = x - points[i].x;
            const dy = y - points[i].y;
            const distance = Math.sqrt(dx * dx + dy * dy);

            if (distance < minDistance) {
                minDistance = distance;
                closestPointIndex = i;
            }
        }

        // Check if the pixel is on the border
        if (isBorderPixel(x, y, closestPointIndex)) {
            ctx.strokeStyle = 'black';
            ctx.beginPath();
            ctx.moveTo(x, y);
            ctx.lineTo(x + 1, y);
            ctx.stroke();
        }
    }
}

// Function to check if a pixel is on the border
function isBorderPixel(x, y, closestPointIndex) {
    const neighbors = [
        { dx: -1, dy: 0 }, { dx: 1, dy: 0 },
        { dx: 0, dy: -1 }, { dx: 0, dy: 1 }
    ];

    for (let i = 0; i < neighbors.length; i++) {
        const nx = x + neighbors[i].dx;
        const ny = y + neighbors[i].dy;

        if (nx >= 0 && nx < canvas.width && ny >= 0 && ny < canvas.height) {
            let minDistanceNeighbor = Infinity;
            let closestPointIndexNeighbor = 0;

            // Calculate the distance to each seed point for the neighbor pixel
            for (let j = 0; j < points.length; j++) {
                const dx = nx - points[j].x;
                const dy = ny - points[j].y;
                const distance = Math.sqrt(dx * dx + dy * dy);

                if (distance < minDistanceNeighbor) {
                    minDistanceNeighbor = distance;
                    closestPointIndexNeighbor = j;
                }
            }

            if (closestPointIndexNeighbor!== closestPointIndex) {
                return true;
            }
        }
    }

    return false;
}

The isBorderPixel function checks if a pixel is on the border of a Voronoi region. It does this by looking at the neighboring pixels and comparing the closest seed points. If the closest seed point of a neighbor is different from the current pixel, then the current pixel is on the border. We then draw a black stroke to outline the region.

Wrapping Up and Reaching Out

Drawing a Voronoi diagram on a Canvas is a super fun and rewarding project. It combines math, art, and web development all in one. And as a Canvas supplier, I know how important it is to have the right tools and resources to bring your creative ideas to life.

Embroidery Fabric If you’re interested in using high – quality Canvas for your projects, whether it’s for this Voronoi diagram or something else entirely, I’d love to chat with you. We offer a wide range of Canvas options that are perfect for both small – scale personal projects and large – scale commercial applications. Don’t hesitate to reach out and start a conversation about your needs!

References

  • "HTML5 Canvas Deep Dive" by Steve Fulton and Jeff Fulton.
  • "JavaScript: The Definitive Guide" by David Flanagan.

Shandong Shengrun Textile Co., Ltd.
With over 15 years of experience, Shandong Shengrun Textile Co., Ltd. is one of the most professional canvas manufacturers and suppliers in China. Please rest assured to buy or wholesale durable canvas in stock here from our factory.
Address: 9th Floor, Hui Ji Business Tower, Ren Cheng District, Ji Ning, Shan Dong, China
E-mail: liang@shengrungroup.com
WebSite: https://www.shengruntextile.com/