2

I have a program where I can make an ellipse gradient such as this: enter image description here

But that's not enough for me I need more than 1. So when I try to make for example 3 gradients, and they collide with each other this is the result: enter image description here

But I expect this (made in photoshop) enter image description here

Clearly, something is wrong with the way I merge the layers there.

Here is the source code.

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;

namespace Gradients {

    static class Gradient {

        public static Bitmap GetGradient() {
            Random random = new Random();
            Bitmap image = new Bitmap(300, 300);
            int size = 300;

            double[,] colorValue = new double[300, 300];

            int amount = 3;

            for (int x = 0; x < size; x++) {
                for (int y = 0; y < size; y++) {
                    colorValue[x, y] = 1;
                }
            }
            for (int i = 0; i < amount; i++) {

                int centerX = random.Next(size / 10 - 1, size - (size / 10 - 1));
                int centerY = random.Next(size / 10 - 1, size - (size / 10 - 1));

                for (int x = 0; x < size; x++) {
                    for (int y = 0; y < size; y++) {

                        double distanceX = (centerX - x) * (centerX - x);
                        double distanceY = (centerY - y) * (centerY - y);

                        double distanceToCenter = Math.Sqrt(distanceX + distanceY) * 5;

                        distanceToCenter /= size;
                        if (distanceToCenter > 1)
                            distanceToCenter = 1;
                        if (distanceToCenter < 0)
                            distanceToCenter = 0;

                        double number = 1 - distanceToCenter; // inverting number range from 1-0 to 0-1
                        colorValue[x, y] -= number;
                        if (colorValue[x, y] < 0)
                            colorValue[x,y] = 0;
                    }
                }
            }


            for (int x = 0; x < size; x++) {
                for (int y = 0; y < size; y++) {
                    int cValue = Convert.ToInt32(colorValue[x, y] * 255);
                    image.SetPixel(x, y, Color.FromArgb(cValue, 0, 0, 0));
                }
            }

            return image;
        }

        // euclidean distance
        private static double getDistance(int x1, int y1, int x2, int y2) {
            return Math.Sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
        }
    }
}
Marat Isaw
  • 131
  • 3
  • 10
  • Why not using `PathGradeintBrush`? – Reza Aghaei Aug 08 '18 at 20:09
  • 1
    With multiple overlapping object, this may become somewhat more complicated. You (probably) need a [Voroni](https://en.wikipedia.org/wiki/Voronoi_diagram) distribution (to register each region's associated pixels. I would change the Euclidean distance with [TaxiCab](https://en.wikipedia.org/wiki/Taxicab_geometry) (Manhattan). Similar, but in this case it might get better results (I think). Then you need to manage pixels collisions (that's where the Voroni diagram will help). First of all you need to substitute `SetPixel()` with `Bitmap.LockBits()` & Co., or this will become a pain. – Jimi Aug 08 '18 at 20:36
  • @RezaAghaei I can use that if I draw them, but I actually don't need to draw the gradients but get the values. I am using this as a Mask. – Marat Isaw Aug 08 '18 at 21:09
  • @Jimi Thanks for your suggestion. I tried using Manhattan instead of Euclidean, didn't really change much. And what would Voroni (a new topic for me) change? I don't know anything about Voroni, isn't there a simpler way? – Marat Isaw Aug 08 '18 at 21:09
  • No, in your context (because of how the code performs at this time) Manhattan or Euclidean won't change anything (or make anything better). If you have multiple overlapping object that need to *blend* in a visually pleasing way, you must manage pixels collisions. A Voronoi diagram helps you to keep track of pixels regions. This is a very broad subject. You need to break it down, piece by piece. Start with using [Bitmap.LockBits()](https://msdn.microsoft.com/en-us/library/5ey6h79d%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396) for setting the values. Many examples for this. – Jimi Aug 08 '18 at 21:19
  • A quick Google search on the terms used here, gave back (among the others) this link: [Stained Glass Image Filter](https://softwarebydefault.com/tag/image-gradient/). Here, a Voronoi (which I wrote wrong, twice) diagram is implemented in a quite simple way. Also, both the Euclidean and Manhattan distances are considered (+ Chebyshev). I might be interenting for you. – Jimi Aug 08 '18 at 21:30
  • 1
    Do have a look at [this post](https://stackoverflow.com/questions/30415191/heatmap-style-gradients-in-net/30416635?s=1|59.8013#30416635) which does the very same but with colors and for a heat map. – TaW Aug 09 '18 at 13:05

0 Answers0