සියලුම වර්ණ සහිත රූප


434

Allrgb.com හි ඇති පින්තූර වලට සමානව , එක් එක් පික්සෙල් අද්විතීය වර්ණයක් ඇති රූප සාදන්න (කිසිදු වර්ණයක් දෙවරක් භාවිතා නොකරන අතර කිසිදු වර්ණයක් අතුරුදහන් නොවේ).

එවැනි රූපයක් ජනනය කරන වැඩසටහනක්, ප්‍රතිදානයේ තිර රුවක් හෝ ගොනුවක් සමඟ දෙන්න (PNG ලෙස උඩුගත කරන්න).

  • රූපය තනිකරම ඇල්ගොරිතමයෙන් සාදන්න.
  • රූපය 256 × 128 විය යුතුය (නැතහොත් තිර රුවක් තබා 256 × 128 දී සුරැකිය හැකි ජාලකය)
  • සියලු බිට් 15 වර්ණ භාවිතා කරන්න *
  • බාහිර ආදානය සඳහා අවසර නැත (වෙබ් විමසුම්, URL හෝ දත්ත සමුදායන් ද නොමැත)
  • කාවැද්දූ පින්තූර සඳහා අවසර නැත (රූපයක් වන ප්‍රභව කේතය හොඳයි, උදා: පීට් )
  • වියළීමට අවසර ඇත
  • මෙය කෙටි කේත තරඟයක් නොවේ, එය ඔබට ඡන්ද ලබා ගත හැකි වුවද.
  • ඔබ සැබවින්ම අභියෝගයකට සූදානම් නම්, 512 × 512, 2048 × 1024 හෝ 4096 × 4096 (බිටු 3 ක වර්ධක වලින්) කරන්න.

ලකුණු ලබා ගැනීම ඡන්දයෙන්. වඩාත්ම අලංකාර කේතය සහ / හෝ රසවත් ඇල්ගොරිතම මගින් සාදන ලද ලස්සනම රූප සඳහා ඡන්දය දෙන්න.

පියවර දෙකක ඇල්ගොරිතම, ඔබ මුලින්ම ලස්සන රූපයක් ජනනය කර පසුව ලබා ගත හැකි එක් වර්ණයකට සියලු පික්සෙල් වලට ගැලපෙන අතර, ඇත්ත වශයෙන්ම අවසර දී ඇත, නමුත් ඔබට අලංකාර ලකුණු ලබා ගත නොහැක.

* බිට් 15 වර්ණ යනු රතු 32 ක්, හරිතයන් 32 ක් සහ බ්ලූස් 32 ක් මිශ්‍ර කිරීමෙන් සෑදිය හැකි වර්ණ 32768 වන අතර ඒවා සියල්ලම සමාන පියවරයන් හා සමාන පරාසයන්ගෙන් යුක්ත වේ. උදාහරණය: බිටු රූප 24 කින් (නාලිකාවකට බිට් 8), එක් නාලිකාවක පරාසය 0..255 (හෝ 0..224) වේ, එබැවින් එය සමාන පරතරයකින් යුත් සෙවන 32 කට බෙදන්න.

ඉතා පැහැදිලිව කිවහොත්, පික්සෙල් වල අනුපිළිවෙල ප්‍රේරණයක් විය යුතුය, මන්ද හැකි සෑම රූපයකම එකම වර්ණ ඇත, විවිධ පික්සල් ස්ථානවල. මම මෙහි සුළු ප්‍රේරණයක් දෙන්නෙමි, එය කිසිසේත් සුන්දර නොවේ:

ජාවා 7

import java.awt.image.BufferedImage;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import javax.imageio.ImageIO;

public class FifteenBitColors {
    public static void main(String[] args) {
        BufferedImage img = new BufferedImage(256, 128, BufferedImage.TYPE_INT_RGB);

        // Generate algorithmically.
        for (int i = 0; i < 32768; i++) {
            int x = i & 255;
            int y = i / 256;
            int r = i << 3 & 0xF8;
            int g = i >> 2 & 0xF8;
            int b = i >> 7 & 0xF8;
            img.setRGB(x, y, (r << 8 | g) << 8 | b);
        }

        // Save.
        try (OutputStream out = new BufferedOutputStream(new FileOutputStream("RGB15.png"))) {
            ImageIO.write(img, "png", out);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

රූප විස්තරය මෙහි ඇතුළත් කරන්න

ජයග්රාහකයා

දින 7 අවසන් වී ඇති නිසා, මම ජයග්‍රාහකයෙකු ප්‍රකාශ කරමි

කෙසේ වෙතත්, කිසිසේත්, මෙය අවසන් යැයි සිතන්න. මම සහ සියලු පා readers කයින් සෑම විටම වඩා පුදුමාකාර නිර්මාණ සාදරයෙන් පිළිගනිමු. නිර්මාණය කිරීම නවත්වන්න එපා.

ජයග්‍රාහකයා: ඡන්ද 231 ක් සමඟ ෆෙජෙස්ජෝකෝ


8
"වියළීමට අවසර ඇත" යැයි ඔබ කියන විට, ඔබ අදහස් කරන්නේ කුමක්ද? "එක් එක් පික්සෙල් අද්විතීය වර්ණයක්" යන රීතියට මෙය ව්‍යතිරේකයක්ද? එසේ නොවේ නම්, වෙනත් ආකාරයකින් තහනම් කර ඇති දේට ඔබ ඉඩ දෙන්නේ කුමක් ද?
පීටර් ටේලර්

1
එයින් අදහස් කරන්නේ ඔබට රටාවකට වර්ණ තැබිය හැකි බැවින් ඇසෙන් බැලූ විට ඒවා වෙනත් වර්ණයකට මිශ්‍ර වන බවයි. උදාහරණයක් ලෙස, allRGB පිටුවේ “පැහැදිලිවම සියලු RGB” රූපය බලන්න, සහ තවත් බොහෝ අය එහි සිටිති.
මාර්ක් ජෙරොනිමස්

8
ඔබේ සුළු ප්‍රේරණ උදාහරණය ඇසට ප්‍රියජනක බව මට පෙනේ.
ජේසන් සී

2
Om සොම්-බී මෑන්, මම මේ පෝස්ටයට කැමතියි. ස්තූතියි!
ජේසන් සී

7
ලස්සන ප්‍රති results ල / පිළිතුරු!
ඊතන් බී

Answers:


538

සී #

මම අහඹු පික්සෙල් එකක් මැදට දමා, අහඹු පික්සෙල් අසල්වැසි ප්‍රදේශයකට දැමීමට පටන් ගනිමි. මාතයන් දෙකක් සඳහා සහය දක්වයි: අවම තේරීමක් සහිතව, වරකට සලකා බලනු ලබන්නේ එක් අසල්වැසි පික්සෙල් පමණි; සාමාන්‍ය තේරීම සමඟ, සියල්ලම (1..8) සාමාන්‍යය වේ. අවම තේරීම තරමක් is ෝෂාකාරී ය, සාමාන්‍ය තේරීම ඇත්ත වශයෙන්ම වඩා බොඳ ය, නමුත් දෙකම ඇත්ත වශයෙන්ම සිතුවම් මෙන් පෙනේ. සමහර සංස්කරණය කිරීමෙන් පසුව, වර්තමාන, තරමක් ප්‍රශස්තිකරණය කළ අනුවාදය මෙන්න (එය සමාන්තර සැකසුම් පවා භාවිතා කරයි!):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Drawing;
using System.Drawing.Imaging;
using System.Diagnostics;
using System.IO;

class Program
{
    // algorithm settings, feel free to mess with it
    const bool AVERAGE = false;
    const int NUMCOLORS = 32;
    const int WIDTH = 256;
    const int HEIGHT = 128;
    const int STARTX = 128;
    const int STARTY = 64;

    // represent a coordinate
    struct XY
    {
        public int x, y;
        public XY(int x, int y)
        {
            this.x = x;
            this.y = y;
        }
        public override int GetHashCode()
        {
            return x ^ y;
        }
        public override bool Equals(object obj)
        {
            var that = (XY)obj;
            return this.x == that.x && this.y == that.y;
        }
    }

    // gets the difference between two colors
    static int coldiff(Color c1, Color c2)
    {
        var r = c1.R - c2.R;
        var g = c1.G - c2.G;
        var b = c1.B - c2.B;
        return r * r + g * g + b * b;
    }

    // gets the neighbors (3..8) of the given coordinate
    static List<XY> getneighbors(XY xy)
    {
        var ret = new List<XY>(8);
        for (var dy = -1; dy <= 1; dy++)
        {
            if (xy.y + dy == -1 || xy.y + dy == HEIGHT)
                continue;
            for (var dx = -1; dx <= 1; dx++)
            {
                if (xy.x + dx == -1 || xy.x + dx == WIDTH)
                    continue;
                ret.Add(new XY(xy.x + dx, xy.y + dy));
            }
        }
        return ret;
    }

    // calculates how well a color fits at the given coordinates
    static int calcdiff(Color[,] pixels, XY xy, Color c)
    {
        // get the diffs for each neighbor separately
        var diffs = new List<int>(8);
        foreach (var nxy in getneighbors(xy))
        {
            var nc = pixels[nxy.y, nxy.x];
            if (!nc.IsEmpty)
                diffs.Add(coldiff(nc, c));
        }

        // average or minimum selection
        if (AVERAGE)
            return (int)diffs.Average();
        else
            return diffs.Min();
    }

    static void Main(string[] args)
    {
        // create every color once and randomize the order
        var colors = new List<Color>();
        for (var r = 0; r < NUMCOLORS; r++)
            for (var g = 0; g < NUMCOLORS; g++)
                for (var b = 0; b < NUMCOLORS; b++)
                    colors.Add(Color.FromArgb(r * 255 / (NUMCOLORS - 1), g * 255 / (NUMCOLORS - 1), b * 255 / (NUMCOLORS - 1)));
        var rnd = new Random();
        colors.Sort(new Comparison<Color>((c1, c2) => rnd.Next(3) - 1));

        // temporary place where we work (faster than all that many GetPixel calls)
        var pixels = new Color[HEIGHT, WIDTH];
        Trace.Assert(pixels.Length == colors.Count);

        // constantly changing list of available coordinates (empty pixels which have non-empty neighbors)
        var available = new HashSet<XY>();

        // calculate the checkpoints in advance
        var checkpoints = Enumerable.Range(1, 10).ToDictionary(i => i * colors.Count / 10 - 1, i => i - 1);

        // loop through all colors that we want to place
        for (var i = 0; i < colors.Count; i++)
        {
            if (i % 256 == 0)
                Console.WriteLine("{0:P}, queue size {1}", (double)i / WIDTH / HEIGHT, available.Count);

            XY bestxy;
            if (available.Count == 0)
            {
                // use the starting point
                bestxy = new XY(STARTX, STARTY);
            }
            else
            {
                // find the best place from the list of available coordinates
                // uses parallel processing, this is the most expensive step
                bestxy = available.AsParallel().OrderBy(xy => calcdiff(pixels, xy, colors[i])).First();
            }

            // put the pixel where it belongs
            Trace.Assert(pixels[bestxy.y, bestxy.x].IsEmpty);
            pixels[bestxy.y, bestxy.x] = colors[i];

            // adjust the available list
            available.Remove(bestxy);
            foreach (var nxy in getneighbors(bestxy))
                if (pixels[nxy.y, nxy.x].IsEmpty)
                    available.Add(nxy);

            // save a checkpoint
            int chkidx;
            if (checkpoints.TryGetValue(i, out chkidx))
            {
                var img = new Bitmap(WIDTH, HEIGHT, PixelFormat.Format24bppRgb);
                for (var y = 0; y < HEIGHT; y++)
                {
                    for (var x = 0; x < WIDTH; x++)
                    {
                        img.SetPixel(x, y, pixels[y, x]);
                    }
                }
                img.Save("result" + chkidx + ".png");
            }
        }

        Trace.Assert(available.Count == 0);
    }
}

256x128 පික්සල, මැද සිට ආරම්භ කිරීම, අවම තේරීම:

ඉහළ වම් කෙළවරේ සිට ආරම්භ වන පික්සල් 256x128, අවම තේරීම:

පික්සල් 256x128, මැද සිට ආරම්භ කිරීම, සාමාන්‍ය තේරීම:

අවම සහ සාමාන්‍ය තේරීම ක්‍රියා කරන ආකාරය පෙන්වන රාමු 10 කින් යුත් සජීවීකරණ දෙකක් මෙන්න (වර්ණ 256 කින් පමණක් එය ප්‍රදර්ශනය කිරීමට හැකිවීම සඳහා gif ආකෘතියට ප්‍රශංසාව):

අවම තේරීමේ මාදිලිය කුඩා තරංග මුහුණතකින්, බ්ලොබ් එකක් මෙන් වර්ධනය වන අතර, එය යන විට සියලු පික්සල් පුරවයි. කෙසේ වෙතත්, සාමාන්‍ය මාදිලියේදී, එකිනෙකට යාබදව විවිධ වර්ණ අතු දෙකක් වැඩීමට පටන් ගත් විට, කුඩා කළු පරතරයක් ඇති වනු ඇත, මන්ද කිසිවක් වෙනස් වර්ණ දෙකකට ආසන්න නොවන බැවිනි. එම හිඩැස් නිසා, තරංග පෙරමුණ විශාලත්වයේ අනුපිළිවෙලක් වනු ඇත, එබැවින් ඇල්ගොරිතම එතරම් මන්දගාමී වනු ඇත. නමුත් එය වැඩෙන කොරල් මෙන් පෙනෙන නිසා එය හොඳයි. මම සාමාන්‍ය මාදිලිය අතහරින්නේ නම්, එය ටිකක් වේගවත් කළ හැකිය, මන්ද සෑම නව වර්ණයක්ම පවතින එක් එක් පික්සෙල් සමඟ 2-3 වතාවක් සංසන්දනය කර ඇත. එය ප්‍රශස්තිකරණය කිරීමට වෙනත් ක්‍රම මා දකින්නේ නැත, එය ප්‍රමාණවත් තරම් හොඳ යැයි මම සිතමි.

විශාල ආකර්ෂණය, මෙන්න පික්සල් 512x512 විදැහුම්කරණය, මැද ආරම්භය, අවම තේරීම:

මට මේ සමඟ සෙල්ලම් කිරීම නතර කළ නොහැක! ඉහත කේතය තුළ වර්ණ අහඹු ලෙස වර්ග කර ඇත. අපි කිසිසේත් වර්ග නොකරන්නේ නම් හෝ වර්ණ ( (c1, c2) => c1.GetHue().CompareTo(c2.GetHue())) අනුව වර්ග කරන්නේ නම් , අපට මේවා පිළිවෙලින් ලැබේ (මැද ආරම්භය සහ අවම තේරීම යන දෙකම):

කොරල් ස්වරූපය අවසානය දක්වා තබා ඇති තවත් සංයෝජනයක්: සාමාන්‍ය වරණයකින් වර්ණ ඇණවුම් කර, රාමු 30 ක සජීවීකරණයක් සහිතව:

යාවත්කාලීන කිරීම: එය සූදානම් !!!

ඔබට හයි-රෙස් අවශ්‍ය විය, මට හයි-රෙස් අවශ්‍ය විය, ඔබ නොඉවසිලිමත් විය, මම යන්තම් නිදා ගතිමි. දැන් මම සතුටු වෙනවා එය අවසාන වශයෙන් සූදානම්, නිෂ්පාදන ගුණාත්මක බව. මම එය මහා පිපිරුමකින්, 1080p යූ ටියුබ් වීඩියෝවකින් මුදා හරිමි! වීඩියෝව සඳහා මෙහි ක්ලික් කරන්න , ගීක් විලාසිතාව ප්‍රවර්ධනය කිරීම සඳහා එය වෛරස් කරමු. මම මගේ බ්ලොග් අඩවියේ ද http://joco.name/ හි පළ කරමි, සියලු රසවත් තොරතුරු, ප්‍රශස්තිකරණය, මම වීඩියෝව සෑදූ ආකාරය ආදිය පිළිබඳ තාක්ෂණික සටහනක් ඇත. අවසාන වශයෙන්, මම මූලාශ්‍රය බෙදා ගන්නෙමි ජීපීඑල් යටතේ කේතය . එය විශාල වී ඇති බැවින් නිසි සත්කාරකත්වය මේ සඳහා හොඳම ස්ථානය වන අතර, මගේ පිළිතුරේ ඉහත කොටස තවදුරටත් සංස්කරණය නොකරමි. මුදා හැරීමේ මාදිලියේ සම්පාදනය කිරීමට වග බලා ගන්න! මෙම වැඩසටහන බොහෝ CPU මධ්‍යයන් සඳහා හොඳින් පරිමාණය කරයි. 4Kx4K විදැහුම්කරණයකට 2-3 GB RAM ප්‍රමාණයක් අවශ්‍ය වේ.

මට දැන් පැය 5-10 කින් විශාල රූප ඉදිරිපත් කළ හැකිය. මා සතුව දැනටමත් 4Kx4K විදැහුම් කිහිපයක් තිබේ, මම ඒවා පසුව පළ කරමි. වැඩසටහන විශාල දියුණුවක් ලබා ඇත, අසංඛ්‍යාත ප්‍රශස්තිකරණයන් ඇත. ඕනෑම කෙනෙකුට පහසුවෙන් භාවිතා කළ හැකි වන පරිදි මම එය පරිශීලක හිතකාමී බවට පත් කළෙමි, එයට හොඳ විධාන රේඛාවක් ඇත. වැඩසටහන ද අහඹු ලෙස අහඹු ය, එයින් අදහස් කරන්නේ ඔබට අහඹු බීජයක් භාවිතා කළ හැකි අතර එය සෑම විටම එකම රූපය ජනනය කරනු ඇත.

මෙන්න විශාල විදැහුම් කිහිපයක්.

මගේ ප්‍රියතම 512:


(මූලාශ්‍රය: joco.name )

මගේ වීඩියෝවේ දැක්වෙන 2048 ගණන් :


(මූලාශ්‍රය: joco.name )


(මූලාශ්‍රය: joco.name )


(මූලාශ්‍රය: joco.name )


(මූලාශ්‍රය: joco.name )

පළමු 4096 විදැහුම්කරණය (TODO: ඒවා උඩුගත කෙරෙමින් පවතින අතර මගේ වෙබ් අඩවියට විශාල ගමනාගමනය හැසිරවිය නොහැක, එබැවින් ඒවා තාවකාලිකව වෙනත් ස්ථානයකට ගෙන යනු ලැබේ):


(මූලාශ්‍රය: joco.name )


(මූලාශ්‍රය: joco.name )


(මූලාශ්‍රය: joco.name )


(මූලාශ්‍රය: joco.name )


25
දැන් මෙය නියමයි!
ජා-සී

5
හරිම ලස්සනයි :-D දැන් වඩා විශාල ඒවා සාදන්න!
r3mainer

20
ඔබ සැබෑ කලාකරුවෙක්! :)
AL

10
මුද්‍රණයක් සඳහා කොපමණ මුදලක්?
ප්‍රීමෝ

16
මම විශාල විදැහුම්කරණය සහ 1080p වීඩියෝවක් සඳහා වැඩ කරමින් සිටිමි. පැය හෝ දින ගත වේවි. විශාල විදැහුම්කරණයකින් මුද්‍රණයක් නිර්මාණය කිරීමට යමෙකුට හැකි වේ යැයි මම බලාපොරොත්තු වෙමි. හෝ ටී ෂර්ට් එකක්: එක් පැත්තක කේතය, අනෙක් පැත්තෙන් රූපය. කිසිවෙකුට එය සංවිධානය කළ හැකිද?
fejesjoco

251

සැකසීම

යාවත්කාලීන කරන්න!පින්තූර 4096x4096!

වැඩසටහන් දෙක එකට එකතු කිරීමෙන් මම මගේ දෙවන පෝස්ටය මෙයට ඒකාබද්ධ කළෙමි.

තෝරාගත් පින්තූරවල සම්පූර්ණ එකතුවක් ඩ්‍රොප්බොක්ස් හි සොයාගත හැකිය .(සටහන: ඩ්‍රොප්බොක්ස් 4096x4096 පින්තූර සඳහා පෙරදසුන් ජනනය කළ නොහැක; ඒවා ක්ලික් කර "බාගන්න" ක්ලික් කරන්න).

ඔබ මේ දෙස එක බැල්මක් පමණක් බැලුවහොත් (ටයිල් කළ හැකි)! මෙන්න එය පරිමාණය කර ඇත (සහ තවත් බොහෝ පහතින්), මුල් 2048x1024:

රූප විස්තරය මෙහි ඇතුළත් කරන්න

මෙම වැඩසටහන ක්‍රියාත්මක වන්නේ වර්ණ කියුබයේ අහඹු ලෙස තෝරාගත් ස්ථාන වලින් ගමන් කිරීමෙන් පසුව රූපයේ අහඹු ලෙස තෝරාගත් මාර්ගවලට ඒවා ඇද ගැනීමෙනි. හැකියාවන් ගොඩක් තිබේ. වින්‍යාසගත කළ හැකි විකල්ප:

  • වර්ණ කියුබ් මාර්ගයේ උපරිම දිග.
  • වර්ණ කියුබ් හරහා ගත යුතු උපරිම පියවර (විශාල අගයන් විශාල විචල්‍යතාවයක් ඇති කරයි, නමුත් දේවල් තද වන විට අවසානය දක්වා කුඩා මාර්ග ගණන අවම කරන්න).
  • රූපය ටයිල් කිරීම.
  • දැනට රූප මාර්ග ආකාර දෙකක් ඇත:
    • ප්‍රකාරය 1 (මෙම මුල් පෝස්ටයේ මාදිලිය): රූපයේ භාවිතයට නොගත් පික්සෙල් සමූහයක් සොයාගෙන එම කොටස වෙත යොමු කරයි. බ්ලොක් අහඹු ලෙස ස්ථානගත කළ හැකිය, නැතහොත් වමේ සිට දකුණට ඇණවුම් කළ හැකිය.
    • ප්‍රකාරය 2 (මගේ දෙවන පෝස්ටයේ මා මෙයට ඒකාබද්ධ කළ ආකාරය): රූපයේ අහඹු ආරම්භක ලක්ෂ්‍යයක් තෝරාගෙන භාවිතයට නොගත් පික්සෙල් හරහා ගමන් කරයි; පාවිච්චි කළ පික්සෙල් වටා ගමන් කළ හැකිය. මෙම මාදිලිය සඳහා විකල්ප:
      • ඇවිදීමට අවශ්‍ය දිශාවන් (විකලාංග, විකර්ණ හෝ දෙකම).
      • එක් එක් පියවරෙන් පසු දිශාව වෙනස් කළ යුතුද නැද්ද යන්න (දැනට ඔරලෝසුවක නමුත් කේතය නම්යශීලී වේ), නැතහොත් වාඩිලා ගත් පික්සෙල් හමු වූ විට පමණක් දිශාව වෙනස් කිරීම ..
      • දිශාව වෙනස් කිරීමේ අනුපිළිවෙල මාරු කිරීමේ විකල්පය (ඔරලෝසුව වෙනුවට).

එය 4096x4096 දක්වා සියලුම ප්‍රමාණ සඳහා ක්‍රියා කරයි.

සම්පූර්ණ සැකසුම් සටහන මෙහි සොයාගත හැකිය: Tracer.zip

අවකාශය ඉතිරි කර ගැනීම සඳහා මම සියලුම ලිපිගොනු එකම කේත බ්ලොක් එකක අලවා ඇත (සියල්ලම එක් ගොනුවක වුවද එය තවමත් වලංගු සටහනකි). ඔබට පෙරසිටර වලින් එකක් භාවිතා කිරීමට අවශ්‍ය නම්, gPresetපැවරුමේ දර්ශකය වෙනස් කරන්න . ඔබ මෙය සැකසුම් තුළ rක්‍රියාත්මක කරන්නේ නම් එය නව රූපයක් ජනනය කිරීම සඳහා ක්‍රියාත්මක වන අතරතුර ඔබන්න .

  • යාවත්කාලීන 1: පළමු භාවිතයට නොගත් වර්ණය / පික්සෙල් නිරීක්ෂණය කිරීමට ප්‍රශස්ත කේතය සහ දන්නා පාවිච්චි කළ පික්සෙල් හරහා සෙවීම නොවේ; 2048x1024 පරම්පරාවේ කාලය මිනිත්තු 10-30 සිට තත්පර 15 දක්වා අඩු කළ අතර 4096x4096 පැය 1-3 සිට මිනිත්තු 1 දක්වා අඩු විය. පහත දැක්වෙන බොක්ස් ප්‍රභවය සහ ප්‍රභවය යාවත්කාලීන කරන්න.
  • යාවත්කාලීන 2: පින්තූර 4096x4096 ජනනය වීම වළක්වන ස්ථාවර දෝෂයකි.
final int BITS = 5; // Set to 5, 6, 7, or 8!

// Preset (String name, int colorBits, int maxCubePath, int maxCubeStep, int imageMode, int imageOpts)
final Preset[] PRESETS = new Preset[] {
  // 0
  new Preset("flowers",      BITS, 8*32*32, 2, ImageRect.MODE2, ImageRect.ALL_CW | ImageRect.CHANGE_DIRS),
  new Preset("diamonds",     BITS, 2*32*32, 2, ImageRect.MODE2, ImageRect.ORTHO_CW | ImageRect.CHANGE_DIRS),
  new Preset("diamondtile",  BITS, 2*32*32, 2, ImageRect.MODE2, ImageRect.ORTHO_CW | ImageRect.CHANGE_DIRS | ImageRect.WRAP),
  new Preset("shards",       BITS, 2*32*32, 2, ImageRect.MODE2, ImageRect.ALL_CW | ImageRect.CHANGE_DIRS | ImageRect.SHUFFLE_DIRS),
  new Preset("bigdiamonds",  BITS,  100000, 6, ImageRect.MODE2, ImageRect.ORTHO_CW | ImageRect.CHANGE_DIRS),
  // 5
  new Preset("bigtile",      BITS,  100000, 6, ImageRect.MODE2, ImageRect.ORTHO_CW | ImageRect.CHANGE_DIRS | ImageRect.WRAP),
  new Preset("boxes",        BITS,   32*32, 2, ImageRect.MODE2, ImageRect.ORTHO_CW),
  new Preset("giftwrap",     BITS,   32*32, 2, ImageRect.MODE2, ImageRect.ORTHO_CW | ImageRect.WRAP),
  new Preset("diagover",     BITS,   32*32, 2, ImageRect.MODE2, ImageRect.DIAG_CW),
  new Preset("boxfade",      BITS,   32*32, 2, ImageRect.MODE2, ImageRect.DIAG_CW | ImageRect.CHANGE_DIRS),
  // 10
  new Preset("randlimit",    BITS,     512, 2, ImageRect.MODE1, ImageRect.RANDOM_BLOCKS),
  new Preset("ordlimit",     BITS,      64, 2, ImageRect.MODE1, 0),
  new Preset("randtile",     BITS,    2048, 3, ImageRect.MODE1, ImageRect.RANDOM_BLOCKS | ImageRect.WRAP),
  new Preset("randnolimit",  BITS, 1000000, 1, ImageRect.MODE1, ImageRect.RANDOM_BLOCKS),
  new Preset("ordnolimit",   BITS, 1000000, 1, ImageRect.MODE1, 0)
};


PGraphics gFrameBuffer;
Preset gPreset = PRESETS[2];

void generate () {
  ColorCube cube = gPreset.createCube();
  ImageRect image = gPreset.createImage();
  gFrameBuffer = createGraphics(gPreset.getWidth(), gPreset.getHeight(), JAVA2D);
  gFrameBuffer.noSmooth();
  gFrameBuffer.beginDraw();
  while (!cube.isExhausted())
    image.drawPath(cube.nextPath(), gFrameBuffer);
  gFrameBuffer.endDraw();
  if (gPreset.getName() != null)
    gFrameBuffer.save(gPreset.getName() + "_" + gPreset.getCubeSize() + ".png");
  //image.verifyExhausted();
  //cube.verifyExhausted();
}

void setup () {
  size(gPreset.getDisplayWidth(), gPreset.getDisplayHeight());
  noSmooth();
  generate();
}

void keyPressed () {
  if (key == 'r' || key == 'R')
    generate();
}

boolean autogen = false;
int autop = 0;
int autob = 5;

void draw () {
  if (autogen) {
    gPreset = new Preset(PRESETS[autop], autob);
    generate();
    if ((++ autop) >= PRESETS.length) {
      autop = 0;
      if ((++ autob) > 8)
        autogen = false;
    }
  }
  if (gPreset.isWrapped()) {
    int hw = width/2;
    int hh = height/2;
    image(gFrameBuffer, 0, 0, hw, hh);
    image(gFrameBuffer, hw, 0, hw, hh);
    image(gFrameBuffer, 0, hh, hw, hh);
    image(gFrameBuffer, hw, hh, hw, hh);
  } else {
    image(gFrameBuffer, 0, 0, width, height);
  }
}

static class ColorStep {
  final int r, g, b;
  ColorStep (int rr, int gg, int bb) { r=rr; g=gg; b=bb; }
}

class ColorCube {

  final boolean[] used;
  final int size; 
  final int maxPathLength;
  final ArrayList<ColorStep> allowedSteps = new ArrayList<ColorStep>();

  int remaining;
  int pathr = -1, pathg, pathb;
  int firstUnused = 0;

  ColorCube (int size, int maxPathLength, int maxStep) {
    this.used = new boolean[size*size*size];
    this.remaining = size * size * size;
    this.size = size;
    this.maxPathLength = maxPathLength;
    for (int r = -maxStep; r <= maxStep; ++ r)
      for (int g = -maxStep; g <= maxStep; ++ g)
        for (int b = -maxStep; b <= maxStep; ++ b)
          if (r != 0 && g != 0 && b != 0)
            allowedSteps.add(new ColorStep(r, g, b));
  }

  boolean isExhausted () {
    println(remaining);
    return remaining <= 0;
  }

  boolean isUsed (int r, int g, int b) {
    if (r < 0 || r >= size || g < 0 || g >= size || b < 0 || b >= size)
      return true;
    else
      return used[(r*size+g)*size+b];
  }

  void setUsed (int r, int g, int b) {
    used[(r*size+g)*size+b] = true;
  }

  int nextColor () {

    if (pathr == -1) { // Need to start a new path.

      // Limit to 50 attempts at random picks; things get tight near end.
      for (int n = 0; n < 50 && pathr == -1; ++ n) {
        int r = (int)random(size);
        int g = (int)random(size);
        int b = (int)random(size);
        if (!isUsed(r, g, b)) {
          pathr = r;
          pathg = g;
          pathb = b;
        }
      }
      // If we didn't find one randomly, just search for one.
      if (pathr == -1) {
        final int sizesq = size*size;
        final int sizemask = size - 1;
        for (int rgb = firstUnused; rgb < size*size*size; ++ rgb) {
          pathr = (rgb/sizesq)&sizemask;//(rgb >> 10) & 31;
          pathg = (rgb/size)&sizemask;//(rgb >> 5) & 31;
          pathb = rgb&sizemask;//rgb & 31;
          if (!used[rgb]) {
            firstUnused = rgb;
            break;
          }
        }
      }

      assert(pathr != -1);

    } else { // Continue moving on existing path.

      // Find valid next path steps.
      ArrayList<ColorStep> possibleSteps = new ArrayList<ColorStep>();
      for (ColorStep step:allowedSteps)
        if (!isUsed(pathr+step.r, pathg+step.g, pathb+step.b))
          possibleSteps.add(step);

      // If there are none end this path.
      if (possibleSteps.isEmpty()) {
        pathr = -1;
        return -1;
      }

      // Otherwise pick a random step and move there.
      ColorStep s = possibleSteps.get((int)random(possibleSteps.size()));
      pathr += s.r;
      pathg += s.g;
      pathb += s.b;

    }

    setUsed(pathr, pathg, pathb);  
    return 0x00FFFFFF & color(pathr * (256/size), pathg * (256/size), pathb * (256/size));

  } 

  ArrayList<Integer> nextPath () {

    ArrayList<Integer> path = new ArrayList<Integer>(); 
    int rgb;

    while ((rgb = nextColor()) != -1) {
      path.add(0xFF000000 | rgb);
      if (path.size() >= maxPathLength) {
        pathr = -1;
        break;
      }
    }

    remaining -= path.size();

    //assert(!path.isEmpty());
    if (path.isEmpty()) {
      println("ERROR: empty path.");
      verifyExhausted();
    }
    return path;

  }

  void verifyExhausted () {
    final int sizesq = size*size;
    final int sizemask = size - 1;
    for (int rgb = 0; rgb < size*size*size; ++ rgb) {
      if (!used[rgb]) {
        int r = (rgb/sizesq)&sizemask;
        int g = (rgb/size)&sizemask;
        int b = rgb&sizemask;
        println("UNUSED COLOR: " + r + " " + g + " " + b);
      }
    }
    if (remaining != 0)
      println("REMAINING COLOR COUNT IS OFF: " + remaining);
  }

}


static class ImageStep {
  final int x;
  final int y;
  ImageStep (int xx, int yy) { x=xx; y=yy; }
}

static int nmod (int a, int b) {
  return (a % b + b) % b;
}

class ImageRect {

  // for mode 1:
  //   one of ORTHO_CW, DIAG_CW, ALL_CW
  //   or'd with flags CHANGE_DIRS
  static final int ORTHO_CW = 0;
  static final int DIAG_CW = 1;
  static final int ALL_CW = 2;
  static final int DIR_MASK = 0x03;
  static final int CHANGE_DIRS = (1<<5);
  static final int SHUFFLE_DIRS = (1<<6);

  // for mode 2:
  static final int RANDOM_BLOCKS = (1<<0);

  // for both modes:
  static final int WRAP = (1<<16);

  static final int MODE1 = 0;
  static final int MODE2 = 1;

  final boolean[] used;
  final int width;
  final int height;
  final boolean changeDir;
  final int drawMode;
  final boolean randomBlocks;
  final boolean wrap;
  final ArrayList<ImageStep> allowedSteps = new ArrayList<ImageStep>();

  // X/Y are tracked instead of index to preserve original unoptimized mode 1 behavior
  // which does column-major searches instead of row-major.
  int firstUnusedX = 0;
  int firstUnusedY = 0;

  ImageRect (int width, int height, int drawMode, int drawOpts) {
    boolean myRandomBlocks = false, myChangeDir = false;
    this.used = new boolean[width*height];
    this.width = width;
    this.height = height;
    this.drawMode = drawMode;
    this.wrap = (drawOpts & WRAP) != 0;
    if (drawMode == MODE1) {
      myRandomBlocks = (drawOpts & RANDOM_BLOCKS) != 0;
    } else if (drawMode == MODE2) {
      myChangeDir = (drawOpts & CHANGE_DIRS) != 0;
      switch (drawOpts & DIR_MASK) {
      case ORTHO_CW:
        allowedSteps.add(new ImageStep(1, 0));
        allowedSteps.add(new ImageStep(0, -1));
        allowedSteps.add(new ImageStep(-1, 0));
        allowedSteps.add(new ImageStep(0, 1));
        break;
      case DIAG_CW:
        allowedSteps.add(new ImageStep(1, -1));
        allowedSteps.add(new ImageStep(-1, -1));
        allowedSteps.add(new ImageStep(-1, 1));
        allowedSteps.add(new ImageStep(1, 1));
        break;
      case ALL_CW:
        allowedSteps.add(new ImageStep(1, 0));
        allowedSteps.add(new ImageStep(1, -1));
        allowedSteps.add(new ImageStep(0, -1));
        allowedSteps.add(new ImageStep(-1, -1));
        allowedSteps.add(new ImageStep(-1, 0));
        allowedSteps.add(new ImageStep(-1, 1));
        allowedSteps.add(new ImageStep(0, 1));
        allowedSteps.add(new ImageStep(1, 1));
        break;
      }
      if ((drawOpts & SHUFFLE_DIRS) != 0)
        java.util.Collections.shuffle(allowedSteps);
    }
    this.randomBlocks = myRandomBlocks;
    this.changeDir = myChangeDir;
  }

  boolean isUsed (int x, int y) {
    if (wrap) {
      x = nmod(x, width);
      y = nmod(y, height);
    }
    if (x < 0 || x >= width || y < 0 || y >= height)
      return true;
    else
      return used[y*width+x];
  }

  boolean isUsed (int x, int y, ImageStep d) {
    return isUsed(x + d.x, y + d.y);
  }

  void setUsed (int x, int y) {
    if (wrap) {
      x = nmod(x, width);
      y = nmod(y, height);
    }
    used[y*width+x] = true;
  }

  boolean isBlockFree (int x, int y, int w, int h) {
    for (int yy = y; yy < y + h; ++ yy)
      for (int xx = x; xx < x + w; ++ xx)
        if (isUsed(xx, yy))
          return false;
    return true;
  }

  void drawPath (ArrayList<Integer> path, PGraphics buffer) {
    if (drawMode == MODE1)
      drawPath1(path, buffer);
    else if (drawMode == MODE2)
      drawPath2(path, buffer);
  }

  void drawPath1 (ArrayList<Integer> path, PGraphics buffer) {

    int w = (int)(sqrt(path.size()) + 0.5);
    if (w < 1) w = 1; else if (w > width) w = width;
    int h = (path.size() + w - 1) / w; 
    int x = -1, y = -1;

    int woff = wrap ? 0 : (1 - w);
    int hoff = wrap ? 0 : (1 - h);

    // Try up to 50 times to find a random location for block.
    if (randomBlocks) {
      for (int n = 0; n < 50 && x == -1; ++ n) {
        int xx = (int)random(width + woff);
        int yy = (int)random(height + hoff);
        if (isBlockFree(xx, yy, w, h)) {
          x = xx;
          y = yy;
        }
      }
    }

    // If random choice failed just search for one.
    int starty = firstUnusedY;
    for (int xx = firstUnusedX; xx < width + woff && x == -1; ++ xx) {
      for (int yy = starty; yy < height + hoff && x == -1; ++ yy) {
        if (isBlockFree(xx, yy, w, h)) {
          firstUnusedX = x = xx;
          firstUnusedY = y = yy;
        }  
      }
      starty = 0;
    }

    if (x != -1) {
      for (int xx = x, pathn = 0; xx < x + w && pathn < path.size(); ++ xx)
        for (int yy = y; yy < y + h && pathn < path.size(); ++ yy, ++ pathn) {
          buffer.set(nmod(xx, width), nmod(yy, height), path.get(pathn));
          setUsed(xx, yy);
        }
    } else {
      for (int yy = 0, pathn = 0; yy < height && pathn < path.size(); ++ yy)
        for (int xx = 0; xx < width && pathn < path.size(); ++ xx)
          if (!isUsed(xx, yy)) {
            buffer.set(nmod(xx, width), nmod(yy, height), path.get(pathn));
            setUsed(xx, yy);
            ++ pathn;
          }
    }

  }

  void drawPath2 (ArrayList<Integer> path, PGraphics buffer) {

    int pathn = 0;

    while (pathn < path.size()) {

      int x = -1, y = -1;

      // pick a random location in the image (try up to 100 times before falling back on search)

      for (int n = 0; n < 100 && x == -1; ++ n) {
        int xx = (int)random(width);
        int yy = (int)random(height);
        if (!isUsed(xx, yy)) {
          x = xx;
          y = yy;
        }
      }  

      // original:
      //for (int yy = 0; yy < height && x == -1; ++ yy)
      //  for (int xx = 0; xx < width && x == -1; ++ xx)
      //    if (!isUsed(xx, yy)) {
      //      x = xx;
      //      y = yy;
      //    }
      // optimized:
      if (x == -1) {
        for (int n = firstUnusedY * width + firstUnusedX; n < used.length; ++ n) {
          if (!used[n]) {
            firstUnusedX = x = (n % width);
            firstUnusedY = y = (n / width);
            break;
          }     
        }
      }

      // start drawing

      int dir = 0;

      while (pathn < path.size()) {

        buffer.set(nmod(x, width), nmod(y, height), path.get(pathn ++));
        setUsed(x, y);

        int diro;
        for (diro = 0; diro < allowedSteps.size(); ++ diro) {
          int diri = (dir + diro) % allowedSteps.size();
          ImageStep step = allowedSteps.get(diri);
          if (!isUsed(x, y, step)) {
            dir = diri;
            x += step.x;
            y += step.y;
            break;
          }
        }

        if (diro == allowedSteps.size())
          break;

        if (changeDir) 
          ++ dir;

      }    

    }

  }

  void verifyExhausted () {
    for (int n = 0; n < used.length; ++ n)
      if (!used[n])
        println("UNUSED IMAGE PIXEL: " + (n%width) + " " + (n/width));
  }

}


class Preset {

  final String name;
  final int cubeSize;
  final int maxCubePath;
  final int maxCubeStep;
  final int imageWidth;
  final int imageHeight;
  final int imageMode;
  final int imageOpts;
  final int displayScale;

  Preset (Preset p, int colorBits) {
    this(p.name, colorBits, p.maxCubePath, p.maxCubeStep, p.imageMode, p.imageOpts);
  }

  Preset (String name, int colorBits, int maxCubePath, int maxCubeStep, int imageMode, int imageOpts) {
    final int csize[] = new int[]{ 32, 64, 128, 256 };
    final int iwidth[] = new int[]{ 256, 512, 2048, 4096 };
    final int iheight[] = new int[]{ 128, 512, 1024, 4096 };
    final int dscale[] = new int[]{ 2, 1, 1, 1 };
    this.name = name; 
    this.cubeSize = csize[colorBits - 5];
    this.maxCubePath = maxCubePath;
    this.maxCubeStep = maxCubeStep;
    this.imageWidth = iwidth[colorBits - 5];
    this.imageHeight = iheight[colorBits - 5];
    this.imageMode = imageMode;
    this.imageOpts = imageOpts;
    this.displayScale = dscale[colorBits - 5];
  }

  ColorCube createCube () {
    return new ColorCube(cubeSize, maxCubePath, maxCubeStep);
  }

  ImageRect createImage () {
    return new ImageRect(imageWidth, imageHeight, imageMode, imageOpts);
  }

  int getWidth () {
    return imageWidth;
  }

  int getHeight () {
    return imageHeight;
  }

  int getDisplayWidth () {
    return imageWidth * displayScale * (isWrapped() ? 2 : 1);
  }

  int getDisplayHeight () {
    return imageHeight * displayScale * (isWrapped() ? 2 : 1);
  }

  String getName () {
    return name;
  }

  int getCubeSize () {
    return cubeSize;
  }

  boolean isWrapped () {
    return (imageOpts & ImageRect.WRAP) != 0;
  }

}

මෙන්න මම කැමති පින්තූර 256x128 සම්පූර්ණ කට්ටලයක්:

ප්‍රකාරය 1:

මුල් කට්ටලයෙන් මගේ ප්‍රියතමය (max_path_length = 512, path_step = 2, අහඹු, දර්ශනය වූ 2x, සබැඳිය 256x128 ):

රූප විස්තරය මෙහි ඇතුළත් කරන්න

අනෙක් ඒවා (වම් දෙක ඇණවුම් කර ඇත, දකුණට අහඹු දෙකක්, ඉහළ මාර්ග දෙකේ සීමිත, පහළ දෙක අසීමිත):

නියෝග අහඹු ලෙස ordnolimit randnolimit

මෙය ටයිල් කළ හැකිය:

අහඹු ලෙස

මාතය 2:

දියමන්ති මල් boxfade diagover ලොකු දියමන්ති box2 කැබලි

මේවා ටයිල් කළ හැකිය:

ලොකු දියමන්ති තෑගි කවරය

512x512 වරණයන්:

ටයිල් කළ හැකි දියමන්ති, මාදිලි 2 සිට මගේ ප්‍රියතම; පවතින වස්තූන් වටා මාර්ග ගමන් කරන ආකාරය ඔබට මෙයින් දැක ගත හැකිය:

රූප විස්තරය මෙහි ඇතුළත් කරන්න

ටයිල් කළ හැකි විශාල මාර්ග පියවර සහ උපරිම මාර්ග දිග:

රූප විස්තරය මෙහි ඇතුළත් කරන්න

සසම්භාවී මාදිලිය 1, ටයිල් කළ හැකි:

රූප විස්තරය මෙහි ඇතුළත් කරන්න

තවත් තේරීම්:

රූප විස්තරය මෙහි ඇතුළත් කරන්න රූප විස්තරය මෙහි ඇතුළත් කරන්න රූප විස්තරය මෙහි ඇතුළත් කරන්න

512x512 විදැහුම් සියල්ලම ඩ්‍රොප්බොක්ස් ෆෝල්ඩරයේ (* _64.png) සොයාගත හැකිය.

2048x1024 සහ 4096x4096:

මේවා කාවැද්දීමට තරම් විශාල වන අතර මා සොයාගත් සියලුම රූප ධාරක ඒවා 1600x1200 දක්වා පහත වැටේ. මම දැනට පින්තූර 4096x4096 කට්ටලයක් ඉදිරිපත් කරමින් සිටිමි, එබැවින් තවත් ඉක්මනින් ලබා ගත හැක. මෙහි ඇති සියලුම සබැඳි ඇතුළත් කරනවා වෙනුවට, ඒවා ඩ්‍රොප්බොක්ස් ෆෝල්ඩරයේ පරීක්ෂා කර බලන්න (* _128.png සහ * _256.png, සටහන: 4096x4096 ඒවා ඩ්‍රොප්බොක්ස් පෙරදසුනට වඩා විශාලයි, "බාගන්න" ක්ලික් කරන්න). මෙන්න මගේ ප්‍රියතමයන් කිහිපයක්:

2048x1024 විශාල ටයිල් කළ හැකි දියමන්ති (මෙම ලිපිය ආරම්භයේදී මා සම්බන්ධ කළ එකම)

2048x1024 දියමන්ති (මම මේකට කැමතියි!), පරිමාණය:

රූප විස්තරය මෙහි ඇතුළත් කරන්න

4096x4096 විශාල ටයිල් කළ හැකි දියමන්ති (අවසාන වශයෙන්, ඩ්‍රොප්බොක්ස් සබැඳියේ 'බාගත කරන්න' ක්ලික් කරන්න; එය ඔවුන්ගේ පෙරදසුනට වඩා විශාලය), පරිමාණයෙන් පහළට:

4096x4096 විශාල ටයිල් කළ හැකි දියමන්ති

4096x4096 අහඹු මාදිලිය 1 : රූප විස්තරය මෙහි ඇතුළත් කරන්න

4096x4096 තවත් සිසිල් එකක්

යාවත්කාලීන කිරීම: 2048x1024 පෙර සැකසුම් රූප කට්ටලය අවසන් කර ඇති අතර එය ඩ්‍රොප්බොක්ස් තුළ ඇත. 4096x4096 කට්ටලය පැයක් ඇතුළත කළ යුතුය.

හොඳ ඒවා ටොන් ගණනක් ඇත, කුමන ඒවා පළ කළ යුතුද යන්න තෝරා ගැනීමට මට ඉතා අපහසු වේ, එබැවින් කරුණාකර ෆෝල්ඩරයේ සබැඳිය බලන්න!


7
සමහර ඛනිජ ලවණ පිළිබඳ සමීප අදහස් මට මතක් කර දෙයි.
මෝර්වන්

3
තරඟයේ කොටසක් නොවේ, නමුත් මම සිතුවේ මෙය තරමක් සිසිල් බවය ; මම විශාල ගෝස්ෂන් බොඳ කිරීමක් සහ ස්වයංක්‍රීය වෙනස ෆොටෝෂොප් හි අහඹු මාදිලියේ 1 පින්තූරයකට වැඩි දියුණු කළ අතර එය හොඳ ඩෙස්ක්ටොප් පසුබිමක්-වයි වර්ගයක් බවට පත් කළේය.
ජේසන් සී

2
අපොයි, මේවා නියම පින්තූර!
sevenseacat

2
ගුස්ටාව් ක්ලිමට් වයනය මට මතක් කරයි.
කිම්

2
ඔබට ඩ්‍රොප්බොක්ස් හි පින්තූර හොට්ලින්ක් කළ හැකි බව ඔබ දැන සිටියාද? හුදෙක් ඉවත් බාගත URL පිටපත් dl=1හා token_hash=<something>කොටසක් මේ වගේ ප්රතිරූපය සබැඳියක් කරන්න: [![Alt text of my small preview image](https://i.stack.imgur.com/smallpreview.png)](https://dl.dropbox.com/linktoyourfullsiz‌​eimage.png). තවත් ඉඟියක්: ඔබට ඔබේ පින්තූර සම්පීඩනය කළ හැකිය ( TruePNG ( බාගත කිරීම ) සමඟ මට හොඳ ප්‍රති results ල ලැබේ. මෙම පින්තූරයේ ගොනු ප්‍රමාණයෙන් 28.1% ක් ඉතිරි කිරීමට මට හැකි විය .
පරිශීලක 2428118

224

පයිතන් w / PIL

මෙය නිව්ටෝනියානු ෆ්‍රැක්ටල් මත පදනම් වේ , විශේෂයෙන් z → z 5 - 1 සඳහා . මූලයන් පහක් ඇති නිසාත්, අභිසාරී ස්ථාන පහක් ඇති නිසාත්, පවතින වර්ණ අවකාශය හියු මත පදනම්ව කලාප පහකට බෙදා ඇත. තනි ලක්ෂ්‍යයන් පළමුව ඒවායේ අභිසාරී ලක්ෂ්‍යයට ළඟා වීමට අවශ්‍ය පුනරාවර්තන ගණන අනුව වර්ග කර ඇති අතර පසුව එම ස්ථානයට ඇති දුර අනුව කලින් අගයන් වඩා දීප්තිමත් වර්ණයක් පවරනු ලැබේ.

යාවත්කාලීන කිරීම: 4096x4096 විශාල විදැහුම්කරණය, allrgb.com හි සත්කාරකත්වය සපයයි .

මුල් (33.7 MB)

කේන්ද්‍රයේ සමීප ස්ථානයක් (සත්‍ය ප්‍රමාණය):

මෙම අගයන් භාවිතා කරමින් වෙනස් වාතාවරණයක්:

xstart = 0
ystart = 0

xd = 1 / dim[0]
yd = 1 / dim[1]

මුල් (32.2 MB)

මේවා භාවිතා කරන තවත් අයෙක්:

xstart = 0.5
ystart = 0.5

xd = 0.001 / dim[0]
yd = 0.001 / dim[1]

මුල් (27.2 MB)


සජීවිකරණය

ඉල්ලීම පරිදි, මම විශාලන සජීවිකරණයක් සම්පාදනය කර ඇත්තෙමි.

නාභීය ලක්ෂ්‍යය: ( 0.50051 , -0.50051 )
විශාලන සාධකය: 2 1/5

නාභිගත කිරීම තරමක් අමුතු අගයකි, මන්ද මට කළු තිතක් විශාලනය කිරීමට අවශ්‍ය නොවීය. විශාලන සාධකය තෝරාගෙන ඇත්තේ එය සෑම රාමු 5 කටම දෙගුණ වන බැවිනි.

32x32 ටීසර්:

256x256 අනුවාදයක් මෙහි දැකිය හැකිය:
http://www.pictureshack.org/images/66172_frac.gif (5.4MB)

ගණිතමය වශයෙන් “තමන් වෙතට” විශාලනය වන කරුණු තිබිය හැකි අතර එය අසීමිත සජීවිකරණයකට ඉඩ සලසයි. මට කිසිවක් හඳුනාගත හැකි නම්, මම ඒවා මෙහි එක් කරමි.


මූලාශ්රය

from __future__ import division
from PIL import Image, ImageDraw
from cmath import phase
from sys import maxint

dim  = (4096, 4096)
bits = 8

def RGBtoHSV(R, G, B):
  R /= 255
  G /= 255
  B /= 255

  cmin = min(R, G, B)
  cmax = max(R, G, B)
  dmax = cmax - cmin

  V = cmax

  if dmax == 0:
    H = 0
    S = 0

  else:
    S = dmax/cmax

    dR = ((cmax - R)/6 + dmax/2)/dmax
    dG = ((cmax - G)/6 + dmax/2)/dmax
    dB = ((cmax - B)/6 + dmax/2)/dmax

    if   R == cmax: H = (dB - dG)%1
    elif G == cmax: H = (1/3 + dR - dB)%1
    elif B == cmax: H = (2/3 + dG - dR)%1

  return (H, S, V)

cmax = (1<<bits)-1
cfac = 255/cmax

img  = Image.new('RGB', dim)
draw = ImageDraw.Draw(img)

xstart = -2
ystart = -2

xd = 4 / dim[0]
yd = 4 / dim[1]

tol = 1e-12

a = [[], [], [], [], []]

for x in range(dim[0]):
  print x, "\r",
  for y in range(dim[1]):
    z = d = complex(xstart + x*xd, ystart + y*yd)
    c = 0
    l = 1
    while abs(l-z) > tol and abs(z) > tol:
      l = z
      z -= (z**5-1)/(5*z**4)
      c += 1
    if z == 0: c = maxint
    p = int(phase(z))

    a[p] += (c,abs(d-z), x, y),

for i in range(5):
  a[i].sort(reverse = False)

pnum = [len(a[i]) for i in range(5)]
ptot = dim[0]*dim[1]

bounds = []
lbound = 0
for i in range(4):
  nbound = lbound + pnum[i]/ptot
  bounds += nbound,
  lbound = nbound

t = [[], [], [], [], []]
for i in range(ptot-1, -1, -1):
  r = (i>>bits*2)*cfac
  g = (cmax&i>>bits)*cfac
  b = (cmax&i)*cfac
  (h, s, v) = RGBtoHSV(r, g, b)
  h = (h+0.1)%1
  if   h < bounds[0] and len(t[0]) < pnum[0]: p=0
  elif h < bounds[1] and len(t[1]) < pnum[1]: p=1
  elif h < bounds[2] and len(t[2]) < pnum[2]: p=2
  elif h < bounds[3] and len(t[3]) < pnum[3]: p=3
  else: p=4
  t[p] += (int(r), int(g), int(b)),

for i in range(5):
  t[i].sort(key = lambda c: c[0]*2126 + c[1]*7152 + c[2]*722, reverse = True)

r = [0, 0, 0, 0, 0]
for p in range(5):
  for c,d,x,y in a[p]:
    draw.point((x,y), t[p][r[p]])
    r[p] += 1

img.save("out.png")

6
අවසාන වශයෙන් අස්ථි බිඳීමක් :) ඒවාට ආදරය කරන්න. අංශක 144 ක් වන එම කොළ මගේ ප්‍රියතම වර්ණයයි (පිරිසිදු කොළ පාටට අංශක 120 ට වඩා නීරස ය).
මාර්ක් ජෙරොනිමස්

2
මට එපා, මම ඇත්ත වශයෙන්ම AllRGB අනුවාදයන්ට වඩා කැමතියි; සම්පූර්ණ දීප්තිමත්ව අවකාශය භාවිතා කිරීමේ අවශ්‍යතාවය ප්‍රමිතීන් මනාව අවධාරණය කරයි.
ඉල්මාරි කරොනන්

2
+1 අවසාන වශයෙන් හොඳ අස්ථි කිහිපයක්! අන්තිම එක මගේ පුද්ගලික ප්‍රියතමය. ඔබ වීඩියෝ විශාලනය කළ යුතුය! (Qu ක්වින්කන්ක්ස්: ඔබත් දුටුවා; එයට මගේ ඡන්දය පළමු දිනයේ සිටම තිබුණා!)
ජේසන් සී

1
Ason ජේසන් සී මම සජීවිකරණයක් එක් කළෙමි;)
ප්‍රීමෝ

2
@primo මම දන්නවා මම පරක්කුයි කියලා, නමුත් මට කියන්න ඕන මේ පින්තූර දර්ශනීයයි කියලා.
අශ්වින් ගුප්තා

132

මට මෙම අදහස පරිශීලක ෆෙජෙස්ජෝකෝගේ ඇල්ගොරිතමයෙන් ලැබුණු අතර ටිකක් සෙල්ලම් කිරීමට අවශ්‍ය වූ නිසා මම මුල සිටම මගේම ඇල්ගොරිතම ලිවීමට පටන් ගතිමි.

මම මෙය පළ කරන්නේ ඔබ අතරින් හොඳම දේට වඩා හොඳ දෙයක් මට කළ හැකි යැයි මට හැඟෙන බැවිනි, මෙම අභියෝගය තවම අවසන් වී ඇතැයි මම නොසිතමි. සංසන්දනය කිරීම සඳහා, AllRGB හි සිත් ඇදගන්නාසුළු මෝස්තර කිහිපයක් මෙහි ඇති මට්ටමට වඩා ඉහළින් මා සලකන අතර ඔවුන් එය කළේ කෙසේදැයි මට අදහසක් නැත.

*) තවමත් ඡන්දයෙන් තීරණය වේ

මෙම ඇල්ගොරිතම:

  1. බීජ (කිහිපයක්) සමඟ ආරම්භ කරන්න, හැකි තරම් කළු පැහැයට හැරෙන්න.
  2. සංචාරය නොකළ ස්ථානයකට සම්බන්ධ නොවූ 8 පික්සෙල් ලැයිස්තුවක් තබා ගන්න.
  3. එම ලැයිස්තුවෙන් අහඹු ** ලක්ෂ්‍යයක් තෝරන්න
  4. ගණනය කරන ලද සියලුම පික්සෙල් වල සාමාන්‍ය වර්ණය ගණනය කරන්න [සංස්කරණය කරන්න ... 9x9 වර්ගයක ගවුසියානු කර්නලයක් භාවිතා කර] එයට 8 සම්බන්ධ කර ඇත (එය මෙතරම් සුමට ලෙස පෙනීමට හේතුව මෙයයි) කිසිවක් සොයාගත නොහැකි නම් කළු පැහැයක් ගන්න.
  5. මෙම වර්ණය වටා 3x3x3 ube නකයක් තුළ, භාවිතයට නොගත් වර්ණයක් සොයන්න.
    • බහු වර්ණ හමු වූ විට, අඳුරුතම එක ගන්න.
    • බහුවිධ සමානව අඳුරු වර්ණ හමු වූ විට, අහඹු ලෙස ඒවායින් එකක් ගන්න.
    • කිසිවක් සොයාගත නොහැකි වූ විට, සෙවුම් පරාසය 5x5x5, 7x7x7 යනාදිය යාවත්කාලීන කරන්න. 5 සිට නැවත නැවත කරන්න.
  6. පික්සෙල් සැලසුම් කරන්න, ලැයිස්තුව යාවත්කාලීන කර 3 සිට නැවත කරන්න

තෝරාගත් පික්සෙල් වෙත කොපමණ අසල්වැසියන් පැමිණ ඇත්දැයි ගණනය කිරීම මත පදනම්ව අපේක්ෂක ලකුණු තෝරා ගැනීමේ විවිධ සම්භාවිතාවන් පිළිබඳව මම අත්හදා බැලුවෙමි, නමුත් එය ඇල්ගොරිතම මන්දගාමී නොවී මන්දගාමී විය. වත්මන් ඇල්ගොරිතම සම්භාවිතාව භාවිතා නොකරන අතර ලැයිස්තුවෙන් අහඹු ලක්ෂ්‍යයක් තෝරා ගනී. මෙය බොහෝ අසල්වැසියන් සමඟ ලකුණු ඉක්මනින් පිරවීමට හේතු වන අතර, එය නොපැහැදිලි දාරයක් සහිත වැඩෙන ball න බෝලයක් බවට පත් කරයි. මෙම ක්‍රියාවලියේදී පසුකාලීනව කුහර පිරවිය යුතු නම් අසල්වැසි වර්ණ නොලැබීමද මෙය වළක්වයි.

රූපය ටොරොයිඩ් වේ.

ජාවා

බාගත කරන්න: com.digitalmodularපුස්තකාලය

package demos;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.util.Arrays;

import com.digitalmodular.utilities.RandomFunctions;
import com.digitalmodular.utilities.gui.ImageFunctions;
import com.digitalmodular.utilities.swing.window.PixelImage;
import com.digitalmodular.utilities.swing.window.PixelWindow;

/**
 * @author jeronimus
 */
// Date 2014-02-28
public class AllColorDiffusion extends PixelWindow implements Runnable {
    private static final int    CHANNEL_BITS    = 7;

    public static void main(String[] args) {
        int bits = CHANNEL_BITS * 3;
        int heightBits = bits / 2;
        int widthBits = bits - heightBits;

        new AllColorDiffusion(CHANNEL_BITS, 1 << widthBits, 1 << heightBits);
    }

    private final int           width;
    private final int           height;
    private final int           channelBits;
    private final int           channelSize;

    private PixelImage          img;
    private javax.swing.Timer   timer;

    private boolean[]           colorCube;
    private long[]              foundColors;
    private boolean[]           queued;
    private int[]               queue;
    private int                 queuePointer    = 0;
    private int                 remaining;

    public AllColorDiffusion(int channelBits, int width, int height) {
        super(1024, 1024 * height / width);

        RandomFunctions.RND.setSeed(0);

        this.width = width;
        this.height = height;
        this.channelBits = channelBits;
        channelSize = 1 << channelBits;
    }

    @Override
    public void initialized() {
        img = new PixelImage(width, height);

        colorCube = new boolean[channelSize * channelSize * channelSize];
        foundColors = new long[channelSize * channelSize * channelSize];
        queued = new boolean[width * height];
        queue = new int[width * height];
        for (int i = 0; i < queue.length; i++)
            queue[i] = i;

        new Thread(this).start();
    }

    @Override
    public void resized() {}

    @Override
    public void run() {
        timer = new javax.swing.Timer(500, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                draw();
            }
        });

        while (true) {
            img.clear(0);
            init();
            render();
        }

        // System.exit(0);
    }

    private void init() {
        RandomFunctions.RND.setSeed(0);

        Arrays.fill(colorCube, false);
        Arrays.fill(queued, false);
        remaining = width * height;

        // Initial seeds (need to be the darkest colors, because of the darkest
        // neighbor color search algorithm.)
        setPixel(width / 2 + height / 2 * width, 0);
        remaining--;
    }

    private void render() {
        timer.start();

        for (; remaining > 0; remaining--) {
            int point = findPoint();
            int color = findColor(point);
            setPixel(point, color);
        }

        timer.stop();
        draw();

        try {
            ImageFunctions.savePNG(System.currentTimeMillis() + ".png", img.image);
        }
        catch (IOException e1) {
            e1.printStackTrace();
        }
    }

    void draw() {
        g.drawImage(img.image, 0, 0, getWidth(), getHeight(), 0, 0, width, height, null);
        repaintNow();
    }

    private int findPoint() {
        while (true) {
            // Time to reshuffle?
            if (queuePointer == 0) {
                for (int i = queue.length - 1; i > 0; i--) {
                    int j = RandomFunctions.RND.nextInt(i);
                    int temp = queue[i];
                    queue[i] = queue[j];
                    queue[j] = temp;
                    queuePointer = queue.length;
                }
            }

            if (queued[queue[--queuePointer]])
                return queue[queuePointer];
        }
    }

    private int findColor(int point) {
        int x = point & width - 1;
        int y = point / width;

        // Calculate the reference color as the average of all 8-connected
        // colors.
        int r = 0;
        int g = 0;
        int b = 0;
        int n = 0;
        for (int j = -1; j <= 1; j++) {
            for (int i = -1; i <= 1; i++) {
                point = (x + i & width - 1) + width * (y + j & height - 1);
                if (img.pixels[point] != 0) {
                    int pixel = img.pixels[point];

                    r += pixel >> 24 - channelBits & channelSize - 1;
                    g += pixel >> 16 - channelBits & channelSize - 1;
                    b += pixel >> 8 - channelBits & channelSize - 1;
                    n++;
                }
            }
        }
        r /= n;
        g /= n;
        b /= n;

        // Find a color that is preferably darker but not too far from the
        // original. This algorithm might fail to take some darker colors at the
        // start, and when the image is almost done the size will become really
        // huge because only bright reference pixels are being searched for.
        // This happens with a probability of 50% with 6 channelBits, and more
        // with higher channelBits values.
        //
        // Try incrementally larger distances from reference color.
        for (int size = 2; size <= channelSize; size *= 2) {
            n = 0;

            // Find all colors in a neighborhood from the reference color (-1 if
            // already taken).
            for (int ri = r - size; ri <= r + size; ri++) {
                if (ri < 0 || ri >= channelSize)
                    continue;
                int plane = ri * channelSize * channelSize;
                int dr = Math.abs(ri - r);
                for (int gi = g - size; gi <= g + size; gi++) {
                    if (gi < 0 || gi >= channelSize)
                        continue;
                    int slice = plane + gi * channelSize;
                    int drg = Math.max(dr, Math.abs(gi - g));
                    int mrg = Math.min(ri, gi);
                    for (int bi = b - size; bi <= b + size; bi++) {
                        if (bi < 0 || bi >= channelSize)
                            continue;
                        if (Math.max(drg, Math.abs(bi - b)) > size)
                            continue;
                        if (!colorCube[slice + bi])
                            foundColors[n++] = Math.min(mrg, bi) << channelBits * 3 | slice + bi;
                    }
                }
            }

            if (n > 0) {
                // Sort by distance from origin.
                Arrays.sort(foundColors, 0, n);

                // Find a random color amongst all colors equally distant from
                // the origin.
                int lowest = (int)(foundColors[0] >> channelBits * 3);
                for (int i = 1; i < n; i++) {
                    if (foundColors[i] >> channelBits * 3 > lowest) {
                        n = i;
                        break;
                    }
                }

                int nextInt = RandomFunctions.RND.nextInt(n);
                return (int)(foundColors[nextInt] & (1 << channelBits * 3) - 1);
            }
        }

        return -1;
    }

    private void setPixel(int point, int color) {
        int b = color & channelSize - 1;
        int g = color >> channelBits & channelSize - 1;
        int r = color >> channelBits * 2 & channelSize - 1;
        img.pixels[point] = 0xFF000000 | ((r << 8 | g) << 8 | b) << 8 - channelBits;

        colorCube[color] = true;

        int x = point & width - 1;
        int y = point / width;
        queued[point] = false;
        for (int j = -1; j <= 1; j++) {
            for (int i = -1; i <= 1; i++) {
                point = (x + i & width - 1) + width * (y + j & height - 1);
                if (img.pixels[point] == 0) {
                    queued[point] = true;
                }
            }
        }
    }
}
  • 512 × 512
  • මුල් 1 බීජ
  • තත්පර 1 යි

රූප විස්තරය මෙහි ඇතුළත් කරන්න

  • 2048 × 1024
  • 1920 × 1080 ඩෙස්ක්ටොප් එකට තරමක් ටයිල් කර ඇත
  • තත්පර 30 යි
  • ෆොටෝෂොප් හි සෘණ

රූප විස්තරය මෙහි ඇතුළත් කරන්න

  • 2048 × 1024
  • බීජ 8 ක්
  • තත්පර 27 යි

රූප විස්තරය මෙහි ඇතුළත් කරන්න

  • 512 × 512
  • අහඹු බීජ 40 ක්
  • තත්පර 6 යි

රූප විස්තරය මෙහි ඇතුළත් කරන්න

  • 4096 × 4096
  • 1 බීජ
  • ස්ට්රයික්ස් සැලකිය යුතු ලෙස තියුණු වේ (මාළු සෂිමි වලට කපා දැමිය හැකි බව පෙනේ)
  • එය මිනිත්තු 20 කින් අවසන් වූවාක් මෙන් පෙනේ, නමුත් ... කිසියම් හේතුවක් නිසා අවසන් කිරීමට අපොහොසත් විය, එබැවින් දැන් මම එක රැයකින් සමාන්තරව අවස්ථා 7 ක් ධාවනය කරමි.

[පහත බලන්න]

[සංස්කරණය කරන්න]
** පික්සෙල් තෝරා ගැනීමේ මගේ ක්‍රමය මුළුමනින්ම අහඹු නොවන බව මම සොයා ගතිමි. සෙවුම් අවකාශයේ අහඹු ලෙස ප්‍රේරණයක් තිබීම අහඹු හා සැබෑ අහඹු ලෙස වේගවත් වනු ඇතැයි මම සිතුවෙමි (මක්නිසාද යත් ලක්ෂ්‍යයක් අහම්බෙන් දෙවරක් තෝරා නොගනු ඇත. කෙසේ වෙතත් එය කෙසේ හෝ සැබෑ අහඹු ලෙස ප්‍රතිස්ථාපනය කිරීමෙන් මගේ රූපයේ වැඩි ශබ්ද නිදර්ශක ලබා ගනී.

[අක්ෂර 30,000 සීමාව ඉක්මවා ගිය නිසා 2 වන අනුවාදය කේතය ඉවත් කරන ලදි]

රූප විස්තරය මෙහි ඇතුළත් කරන්න

  • ආරම්භක සෙවුම් කියුබ් 5x5x5 දක්වා වැඩි කිරීම

රූප විස්තරය මෙහි ඇතුළත් කරන්න

  • ඊටත් වඩා විශාල, 9x9x9

රූප විස්තරය මෙහි ඇතුළත් කරන්න

  • හදිසි අනතුරු 1. ප්‍රේරණය අක්‍රීය කර ඇති බැවින් සෙවුම් අවකාශය සැමවිටම රේඛීය වේ.

රූප විස්තරය මෙහි ඇතුළත් කරන්න

  • හදිසි අනතුරු 2. ෆිෆෝ පෝලිමක් භාවිතා කරමින් නව සෙවුම් ක්‍රමයක් උත්සාහ කළා. තවමත් මෙය විශ්ලේෂණය කළ යුතු නමුත් එය බෙදා ගැනීම වටී යැයි මම සිතුවෙමි.

රූප විස්තරය මෙහි ඇතුළත් කරන්න

  • සෑම විටම කේන්ද්‍රයේ සිට භාවිතයට නොගත් පික්සල් X තුළ තෝරා ගැනීම
  • X 256 පියවරෙන් 0 සිට 8192 දක්වා පරාසයක පවතී

රූපය උඩුගත කළ නොහැක: "අපොයි! යම්කිසි නරක දෙයක් සිදුවී ඇත! එය ඔබ නොවේ, එය අපයි. මෙය අපගේ වරදකි." රූපය imgur සඳහා ඉතා විශාලයි. වෙනත් තැනක උත්සාහ කරනවා ...

රූප විස්තරය මෙහි ඇතුළත් කරන්න

digitalmodularපික්සෙල් හසුරුවන අනුපිළිවෙල තීරණය කිරීම සඳහා පුස්තකාලයේ මා සොයාගත් උපලේඛන පැකේජයක් සමඟ අත්හදා බැලීම (විසරණය වෙනුවට).

package demos;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.util.Arrays;

import com.digitalmodular.utilities.RandomFunctions;
import com.digitalmodular.utilities.gui.ImageFunctions;
import com.digitalmodular.utilities.gui.schedulers.ScheduledPoint;
import com.digitalmodular.utilities.gui.schedulers.Scheduler;
import com.digitalmodular.utilities.gui.schedulers.XorScheduler;
import com.digitalmodular.utilities.swing.window.PixelImage;
import com.digitalmodular.utilities.swing.window.PixelWindow;

/**
 * @author jeronimus
 */
// Date 2014-02-28
public class AllColorDiffusion3 extends PixelWindow implements Runnable {
    private static final int    CHANNEL_BITS    = 7;

    public static void main(String[] args) {

        int bits = CHANNEL_BITS * 3;
        int heightBits = bits / 2;
        int widthBits = bits - heightBits;

        new AllColorDiffusion3(CHANNEL_BITS, 1 << widthBits, 1 << heightBits);
    }

    private final int           width;
    private final int           height;
    private final int           channelBits;
    private final int           channelSize;

    private PixelImage          img;
    private javax.swing.Timer   timer;
    private Scheduler           scheduler   = new XorScheduler();

    private boolean[]           colorCube;
    private long[]              foundColors;

    public AllColorDiffusion3(int channelBits, int width, int height) {
        super(1024, 1024 * height / width);

        this.width = width;
        this.height = height;
        this.channelBits = channelBits;
        channelSize = 1 << channelBits;
    }

    @Override
    public void initialized() {
        img = new PixelImage(width, height);

        colorCube = new boolean[channelSize * channelSize * channelSize];
        foundColors = new long[channelSize * channelSize * channelSize];

        new Thread(this).start();
    }

    @Override
    public void resized() {}

    @Override
    public void run() {
        timer = new javax.swing.Timer(500, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                draw();
            }
        });

        // for (double d = 0.2; d < 200; d *= 1.2)
        {
            img.clear(0);
            init(0);
            render();
        }

        // System.exit(0);
    }

    private void init(double param) {
        // RandomFunctions.RND.setSeed(0);

        Arrays.fill(colorCube, false);

        // scheduler = new SpiralScheduler(param);
        scheduler.init(width, height);
    }

    private void render() {
        timer.start();

        while (scheduler.getProgress() != 1) {
            int point = findPoint();
            int color = findColor(point);
            setPixel(point, color);
        }

        timer.stop();
        draw();

        try {
            ImageFunctions.savePNG(System.currentTimeMillis() + ".png", img.image);
        }
        catch (IOException e1) {
            e1.printStackTrace();
        }
    }

    void draw() {
        g.drawImage(img.image, 0, 0, getWidth(), getHeight(), 0, 0, width, height, null);
        repaintNow();
        setTitle(Double.toString(scheduler.getProgress()));
    }

    private int findPoint() {
        ScheduledPoint p = scheduler.poll();

        // try {
        // Thread.sleep(1);
        // }
        // catch (InterruptedException e) {
        // }

        return p.x + width * p.y;
    }

    private int findColor(int point) {
        // int z = 0;
        // for (int i = 0; i < colorCube.length; i++)
        // if (!colorCube[i])
        // System.out.println(i);

        int x = point & width - 1;
        int y = point / width;

        // Calculate the reference color as the average of all 8-connected
        // colors.
        int r = 0;
        int g = 0;
        int b = 0;
        int n = 0;
        for (int j = -3; j <= 3; j++) {
            for (int i = -3; i <= 3; i++) {
                point = (x + i & width - 1) + width * (y + j & height - 1);
                int f = (int)Math.round(10000 * Math.exp((i * i + j * j) * -0.4));
                if (img.pixels[point] != 0) {
                    int pixel = img.pixels[point];

                    r += (pixel >> 24 - channelBits & channelSize - 1) * f;
                    g += (pixel >> 16 - channelBits & channelSize - 1) * f;
                    b += (pixel >> 8 - channelBits & channelSize - 1) * f;
                    n += f;
                }
                // System.out.print(f + "\t");
            }
            // System.out.println();
        }
        if (n > 0) {
            r /= n;
            g /= n;
            b /= n;
        }

        // Find a color that is preferably darker but not too far from the
        // original. This algorithm might fail to take some darker colors at the
        // start, and when the image is almost done the size will become really
        // huge because only bright reference pixels are being searched for.
        // This happens with a probability of 50% with 6 channelBits, and more
        // with higher channelBits values.
        //
        // Try incrementally larger distances from reference color.
        for (int size = 2; size <= channelSize; size *= 2) {
            n = 0;

            // Find all colors in a neighborhood from the reference color (-1 if
            // already taken).
            for (int ri = r - size; ri <= r + size; ri++) {
                if (ri < 0 || ri >= channelSize)
                    continue;
                int plane = ri * channelSize * channelSize;
                int dr = Math.abs(ri - r);
                for (int gi = g - size; gi <= g + size; gi++) {
                    if (gi < 0 || gi >= channelSize)
                        continue;
                    int slice = plane + gi * channelSize;
                    int drg = Math.max(dr, Math.abs(gi - g));
                    // int mrg = Math.min(ri, gi);
                    long srg = ri * 299L + gi * 436L;
                    for (int bi = b - size; bi <= b + size; bi++) {
                        if (bi < 0 || bi >= channelSize)
                            continue;
                        if (Math.max(drg, Math.abs(bi - b)) > size)
                            continue;
                        if (!colorCube[slice + bi])
                            // foundColors[n++] = Math.min(mrg, bi) <<
                            // channelBits * 3 | slice + bi;
                            foundColors[n++] = srg + bi * 114L << channelBits * 3 | slice + bi;
                    }
                }
            }

            if (n > 0) {
                // Sort by distance from origin.
                Arrays.sort(foundColors, 0, n);

                // Find a random color amongst all colors equally distant from
                // the origin.
                int lowest = (int)(foundColors[0] >> channelBits * 3);
                for (int i = 1; i < n; i++) {
                    if (foundColors[i] >> channelBits * 3 > lowest) {
                        n = i;
                        break;
                    }
                }

                int nextInt = RandomFunctions.RND.nextInt(n);
                return (int)(foundColors[nextInt] & (1 << channelBits * 3) - 1);
            }
        }

        return -1;
    }

    private void setPixel(int point, int color) {
        int b = color & channelSize - 1;
        int g = color >> channelBits & channelSize - 1;
        int r = color >> channelBits * 2 & channelSize - 1;
        img.pixels[point] = 0xFF000000 | ((r << 8 | g) << 8 | b) << 8 - channelBits;

        colorCube[color] = true;
    }
}
  • කෝණික (8)

රූප විස්තරය මෙහි ඇතුළත් කරන්න

  • කෝණික (64)

රූප විස්තරය මෙහි ඇතුළත් කරන්න

  • සී.ආර්.ටී.

රූප විස්තරය මෙහි ඇතුළත් කරන්න

  • ඩිටර්

රූප විස්තරය මෙහි ඇතුළත් කරන්න

  • මල් (5, X), එහිදී X = X × 1.2 පියවරෙන් X 0.5 සිට 20 දක්වා පරාසයක පවතී

රූප විස්තරය මෙහි ඇතුළත් කරන්න

  • මොඩ්

රූප විස්තරය මෙහි ඇතුළත් කරන්න

  • පයිතගරස්

රූප විස්තරය මෙහි ඇතුළත් කරන්න

  • රේඩියල්

රූප විස්තරය මෙහි ඇතුළත් කරන්න

  • අහඹුයි

රූප විස්තරය මෙහි ඇතුළත් කරන්න

  • ස්කෑන්ලයින්

රූප විස්තරය මෙහි ඇතුළත් කරන්න

  • සර්පිලාකාර (X), එහිදී X = X × 1.2 හි පියවර 0.1 සිට 200 දක්වා පරාසයක පවතී
  • එය රේඩියල් සිට කෝණික (5) අතර පරාසයක පවතින බව ඔබට දැකගත හැකිය.

රූප විස්තරය මෙහි ඇතුළත් කරන්න

  • බෙදුණු

රූප විස්තරය මෙහි ඇතුළත් කරන්න

  • SquareSpiral

රූප විස්තරය මෙහි ඇතුළත් කරන්න

  • XOR

රූප විස්තරය මෙහි ඇතුළත් කරන්න

නව අක්ෂි ආහාර

  • වර්ණ තේරීමේ බලපෑම max(r, g, b)

රූප විස්තරය මෙහි ඇතුළත් කරන්න

  • වර්ණ තේරීමේ බලපෑම min(r, g, b)
  • ඉහත සඳහන් කළ ආකාරයටම එකම අංග / විස්තර ඇති බව සලකන්න, විවිධ වර්ණවලින් පමණි! (එකම අහඹු බීජ)

රූප විස්තරය මෙහි ඇතුළත් කරන්න

  • වර්ණ තේරීමේ බලපෑම max(r, min(g, b))

රූප විස්තරය මෙහි ඇතුළත් කරන්න

  • අළු අගය අනුව වර්ණ තේරීමේ බලපෑම 299*r + 436*g + 114*b

රූප විස්තරය මෙහි ඇතුළත් කරන්න

  • වර්ණ තේරීමේ බලපෑම 1*r + 10*g + 100*b

රූප විස්තරය මෙහි ඇතුළත් කරන්න

  • වර්ණ තේරීමේ බලපෑම 100*r + 10*g + 1*b

රූප විස්තරය මෙහි ඇතුළත් කරන්න

  • 299*r + 436*g + 114*bබිටු 32 ක පූර්ණ සංඛ්‍යාවක් තුළ පිරී ඉතිරී යන විට ප්‍රීතිමත් අනතුරු

රූප විස්තරය මෙහි ඇතුළත් කරන්න රූප විස්තරය මෙහි ඇතුළත් කරන්න රූප විස්තරය මෙහි ඇතුළත් කරන්න

  • අළු අගය සහ රේඩියල් උපලේඛනය සහිත ප්‍රභේදය 3

රූප විස්තරය මෙහි ඇතුළත් කරන්න

  • මම මෙය නිර්මාණය කළ ආකාරය මට අමතක විය

රූප විස්තරය මෙහි ඇතුළත් කරන්න

  • සී.ආර්.ටී උපලේඛකයාට ප්‍රීතිමත් පූර්ණ සංඛ්‍යා පිටාර ගැලීමේ දෝෂයක් (ZIP යාවත්කාලීන කරන ලදි), මෙය අඩක් ආරම්භ කිරීමට හේතු විය, රූප 512 × 512, මධ්‍යයේ නොව. මෙය පෙනිය යුත්තේ මෙයයි:

රූප විස්තරය මෙහි ඇතුළත් කරන්න රූප විස්තරය මෙහි ඇතුළත් කරන්න

  • InverseSpiralScheduler(64) (නව)

රූප විස්තරය මෙහි ඇතුළත් කරන්න

  • තවත් XOR එකක්

රූප විස්තරය මෙහි ඇතුළත් කරන්න

  • පළමු සාර්ථක 4096 දෝෂ නිරාකරණයෙන් පසුව සිදු කරන්න. මම හිතන්නේ මෙය 3 වන අනුවාදය SpiralScheduler(1)හෝ වෙනත් දෙයක් විය

රූප විස්තරය මෙහි ඇතුළත් කරන්න (50MB !!)

  • අනුවාදය 1 4096, නමුත් මම අහම්බෙන් වර්ණ නිර්ණායක අතහැර දැමුවෙමි max()

රූප විස්තරය මෙහි ඇතුළත් කරන්න (50MB !!)

  • 4096, දැන් සමඟ min()
  • ඉහත සඳහන් කළ ආකාරයටම එකම අංග / විස්තර ඇති බව සලකන්න, විවිධ වර්ණවලින් පමණි! (එකම අහඹු බීජ)
  • වේලාව: එය පටිගත කිරීමට අමතක වූ නමුත් ගොනුවේ කාලරාමුව රූපයට පෙර මිනිත්තු 3 කට පසුව වේ

රූප විස්තරය මෙහි ඇතුළත් කරන්න (50MB !!)


සිසිල්. ඔබේ අවසාන ප්‍රතිරූපය මම විසි කරන දෙවන අදහසට සමානය, මගේ හැඟීම තිබුණත් මගේ තරම් හොඳ පෙනුමක් නැත. BTW, allrgb.com/diffusive හි සමාන සිසිල් එකක් තිබේ .
ජේසන් සී

එය තේ හැන්දක් ලෙස අදහස් කළ නමුත්, මම එය සංස්කරණය කළේ ධජය සලකුණු කර ගැනීමේ බියෙන්, එය පෙනෙන පරිදි සිදු විය :)
මාර්ක් ජෙරොනිමස්

2
අනතුරු පවා ලස්සනයි :). වර්ණ කියුබ් ඉතා හොඳ අදහසක් සේ පෙනේ, මගේ විදැහුම් වේගය මගේ හා සසඳන විට පුදුම සහගතය. Allrgb හි සමහර මෝස්තර වලට හොඳ විස්තරයක් ඇත, උදාහරණයක් ලෙස allrgb.com/dla. තවත් අත්හදා බැලීම් කිරීමට මට වැඩි කාලයක් තිබෙන්නට ඇතැයි මම ප්‍රාර්ථනා කරමි, බොහෝ හැකියාවන් ඇත ...
fejesjoco

මට බොහෝ දුරට අමතක වී ඇත, මම මගේ විශාල විදැහුම් කිහිපයක් උඩුගත කළෙමි. මම හිතන්නේ ඒවායින් එකක්, දේදුන්න දුම / තීන්ත ආලේප කිරීම, allrgb හි ඇති ඕනෑම දෙයකට වඩා හොඳයි :). මම එකඟ වෙමි, අනෙක් ඒවා එතරම් සිත් ඇදගන්නා සුළු නොවේ, ඒ නිසා මම ඔවුන්ගෙන් තවත් යමක් සෑදීමට වීඩියෝවක් සාදන ලදී :).
fejesjoco

ප්‍රභව කේතය සහ ඩිජිසොෆ්ට් පුස්තකාලයට සබැඳිය එක් කළ නිසා ඔබට ඇත්ත වශයෙන්ම මගේ කේතය සම්පාදනය කළ හැකිය
මාර්ක් ජෙරොනිමස්

72

C ++ w / Qt

මම ඔබට අනුවාදය දකිමි:

රූප විස්තරය මෙහි ඇතුළත් කරන්න

වර්ණ සඳහා සාමාන්‍ය බෙදා හැරීම භාවිතා කිරීම:

රූප විස්තරය මෙහි ඇතුළත් කරන්න රූප විස්තරය මෙහි ඇතුළත් කරන්න

හෝ පළමුව රතු / පැහැයෙන් වර්ග කර ඇත (කුඩා අපගමනය සමඟ):

රූප විස්තරය මෙහි ඇතුළත් කරන්න රූප විස්තරය මෙහි ඇතුළත් කරන්න

හෝ වෙනත් බෙදාහැරීම්:

රූප විස්තරය මෙහි ඇතුළත් කරන්න රූප විස්තරය මෙහි ඇතුළත් කරන්න

Cauchy ව්‍යාප්තිය (hsl / red):

රූප විස්තරය මෙහි ඇතුළත් කරන්න රූප විස්තරය මෙහි ඇතුළත් කරන්න

සැහැල්ලුබව අනුව වර්ග කළ තීරු (hsl):

රූප විස්තරය මෙහි ඇතුළත් කරන්න

යාවත්කාලීන කළ ප්‍රභව කේතය - 6 වන රූපය නිපදවයි:

int main() {
    const int c = 256*128;
    std::vector<QRgb> data(c);
    QImage image(256, 128, QImage::Format_RGB32);

    std::default_random_engine gen;
    std::normal_distribution<float> dx(0, 2);
    std::normal_distribution<float> dy(0, 1);

    for(int i = 0; i < c; ++i) {
        data[i] = qRgb(i << 3 & 0xF8, i >> 2 & 0xF8, i >> 7 & 0xF8);
    }
    std::sort(data.begin(), data.end(), [] (QRgb a, QRgb b) -> bool {
        return QColor(a).hsvHue() < QColor(b).hsvHue();
    });

    int i = 0;
    while(true) {
        if(i % 10 == 0) { //no need on every iteration
            dx = std::normal_distribution<float>(0, 8 + 3 * i/1000.f);
            dy = std::normal_distribution<float>(0, 4 + 3 * i/1000.f);
        }
        int x = (int) dx(gen);
        int y = (int) dy(gen);
        if(x < 256 && x >= 0 && y >= 0 && y < 128) {
            if(!image.pixel(x, y)) {
                image.setPixel(x, y, data[i]);
                if(i % (c/100) == 1) {
                    std::cout << (int) (100.f*i/c) << "%\n";
                }
                if(++i == c) break;
            }
        }
    }
    image.save("tmp.png");
    return 0;
}

හොඳට කලා. කෙසේ වෙතත්, image.pixel(x, y) == 0පළමු ස්ථානයේ ඇති පික්සෙල් අසමත් වී නැවත ලිවිය නොහැක.
මාර්ක් ජෙරොනිමස්

Om Zom-B: එයට හැකිය, නමුත් අන්තිම එක කළු වනු ඇත, එබැවින් එය නීති රීති වලට අනුකූල වේ ..
ජා-සී

රීති ගැටලුවක් නැත. මම හිතුවේ ඔයාට ඒක මඟ හැරෙන්න ඇති කියලා. 1 සිට ගණන් කළ හැකිය. මම ඔබේ අනෙක් අයට ආදරෙයි!
මාර්ක් ජෙරොනිමස්

Om Zom-B: ස්තූතියි, මම තවත් කිහිපයක් එකතු කළ හැකිය, මම එයට කැමතියි: P
Jaa-c

රවුම් දෙකක් ඇති තැනැත්තා සහ ඊට පහළින් ඇති තැනැත්තා වඳුරු මුහුණක් මෙන් පෙනේ.
ජේසන් සී

64

ජාවා හි:

import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Collections;
import java.util.LinkedList;

import javax.imageio.ImageIO;

public class ImgColor {

    private static class Point {
        public int x, y;
        public color c;

        public Point(int x, int y, color c) {
            this.x = x;
            this.y = y;
            this.c = c;
        }
    }

    private static class color {
        char r, g, b;

        public color(int i, int j, int k) {
            r = (char) i;
            g = (char) j;
            b = (char) k;
        }
    }

    public static LinkedList<Point> listFromImg(String path) {
        LinkedList<Point> ret = new LinkedList<>();
        BufferedImage bi = null;
        try {
            bi = ImageIO.read(new File(path));
        } catch (IOException e) {
            e.printStackTrace();
        }
        for (int x = 0; x < 4096; x++) {
            for (int y = 0; y < 4096; y++) {
                Color c = new Color(bi.getRGB(x, y));
                ret.add(new Point(x, y, new color(c.getRed(), c.getGreen(), c.getBlue())));
            }
        }
        Collections.shuffle(ret);
        return ret;
    }

    public static LinkedList<color> allColors() {
        LinkedList<color> colors = new LinkedList<>();
        for (int r = 0; r < 256; r++) {
            for (int g = 0; g < 256; g++) {
                for (int b = 0; b < 256; b++) {
                    colors.add(new color(r, g, b));
                }
            }
        }
        Collections.shuffle(colors);
        return colors;
    }

    public static Double cDelta(color a, color b) {
        return Math.pow(a.r - b.r, 2) + Math.pow(a.g - b.g, 2) + Math.pow(a.b - b.b, 2);
    }

    public static void main(String[] args) {
        BufferedImage img = new BufferedImage(4096, 4096, BufferedImage.TYPE_INT_RGB);
        LinkedList<Point> orig = listFromImg(args[0]);
        LinkedList<color> toDo = allColors();

        Point p = null;
        while (orig.size() > 0 && (p = orig.pop()) != null) {
            color chosen = toDo.pop();
            for (int i = 0; i < Math.min(100, toDo.size()); i++) {
                color c = toDo.pop();
                if (cDelta(c, p.c) < cDelta(chosen, p.c)) {
                    toDo.add(chosen);
                    chosen = c;
                } else {
                    toDo.add(c);
                }
            }
            img.setRGB(p.x, p.y, new Color(chosen.r, chosen.g, chosen.b).getRGB());
        }
        try {
            ImageIO.write(img, "PNG", new File(args[1]));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

සහ ආදාන රූපයක්:

ලෙමුර්

මම මේ වගේ දෙයක් ජනනය කරනවා:

ඇසිඩ්ලෙමූර්

සම්පීඩිත නොවන අනුවාදය මෙහි: https://www.mediafire.com/?7g3fetvaqhoqgh8

4096 ^ 2 රූපයක් කිරීමට මගේ පරිගණකයට දළ වශයෙන් මිනිත්තු 30 ක් ගත වේ, එය මගේ පළමු ක්‍රියාත්මක කිරීම සඳහා ගත වූ දින 32 තුළ විශාල දියුණුවක්.


1
ඕච්; දින 32 ක් විහිළුවක් ලෙස පෙනුනේ නැත ..... ප්‍රශස්තිකරණයට පෙර 4k හි ෆෙජෙස්ජොකොස් පිළිතුරේ සාමාන්‍ය ඇල්ගොරිතමයට මාස කිහිපයක්
ගතවනු ඇත

5
මම ඔහුගේ පන්ච් ඇහිබැමි වලට ආදරෙයි!
මට්ටමේ ගංගාව ශාන්ත

45

ජාවා බබල්සෝර්ට් සමඟ

(සාමාන්‍යයෙන් බබල්සෝර්ට් එතරම් කැමැත්තක් නොදක්වන නමුත් මෙම අභියෝගය සඳහා අවසානයේ එය භාවිතයට ගැනුනි. වර්ග කිරීම තෙරපෙන අතර සෑම එකක්ම වර්ග කර ඇති විට ඒවායේ වටිනාකමට 1 ක් එකතු විය.

එම විශාල ඉරි ඉවත් කර ගැනීම සඳහා මූලාශ්‍ර කේතය යාවත්කාලීන කරන ලදි
(යම් තරමක මැජික් අවශ්‍ය වේ: P)

class Pix
{
    public static void main(String[] devnull) throws Exception
    {
        int chbits=8;
        int colorsperchannel=1<<chbits;
        int xsize=4096,ysize=4096;
        System.out.println(colorsperchannel);
        int[] x = new int[xsize*ysize];//colorstream

        BufferedImage i = new BufferedImage(xsize,ysize, BufferedImage.TYPE_INT_RGB);
        List<Integer> temp = new ArrayList<>();
        for (int j = 0; j < 4096; j++)
        {
            temp.add(4096*j);
        }
        int[] temp2=new int[4096];

        Collections.shuffle(temp,new Random(9263));//intended :P looked for good one
        for (int j = 0; j < temp.size(); j++)
        {
            temp2[j]=(int)(temp.get(j));
        }
        x = spezbubblesort(temp2, 4096);
        int b=-1;
        int b2=-1;
        for (int j = 0; j < x.length; j++)
        {
            if(j%(4096*16)==0)b++;
            if(j%(4096)==0)b2++;
            int h=j/xsize;
            int w=j%xsize;
            i.setRGB(w, h, x[j]&0xFFF000|(b|(b2%16)<<8));
            x[j]=x[j]&0xFFF000|(b|(b2%16)<<8);
        }  

        //validator sorting and checking that all values only have 1 difference
        Arrays.sort(x);
        int diff=0;
        for (int j = 1; j < x.length; j++)
        {
            int ndiff=x[j]-x[j-1];
            if(ndiff!=diff)
            {
                System.out.println(ndiff);
            }
            diff=ndiff;

        }
        OutputStream out = new BufferedOutputStream(new FileOutputStream("RGB24.bmp"));
        ImageIO.write(i, "bmp", out);

    }
    public static int[] spezbubblesort(int[] vals,int lines)
    {
        int[] retval=new int[vals.length*lines];
        for (int i = 0; i < lines; i++)
        {
            retval[(i<<12)]=vals[0];
            for (int j = 1; j < vals.length; j++)
            {
                retval[(i<<12)+j]=vals[j];
                if(vals[j]<vals[j-1])
                {

                    int temp=vals[j-1];
                    vals[j-1]=vals[j];
                    vals[j]=temp;
                }
                vals[j-1]=vals[j-1]+1;
            }
            vals[lines-1]=vals[lines-1]+1;
        }
        return retval;
    }
}

ප්‍රති ult ලය:

පැරණි අනුවාදය

class Pix
{
    public static void main(String[] devnull) throws Exception
    {
        int[] x = new int[4096*4096];//colorstream
        int idx=0;
        BufferedImage i = new BufferedImage(4096, 4096, BufferedImage.TYPE_INT_RGB);
        //GENCODE
        List<Integer> temp = new ArrayList<>();
        for (int j = 0; j < 4096; j++)
        {
            temp.add(4096*j);
        }
        int[] temp2=new int[4096];

        Collections.shuffle(temp,new Random(9263));//intended :P looked for good one
        for (int j = 0; j < temp.size(); j++)
        {
            temp2[j]=(int)(temp.get(j));
        }
        x = spezbubblesort(temp2, 4096);
        for (int j = 0; j < x.length; j++)
        {
            int h=j/4096;
            int w=j%4096;
            i.setRGB(w, h, x[j]);
        }
        //validator sorting and checking that all values only have 1 difference
        Arrays.sort(x);
        int diff=0;
        for (int j = 1; j < x.length; j++)
        {
            int ndiff=x[j]-x[j-1];
            if(ndiff!=diff)
            {
                System.out.println(ndiff);
            }
            diff=ndiff;

        }
        OutputStream out = new BufferedOutputStream(new FileOutputStream("RGB24.bmp"));
        ImageIO.write(i, "bmp", out);
    }
    public static int[] spezbubblesort(int[] vals,int lines)
    {
        int[] retval=new int[vals.length*lines];
        for (int i = 0; i < lines; i++)
        {
            retval[(i<<12)]=vals[0];
            for (int j = 1; j < vals.length; j++)
            {
                retval[(i<<12)+j]=vals[j];
                if(vals[j]<vals[j-1])
                {

                    int temp=vals[j-1];
                    vals[j-1]=vals[j];
                    vals[j]=temp;
                }
                vals[j-1]=vals[j-1]+1;
            }
            vals[lines-1]=vals[lines-1]+1;
        }
        return retval;
    }
}

ප්‍රතිදාන පෙරදසුන


AllRGB පිටුවේ දැනටමත් QuickSort අනුවාදයක් ඇත.
මාර්ක් ජෙරොනිමස්

1
Om Zom-B Quicksort යනු බබල්සෝර්ට් වලට වඩා වෙනස් ඇල්ගොරිතමයකි
masterX244

43

සී

මට නොතේරෙන හේතු නිසා, සම්පූර්ණයෙන්ම වෙනස් සුළි අඩංගු ඉරට්ටේ හා අමුතු රාමු සහිත සුළි සුළඟක් නිර්මාණය කරයි.

මෙය පළමු අමුතු රාමු 50 ක පෙරදසුනක්:

සුළි පෙරදසුන

නියැදි රූපය පීපීඑම් සිට නිරූපණය දක්වා සම්පූර්ණ වර්ණ ආවරණය:

නියැදි රූපය

පසුකාලීනව, ඒ සියල්ල අළු පැහැයට හුරු වූ විට, ඔබට එය කැරකෙමින් පවතින බව දැකිය හැකිය: දිගු අනුක්‍රමය .

කේතය පහත පරිදි වේ. ධාවනය කිරීමට, රාමු අංකය ඇතුළත් කරන්න, උදා:

./vortex 35 > 35.ppm

සජීවිකරණ GIF ලබා ගැනීම සඳහා මම මෙය භාවිතා කළෙමි:

convert -delay 10 `ls * .ppm | sort -n | xargs` -loop 0 vortex.gif
#include <stdlib.h>
#include <stdio.h>

#define W 256
#define H 128

typedef struct {unsigned char r, g, b;} RGB;

int S1(const void *a, const void *b)
{
    const RGB *p = a, *q = b;
    int result = 0;

    if (!result)
        result = (p->b + p->g * 6 + p->r * 3) - (q->b + q->g * 6 + q->r * 3);

    return result;
}

int S2(const void *a, const void *b)
{
    const RGB *p = a, *q = b;
    int result = 0;

    if (!result)
        result = p->b * 6 - p->g;
    if (!result)
        result = p->r - q->r;
    if (!result)
        result = p->g - q->b * 6;

    return result;
}

int main(int argc, char *argv[])
{
    int i, j, n;
    RGB *rgb = malloc(sizeof(RGB) * W * H);
    RGB c[H];

    for (i = 0; i < W * H; i++)
    {
        rgb[i].b = (i & 0x1f) << 3;
        rgb[i].g = ((i >> 5) & 0x1f) << 3;
        rgb[i].r = ((i >> 10) & 0x1f) << 3;
    }

    qsort(rgb, H * W, sizeof(RGB), S1);

    for (n = 0; n < atoi(argv[1]); n++)
    {
        for (i = 0; i < W; i++)
        {
            for (j = 0; j < H; j++)
                c[j] = rgb[j * W + i];
            qsort(c, H, sizeof(RGB), S2);
            for (j = 0; j < H; j++)
                rgb[j * W + i] = c[j];
        }

        for (i = 0; i < W * H; i += W)
            qsort(rgb + i, W, sizeof(RGB), S2);
    }

    printf("P6 %d %d 255\n", W, H);
    fwrite(rgb, sizeof(RGB), W * H, stdout);

    free(rgb);

    return 0;
}

53
"මට තේරෙන්නේ නැති හේතු" නිසා යමක් සිදු වූ විට එය සී බව ඔබ දන්නවා.
නිට්

2
ඔව්, සාමාන්‍යයෙන් මම බලාපොරොත්තු විය යුතු දේ මම දනිමි, නමුත් මෙන්න මම ලබා ගත හැකි රටා මොනවාදැයි බැලීමට මම සෙල්ලම් කරමින් සිටියෙමි.

8
ඔබේ සංසන්දනාත්මක ශ්‍රිතය ත්‍රිකෝණ අසමානතාවය අනුගමනය නොකරන නිසා එය සුළි සුළඟට වැටේ. උදාහරණයක් ලෙස, r> b, b> g, g> r. මට එය ජාවා වෙත ගෙනයාමට පවා නොහැකි වන්නේ එය ඒකාබද්ධ කිරීම මෙම දේපල මත රඳා පවතින නිසාය, එබැවින් මට ව්‍යතිරේකය ලැබෙන්නේ "සංසන්දනය කිරීමේ ක්‍රමය එහි සාමාන්‍ය කොන්ත්‍රාත්තුව උල්ලං lates නය කරයි!"
මාර්ක් ජෙරොනිමස්

2
මම උත්සාහ කරමි, p->b * 6 - q->g;නමුත් එය සුළි සුළඟට හසු වුවහොත් එය නිවැරදි නොකරනු ඇත!

4
+1 මට නොතේරෙන හේතු නිසා.
ජේසන් සී

40

ජාවා

512x512 හි වර්ණ අච්චාරුවක විචලනයන්. අලංකාර කේතය එය නොවේ , නමුත් මම ලස්සන පින්තූර වලට කැමතියි:

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Random;

import javax.imageio.ImageIO;

public class EighteenBitColors {

    static boolean shuffle_block = false;
    static int shuffle_radius = 0;

    public static void main(String[] args) {
        BufferedImage img = new BufferedImage(512, 512, BufferedImage.TYPE_INT_RGB);
        for(int r=0;r<64;r++)
            for(int g=0;g<64;g++)
                for(int b=0;b<64;b++)
                    img.setRGB((r * 8) + (b / 8), (g * 8) + (b % 8), ((r * 4) << 8 | (g * 4)) << 8 | (b * 4));

        if(shuffle_block)
            blockShuffle(img);
        else
            shuffle(img, shuffle_radius);

        try {           
            ImageIO.write(img, "png", new File(getFileName()));
        } catch(IOException e){
            System.out.println("suck it");
        }
    }

    public static void shuffle(BufferedImage img, int radius){
        if(radius < 1)
            return;
        int width = img.getWidth();
        int height = img.getHeight();
        Random rand = new Random();
        for(int x=0;x<512;x++){
            for(int y=0;y<512;y++){
                int xx = -1;
                int yy = -1;
                while(xx < 0 || xx >= width){
                    xx = x + rand.nextInt(radius*2+1) - radius;
                }
                while(yy < 0 || yy >= height){
                    yy = y + rand.nextInt(radius*2+1) - radius;
                }
                int tmp = img.getRGB(xx, yy);
                img.setRGB(xx, yy, img.getRGB(x, y));
                img.setRGB(x,y,tmp);
            }
        }
    }

    public static void blockShuffle(BufferedImage img){
        int tmp;
        Random rand = new Random();
        for(int bx=0;bx<8;bx++){
            for(int by=0;by<8;by++){
                for(int x=0;x<64;x++){
                    for(int y=0;y<64;y++){
                        int xx = bx*64+x;
                        int yy = by*64+y;
                        int xxx = bx*64+rand.nextInt(64);
                        int yyy = by*64+rand.nextInt(64);
                        tmp = img.getRGB(xxx, yyy);
                        img.setRGB(xxx, yyy, img.getRGB(xx, yy));
                        img.setRGB(xx,yy,tmp);
                    }
                }
            }
        }
    }

    public static String getFileName(){
        String fileName = "allrgb_";
        if(shuffle_block){
            fileName += "block";
        } else if(shuffle_radius > 0){
            fileName += "radius_" + shuffle_radius;
        } else {
            fileName += "no_shuffle";
        }
        return fileName + ".png";
    }
}

ලියා ඇති පරිදි, එය ප්‍රතිදානය කරයි:

මාරු කිරීමක් නැත

ඔබ එය සමඟ ධාවනය කරන්නේ නම් shuffle_block = true , එය එක් එක් 64x64 බ්ලොක් වල වර්ණ මාරු කරයි:

අවහිර කිරීම අවහිර කරන්න

නැතහොත්, ඔබ එය සමඟ ධාවනය කරන්නේ නම් shuffle_radius > 0, එය එක් එක් පික්සෙල් shuffle_radiusx / y තුළ අහඹු පික්සෙල් සමඟ මාරු කරයි. විවිධ ප්‍රමාණයන් සමඟ සෙල්ලම් කිරීමෙන් පසු, මම පික්සල් 32 ක අරයකට කැමතියි, එය ඕනෑවට වඩා දේවල් චලනය නොකර රේඛා බොඳ කරයි:

රූප විස්තරය මෙහි ඇතුළත් කරන්න


3
අනේ මේ පින්තූර තමයි ලස්සනම
සෙවන්සෙකැට්

මේවා ඇත්තෙන්ම විශිෂ්ටයි 😍
මතෙව්

38

සැකසීම

මම දැන් සී සමඟ ආරම්භ කරමි (වෙනත් භාෂාවලින් ක්‍රමලේඛනය කර ඇති) නමුත් දෘශ්‍ය සී හි ග්‍රැෆික්ස් අනුගමනය කිරීම අසීරු බැවින් මම @ace භාවිතා කරන මෙම සැකසුම් වැඩසටහන බාගත කළෙමි.

මෙන්න මගේ කේතය සහ මගේ ඇල්ගොරිතම.

void setup(){
  size(256,128);
  background(0);
  frameRate(1000000000);
  noLoop();
 }

int x,y,r,g,b,c;
void draw() {
  for(y=0;y<128;y++)for(x=0;x<128;x++){
    r=(x&3)+(y&3)*4;
    g=x>>2;
    b=y>>2;
    c=0;
    //c=x*x+y*y<10000? 1:0; 
    stroke((r^16*c)<<3,g<<3,b<<3);
    point(x,y);
    stroke((r^16*(1-c))<<3,g<<3,b<<3);
    point(255-x,y);  
  } 
}

ඇල්ගොරිතම

X, y වලින් හරිත හා නිල් යන අගයන් 32 ක සංයෝජනයන්ගෙන් වර්ග 4x4 කින් ආරම්භ කරන්න. ආකෘතිය, 128x128 වර්ගයක් සෑදීම සෑම 4x4 වර්ගයකටම පික්සල් 16 ක් ඇත, එබැවින් පහත රූපයකට හරිත හා නිල් යන සෑම සංයෝජනයකින්ම පික්සල් 32 ක් ලබා දීම සඳහා දර්පණ රූපයක් සාදන්න.

(විකාරරූපී ලෙස සම්පූර්ණ සයන් වලට වඩා දීප්තිමත් කොළ පැහැය පෙනේ. මෙය දෘශ්‍ය මායාවක් විය යුතුය. අදහස් දැක්වීමේදී පැහැදිලි කර ඇත)

වම්පස චතුරස්රයේ, රතු අගයන් 0-15 එකතු කරන්න. රයිට්හැන්ඩ් චතුරස්රය සඳහා, XOR මෙම අගයන් 16 සමඟ, අගයන් 16-31 බවට පත් කරන්න.

රූප විස්තරය මෙහි ඇතුළත් කරන්න

නිමැවුම් 256x128

මෙය පහළ රූපයේ ප්‍රතිදානය ලබා දෙයි.

කෙසේ වෙතත්, සෑම පික්සෙල් එකක්ම එහි දර්පණ රූපයට වඩා වෙනස් වන්නේ රතු අගයේ වඩාත්ම වැදගත් ප්‍රමාණයෙන් පමණි. ඉතින්, මට විචල්‍යය සමඟ කොන්දේසියක් යෙදිය හැකියc මෙම පික්සෙල් දෙක හුවමාරු කර ගැනීමට සමාන බලපෑමක් ඇති XOR ආපසු හැරවීමට මට .

මේ සඳහා උදාහරණයක් පහත රූපයේ දක්වා ඇත (දැනට අදහස් දක්වා ඇති කේත රේඛාව අප විසින් ඉවත් නොකළහොත්.)

රූප විස්තරය මෙහි ඇතුළත් කරන්න

512 x 512 - ඇන්ඩි වෝර්හෝල්ගේ මේරිලින්ට උපහාරයක්

ෆ්‍රීහැන්ඩ් රතු කව වල “නපුරු සිනහවක්” සහිතව මෙම ප්‍රශ්නයට ක්වින්කන්ක්ස් දුන් පිළිතුරෙන් ආශ්වාදයක් ලද, මෙන්න මගේ ජනප්‍රිය පින්තූරයේ අනුවාදය. මුල් පිටපතෙහි ඇත්ත වශයෙන්ම වර්ණ මේරිලින් 25 ක් සහ කළු සහ සුදු මේරිලින් 25 ක් තිබූ අතර ඇයගේ අකල් මරණයෙන් පසු වෝර්හෝල් මේරිලින්ට උපහාරයක් විය. Http://en.wikipedia.org/wiki/Mrallyn_Diptych බලන්න

සැකසුම් මඟින් 256x128 හි මා භාවිතා කළ ඒවා අර්ධ පාරදෘශ්‍ය බව පෙන්වන බව දැන ගැනීමෙන් පසුව මම විවිධ කාර්යයන් වෙත වෙනස් කළෙමි. අළුත් ඒවා පාරාන්ධයි.

රූපය සම්පූර්ණයෙන්ම ඇල්ගොරිතම නොවුනත් මම එයට කැමතියි.

int x,y,r,g,b,c;
PImage img;
color p;
void setup(){
  size(512,512);
  background(0);
  img = loadImage("marylin256.png");
  frameRate(1000000000);
  noLoop();
 }

void draw() {

   image(img,0,0);

   for(y=0;y<256;y++)for(x=0;x<256;x++){
      // Note the multiplication by 0 in the next line. 
      // Replace the 0 with an 8 and the reds are blended checkerboard style
      // This reduces the grain size, but on balance I decided I like the grain.
      r=((x&3)+(y&3)*4)^0*((x&1)^(y&1));
      g=x>>2;
      b=y>>2; 
      c=brightness(get(x,y))>100? 32:0;
      p=color((r^c)<<2,g<<2,b<<2);
      set(x,y,p);
      p=color((r^16^c)<<2,g<<2,b<<2);
      set(256+x,y,p);  
      p=color((r^32^c)<<2,g<<2,b<<2);
      set(x,256+y,p);
      p=color((r^48^c)<<2,g<<2,b<<2);
      set(256+x,256+y,p);  
 } 
 save("warholmarylin.png");

}

රූප විස්තරය මෙහි ඇතුළත් කරන්න

512x512 දුරින් කඳු සහිත විලක් උඩින්

මෙන්න, සම්පූර්ණ ඇල්ගොරිතම පින්තූරයක්. කොන්දේසිය සමඟ මා මොඩියුලේට් කරන වර්ණය වෙනස් කිරීම සමඟ මම සෙල්ලම් කර ඇත, නමුත් රතු පැහැය වඩාත් හොඳින් ක්‍රියාත්මක වන බව මම නැවත නිගමනය කරමි. මේරිලින් පින්තූරයට සමානව, මම පළමුව කඳු අඳින්නෙමි, ඉන්පසු එම පින්තූරයෙන් දීප්තිය තෝරාගෙන ධනාත්මක RGB රූපය නැවත ලිවීමටත්, සෘණ භාගයට පිටපත් කිරීමටත්. සුළු වෙනසක් නම්, බොහෝ කඳුකරයේ පතුල (ඒවා සියල්ලම එකම ප්‍රමාණයෙන් ඇද ඇති නිසා) කියවන ප්‍රදේශයට පහළින් විහිදෙන බැවින් කියවීමේ ක්‍රියාවලියේදී මෙම ප්‍රදේශය සරලව කපා ඇත (එම නිසා විවිධ ප්‍රමාණයේ කඳුකරයේ අපේක්ෂිත හැඟීම ලබා දෙයි. )

මෙහි දී මම ධනාත්මක සඳහා රතු 32 කින් යුත් 8x4 සෛලයක් ද, රතු 32 the ණ සඳහා ද භාවිතා කරමි.

මගේ කේතයේ අවසානයේ ඇති රාමුව (1) යන විධාන විධාන සටහන් කරන්න. මෙම විධානය නොමැතිව, සැකසුම් මගේ CPU හි එක් හරයකින් 100% ක් භාවිතා කරනු ඇති බව මම සොයා ගතිමි. මට කිව හැකි පරිදි නින්දේ ක්‍රියාකාරිත්වයක් නොමැත, ඔබට කළ හැක්කේ ඡන්දය ප්‍රකාශ කිරීමේ වාර ගණන අඩු කිරීමයි.

int i,j,x,y,r,g,b,c;
PImage img;
color p;
void setup(){
  size(512,512);
  background(255,255,255);
  frameRate(1000000000);
  noLoop();
 }

void draw() {
  for(i=0; i<40; i++){
    x=round(random(512));
    y=round(random(64,256));
    for(j=-256; j<256; j+=12) line(x,y,x+j,y+256);  
  }
  for(y=0;y<256;y++)for(x=0;x<512;x++){
    r=(x&7)+(y&3)*8;
    b=x>>3;
    g=(255-y)>>2;
    c=brightness(get(x,y))>100? 32:0;
    p=color((r^c)<<2,g<<2,b<<2);
    set(x,y,p);
    p=color((r^32^c)<<2,g<<2,b<<2);
    set(x,511-y,p);  
  }
  save("mountainK.png");
  frameRate(1);
}

රූප විස්තරය මෙහි ඇතුළත් කරන්න


එය කිසිසේත් සම්පූර්ණ සයන් නොවන නිසා. එය (0,217,217). [0,255] දිගු නොකලත්, සංයෝජන 32 ම පවතී. සංස්කරණය කරන්න: ඔබ 7 පියවර භාවිතා කරයි, නමුත් මට මෙය කේතයෙන් සොයාගත නොහැක. සැකසුම් දෙයක් විය යුතුය.
මාර්ක් ජෙරොනිමස්

framesteveverrill සැකසීමේදී, save("filename.png")වත්මන් රාමු බෆරය රූපයකට සුරැකීමට ඔබට කළ හැකිය . වෙනත් රූප ආකෘති සඳහාද සහය දක්වයි. එය තිරපිටපත් ගැනීමේ කරදරයෙන් ඔබව ගලවා ගනු ඇත. රූපය ස්කෙච් ෆෝල්ඩරයට සුරකින ලදි.
ජේසන් සී

Ason ජේසන් ටිප් එකට ස්තූතියි, මට විශ්වාසයි ක්‍රමයක් තිබිය යුතුයි, නමුත් මම හිතන්නේ නැහැ මම මේවා සංස්කරණය කරන්නම්. මම පින්තූර වටා රාමුව අර්ධ වශයෙන් වෙන් කර තැබුවෙමි (එවැනි කුඩා පින්තූර සඳහා ලිපිගොනු 2 ක් අධික විය.) මට 512x512 හි පින්තූර කිහිපයක් කිරීමට අවශ්‍යය (විශේෂයෙන් මට අදහසක් ඇත) එබැවින් මම ඒවා උඩුගත කරමි ඔබ යෝජනා කරනවා.
මට්ටම් ගංගාව ශාන්ත

1
@steveverrill Haha, Warhols කදිම ස්පර්ශයකි.
ජේසන් සී

Om Zom-B සැකසුම් එහි ප්‍රලේඛනයේ සඳහන් කර නැති (කරදරකාරී ලෙස) බොහෝ දේ කරන බව පෙනේ: එහි භෞතික නිමැවුමේ සම්පූර්ණ 256 තාර්කික වර්ණ නාලිකා අගයන් භාවිතා නොකිරීම, ඔබට අවශ්‍ය නොවන විට වර්ණ මිශ්‍ර කිරීම, සම්පූර්ණ හරයක් භාවිතා කිරීම මගේ CPU ඇඳීම අවසන් වූ පසුවත්. තවමත් එයට ඇතුල් වීම ඉතා සරල වන අතර ඔබට ඒවා ඇති බව දැනගත් පසු ඔබට ඒවා විසඳා ගත හැකිය (පළමු එක හැර, මම තවම එය විසඳා නැත ...)
ලෙවල් රිවර් ශාන්ත

35

මම ජාවාස්ක්‍රිප්ට් හි හිල්බට් වක්‍රය මත බිට් 16 වර්ණ (5r, 6g, 5b) සකසා ඇත.

හිල්බට් වක්‍ර වර්ණ

පෙර, (හිල්බට් වක්‍රය නොවේ) රූපය:

හිල්බට් වක්රය

JSfiddle: jsfiddle.net/LCsLQ/3

ජාවාස්ක්‍රිප්ට්

// ported code from http://en.wikipedia.org/wiki/Hilbert_curve
function xy2d (n, p) {
    p = {x: p.x, y: p.y};
    var r = {x: 0, y: 0},
        s,
        d=0;
    for (s=(n/2)|0; s>0; s=(s/2)|0) {
        r.x = (p.x & s) > 0 ? 1 : 0;
        r.y = (p.y & s) > 0 ? 1 : 0;
        d += s * s * ((3 * r.x) ^ r.y);
        rot(s, p, r);
    }
    return d;
}

//convert d to (x,y)
function d2xy(n, d) {
    var r = {x: 0, y: 0},
        p = {x: 0, y: 0},
        s,
        t=d;
    for (s=1; s<n; s*=2) {
        r.x = 1 & (t/2);
        r.y = 1 & (t ^ rx);
        rot(s, p, r);
        p.x += s * r.x;
        p.y += s * r.y;
        t /= 4;
    }
    return p;
}

//rotate/flip a quadrant appropriately
function rot(n, p, r) {
    if (r.y === 0) {
        if (r.x === 1) {
            p.x = n-1 - p.x;
            p.y = n-1 - p.y;
        }

        //Swap x and y
        var t  = p.x;
        p.x = p.y;
        p.y = t;
    }
}
function v2rgb(v) {
    return ((v & 0xf800) << 8) | ((v & 0x7e0) << 5) | ((v & 0x1f) << 3); 
}
function putData(arr, size, coord, v) {
    var pos = (coord.x + size * coord.y) * 4,
        rgb = v2rgb(v);

    arr[pos] = (rgb & 0xff0000) >> 16;
    arr[pos + 1] = (rgb & 0xff00) >> 8;
    arr[pos + 2] = rgb & 0xff;
    arr[pos + 3] = 0xff;
}
var size = 256,
    context = a.getContext('2d'),
    data = context.getImageData(0, 0, size, size);

for (var i = 0; i < size; i++) {
    for (var j = 0; j < size; j++) {
        var p = {x: j, y: i};
        putData(data.data, size, p, xy2d(size, p));
    }
}
context.putImageData(data, 0, 0);

සංස්කරණය කරන්න : හිල්බට් වක්‍රය ගණනය කිරීම සඳහා මගේ ශ්‍රිතයේ දෝෂයක් ඇති බවත් එය වැරදියි; එනම්, ලෙස r.x = (p.x & s) > 0; r.y = (p.y & s) > 0;වෙනස් කර ඇතr.x = (p.x & s) > 0 ? 1 : 0; r.y = (p.y & s) > 0 ? 1 : 0;

සංස්කරණය 2: තවත් අස්ථියක්:

sierpinsky

http://jsfiddle.net/jej2d/5/


හොඳයි! PPCG වෙත සාදරයෙන් පිළිගනිමු.
ජොනතන් වැන් මැට්රේ

වර්ණ කියුබ් හරහා ඇවිදින විට ත්‍රිමාණ හිල්බට් වක්‍රය පෙනෙන්නේ කෙසේද? සංස්කරණය කරන්න nm. කවුරුහරි එහෙම කළා.
මාර්ක් ජෙරොනිමස්

35

සී #: දේශීය දේශීය සමානතා ප්‍රශස්තිකරණය

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

namespace AllColors
{
    class Program
    {
        static Random _random = new Random();

        const int ImageWidth = 256;
        const int ImageHeight = 128;
        const int PixelCount = ImageWidth * ImageHeight;
        const int ValuesPerChannel = 32;
        const int ChannelValueDelta = 256 / ValuesPerChannel;

        static readonly int[,] Kernel;
        static readonly int KernelWidth;
        static readonly int KernelHeight;

        static Program()
        {
            // Version 1
            Kernel = new int[,] { { 0, 1, 0, },
                                  { 1, 0, 1, },
                                  { 0, 1, 0, } };
            // Version 2
            //Kernel = new int[,] { { 0, 0, 1, 0, 0 },
            //                      { 0, 2, 3, 2, 0 },
            //                      { 1, 3, 0, 3, 1 },
            //                      { 0, 2, 3, 2, 0 },
            //                      { 0, 0, 1, 0, 0 } };
            // Version 3
            //Kernel = new int[,] { { 3, 0, 0, 0, 3 },
            //                      { 0, 1, 0, 1, 0 },
            //                      { 0, 0, 0, 0, 0 },
            //                      { 0, 1, 0, 1, 0 },
            //                      { 3, 0, 0, 0, 3 } };
            // Version 4
            //Kernel = new int[,] { { -9, -9, -9, -9, -9 },
            //                      {  1,  2,  3,  2,  1 },
            //                      {  2,  3,  0,  3,  2 },
            //                      {  1,  2,  3,  2,  1 },
            //                      {  0,  0,  0,  0,  0 } };
            // Version 5
            //Kernel = new int[,] { { 0, 0, 1, 0, 0, 0, 0 },
            //                      { 0, 1, 2, 1, 0, 0, 0 },
            //                      { 1, 2, 3, 0, 1, 0, 0 },
            //                      { 0, 1, 2, 0, 0, 0, 0 },
            //                      { 0, 0, 1, 0, 0, 0, 0 } };
            KernelWidth = Kernel.GetLength(1);
            KernelHeight = Kernel.GetLength(0);

            if (KernelWidth % 2 == 0 || KernelHeight % 2 == 0)
            {
                throw new InvalidOperationException("Invalid kernel size");
            }
        }

        private static Color[] CreateAllColors()
        {
            int i = 0;
            Color[] colors = new Color[PixelCount];
            for (int r = 0; r < ValuesPerChannel; r++)
            {
                for (int g = 0; g < ValuesPerChannel; g++)
                {
                    for (int b = 0; b < ValuesPerChannel; b++)
                    {
                        colors[i] = Color.FromArgb(255, r * ChannelValueDelta, g * ChannelValueDelta, b * ChannelValueDelta);
                        i++;
                    }
                }
            }
            return colors;
        }

        private static void Shuffle(Color[] colors)
        {
            // Knuth-Fisher-Yates shuffle
            for (int i = colors.Length - 1; i > 0; i--)
            {
                int n = _random.Next(i + 1);
                Swap(colors, i, n);
            }
        }

        private static void Swap(Color[] colors, int index1, int index2)
        {
            var temp = colors[index1];
            colors[index1] = colors[index2];
            colors[index2] = temp;
        }

        private static Bitmap ToBitmap(Color[] pixels)
        {
            Bitmap bitmap = new Bitmap(ImageWidth, ImageHeight);
            int x = 0;
            int y = 0;
            for (int i = 0; i < PixelCount; i++)
            {
                bitmap.SetPixel(x, y, pixels[i]);
                x++;
                if (x == ImageWidth)
                {
                    x = 0;
                    y++;
                }
            }
            return bitmap;
        }

        private static int GetNeighborDelta(Color[] pixels, int index1, int index2)
        {
            return GetNeighborDelta(pixels, index1) + GetNeighborDelta(pixels, index2);
        }

        private static int GetNeighborDelta(Color[] pixels, int index)
        {
            Color center = pixels[index];
            int sum = 0;
            for (int x = 0; x < KernelWidth; x++)
            {
                for (int y = 0; y < KernelHeight; y++)
                {
                    int weight = Kernel[y, x];
                    if (weight == 0)
                    {
                        continue;
                    }

                    int xOffset = x - (KernelWidth / 2);
                    int yOffset = y - (KernelHeight / 2);
                    int i = index + xOffset + yOffset * ImageWidth;

                    if (i >= 0 && i < PixelCount)
                    {
                        sum += GetDelta(pixels[i], center) * weight;
                    }
                }
            }

            return sum;
        }

        private static int GetDelta(Color c1, Color c2)
        {
            int sum = 0;
            sum += Math.Abs(c1.R - c2.R);
            sum += Math.Abs(c1.G - c2.G);
            sum += Math.Abs(c1.B - c2.B);
            return sum;
        }

        private static bool TryRandomSwap(Color[] pixels)
        {
            int index1 = _random.Next(PixelCount);
            int index2 = _random.Next(PixelCount);

            int delta = GetNeighborDelta(pixels, index1, index2);
            Swap(pixels, index1, index2);
            int newDelta = GetNeighborDelta(pixels, index1, index2);

            if (newDelta < delta)
            {
                return true;
            }
            else
            {
                // Swap back
                Swap(pixels, index1, index2);
                return false;
            }
        }

        static void Main(string[] args)
        {
            string fileNameFormat = "{0:D10}.png";
            var image = CreateAllColors();
            ToBitmap(image).Save("start.png");
            Shuffle(image);
            ToBitmap(image).Save(string.Format(fileNameFormat, 0));

            long generation = 0;
            while (true)
            {
                bool swapped = TryRandomSwap(image);
                if (swapped)
                {
                    generation++;
                    if (generation % 1000 == 0)
                    {
                        ToBitmap(image).Save(string.Format(fileNameFormat, generation));
                    }
                }
            }
        }
    }
}

අදහස

පළමුව අපි අහඹු මාරුවකින් ආරම්භ කරමු:

රූප විස්තරය මෙහි ඇතුළත් කරන්න

එවිට අපි අහඹු ලෙස පික්සල් දෙකක් තෝරා ඒවා මාරු කරමු. මෙය ඔවුන්ගේ අසල්වැසියන්ට පික්සෙල් වල සමානතාව වැඩි නොකරන්නේ නම්, අපි ආපසු මාරු වී නැවත උත්සාහ කරමු. අපි මෙම ක්‍රියාවලිය නැවත නැවතත් සිදු කරමු.

පරම්පරා කිහිපයකට පසු (5000) වෙනස්කම් එතරම් පැහැදිලි නැත ...

රූප විස්තරය මෙහි ඇතුළත් කරන්න

නමුත් එය වැඩි කාලයක් ධාවනය වේ (25000), ...

රූප විස්තරය මෙහි ඇතුළත් කරන්න

... වඩාත් නිශ්චිත රටාවන් මතුවීමට පටන් ගනී (100000).

රූප විස්තරය මෙහි ඇතුළත් කරන්න

අසල්වැසි ප්‍රදේශ සඳහා විවිධ අර්ථකථන භාවිතා කරමින් , අපට මෙම රටාවන්ට බලපෑම් කළ හැකි අතර ඒවා ස්ථායීද නැද්ද යන්න. මෙම Kernelකිරීමට සමාන න්යාසය වේ රූප සැකසීම දී පෙරහන් සඳහා භාවිතා අය . එය RGB ඩෙල්ටා ගණනය කිරීම සඳහා භාවිතා කරන එක් එක් අසල්වැසියාගේ බර නියම කරයි.

ප්රතිපල

මෙන්න මම නිර්මාණය කළ ප්රති results ල කිහිපයක්. වීඩියෝ මඟින් පුනරාවර්තන ක්‍රියාවලිය පෙන්වයි (1 රාමුව == පරම්පරා 1000), නමුත් කනගාටුදායක ලෙස ගුණාත්මකභාවය හොඳම නොවේ (විමියෝ, යූ ටියුබ් යනාදිය එවැනි කුඩා මානයන් සඳහා නිසි ලෙස සහාය නොදක්වයි). මම පසුව වඩා හොඳ තත්ත්වයේ වීඩියෝ නිර්මාණය කිරීමට උත්සාහ කළ හැකිය.

0 1 0
1 X 1
0 1 0

පරම්පරා 185000:

රූප විස්තරය මෙහි ඇතුළත් කරන්න වීඩියෝ (00:06)


0 0 1 0 0
0 2 3 2 0
1 3 X 3 1
0 2 3 2 0
0 0 1 0 0

පරම්පරා 243000:

රූප විස්තරය මෙහි ඇතුළත් කරන්න වීඩියෝ (00:07)


3 0 0 0 3
0 1 0 1 0
0 0 X 0 0
0 1 0 1 0
3 0 0 0 3

පරම්පරා 230000:

රූප විස්තරය මෙහි ඇතුළත් කරන්න වීඩියෝ (00:07)


0 0 1 0 0 0 0
0 1 2 1 0 0 0
1 2 3 X 1 0 0
0 1 2 0 0 0 0
0 0 1 0 0 0 0

මෙම කර්නලය සිත්ගන්නා සුළු වන්නේ එහි අසමමිතිය නිසා රටා ස්ථායී නොවන අතර පරම්පරාවන් ගත වන විට සමස්ත රූපය දකුණට ගමන් කරන බැවිනි.

පරම්පරා 2331000:

රූප විස්තරය මෙහි ඇතුළත් කරන්න වීඩියෝ (01:10)


විශාල ප්‍රති Results ල (512x512)

විශාල රූප මානයක් සහිත ඉහත කර්නල් භාවිතා කිරීමෙන් එකම දේශීය රටා නිර්මාණය වන අතර විශාල ප්‍රදේශයක් පුරා විහිදේ. 512x512 රූපයක් ස්ථාවර වීමට පරම්පරා මිලියන 1 ත් 2 ත් අතර කාලයක් ගතවේ.

රූප විස්තරය මෙහි ඇතුළත් කරන්න රූප විස්තරය මෙහි ඇතුළත් කරන්න රූප විස්තරය මෙහි ඇතුළත් කරන්න


හරි, දැන් අපි බැරෑරුම් ලෙස සලකා 15x15 රේඩියල් කර්නලයක් සහිත විශාල, අඩු දේශීය රටා නිර්මාණය කරමු:

0 0 0 0 0 1 1 1 1 1 0 0 0 0 0
0 0 0 1 1 2 2 2 2 2 1 1 0 0 0
0 0 1 2 2 3 3 3 3 3 2 2 1 0 0
0 1 2 2 3 4 4 4 4 4 3 2 2 1 0
0 1 2 3 4 4 5 5 5 4 4 3 2 1 0
1 2 3 4 4 5 6 6 6 5 4 4 3 2 1
1 2 3 4 5 6 7 7 7 6 5 4 3 2 1
1 2 3 4 5 6 7 X 7 6 5 4 3 2 1
1 2 3 4 5 6 7 7 7 6 5 4 3 2 1
1 2 3 4 4 5 6 6 6 5 4 4 3 2 1
0 1 2 3 4 4 5 5 5 4 4 3 2 1 0
0 1 2 2 3 4 4 4 4 4 3 2 2 1 0
0 0 1 2 2 3 3 3 3 3 2 2 1 0 0
0 0 0 1 1 2 2 2 2 2 1 1 0 0 0
0 0 0 0 0 1 1 1 1 1 0 0 0 0 0

මෙය එක් පරම්පරාවකට ගණනය කිරීමේ කාලය විශාල ලෙස වැඩි කරයි. පරම්පරා මිලියන 1.71 ක් සහ පැය 20 කට පසුව:

රූප විස්තරය මෙහි ඇතුළත් කරන්න


1
එහි යාමට ටික වේලාවක් ගත වේ, නමුත් අවසාන ප්‍රති result ලය තරමක් හොඳයි.
primo

සිත්ගන්නාසුලු අහඹු සිදුවීමකි, මට මෙම මාතෘකාව පිළිබඳ ලිපියක් ඇත: nayuki.io/page/simulated-annealing-demo
නායුකි

31

ජාවා

මගේ අනෙක් පිළිතුරෙහි වෙනස්කම් කිහිපයක් සමඟ, අපට ඉතා රසවත් ප්‍රතිදානයන් ලබා ගත හැකිය.

import java.awt.Point;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Random;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;

/**
 *
 * @author Quincunx
 */
public class AllColorImage {

    public static void main(String[] args) {
        BufferedImage img = new BufferedImage(4096, 4096, BufferedImage.TYPE_INT_RGB);

        int num = 0;
        ArrayList<Point> points = new ArrayList<>();
        for (int y = 0; y < 4096; y++) {
            for (int x = 0; x < 4096; x++) {
                points.add(new Point(x, y));
            }
        }
        Collections.sort(points, new Comparator<Point>() {

            @Override
            public int compare(Point t, Point t1) {
                int compareVal = (Integer.bitCount(t.x) + Integer.bitCount(t.y))
                        - (Integer.bitCount(t1.x) + Integer.bitCount(t1.y));
                return compareVal < 0 ? -1 : compareVal == 0 ? 0 : 1;
            }

        });
        for (Point p : points) {
            int x = p.x;
            int y = p.y;

            img.setRGB(x, y, num);
            num++;
        }
        try {
            ImageIO.write(img, "png", new File("Filepath"));
        } catch (IOException ex) {
            Logger.getLogger(AllColorImage.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}

වැදගත් කේතය මෙහි ඇත:

Collections.sort(points, new Comparator<Point>() {

    @Override
    public int compare(Point t, Point t1) {
        int compareVal = (Integer.bitCount(t.x) + Integer.bitCount(t.y))
                - (Integer.bitCount(t1.x) + Integer.bitCount(t1.y));
        return compareVal < 0 ? -1 : compareVal == 0 ? 0 : 1;
    }

});

ප්‍රතිදානය (තිර රුව):

රූප විස්තරය මෙහි ඇතුළත් කරන්න

සංසන්දකය මේ සඳහා වෙනස් කරන්න:

public int compare(Point t, Point t1) {
    int compareVal = (Integer.bitCount(t.x + t.y))
            - (Integer.bitCount(t1.x + t1.y));
    return compareVal < 0 ? -1 : compareVal == 0 ? 0 : 1;
}

අපට මෙය ලැබේ:

රූප විස්තරය මෙහි ඇතුළත් කරන්න

තවත් විචලනය:

public int compare(Point t, Point t1) {
    int compareVal = (t.x + t.y)
            - (t1.x + t1.y);
    return compareVal < 0 ? -1 : compareVal == 0 ? 0 : 1;
}

රූප විස්තරය මෙහි ඇතුළත් කරන්න

තවත් විචල්‍යතාවයක් (සෛලීය ස්වයංක්‍රීය යන්ත්‍රය මට මතක් කර දෙයි):

public int compare(Point t, Point t1) {
    int compareVal = (t1.x - t.y)
            + (t.x - t1.y);
    return compareVal < 0 ? -1 : compareVal == 0 ? 0 : 1;
}

රූප විස්තරය මෙහි ඇතුළත් කරන්න

තවත් වෙනස්කමක් (නව පුද්ගලික ප්‍රියතම):

public int compare(Point t, Point t1) {
    int compareVal = (Integer.bitCount(t.x ^ t.y))
            - (Integer.bitCount(t1.x ^ t1.y));
    return compareVal < 0 ? -1 : compareVal == 0 ? 0 : 1;
}

රූප විස්තරය මෙහි ඇතුළත් කරන්න

එය එතරම් අස්ථිර පෙනුමක්. XOR හරිම ලස්සනයි, විශේෂයෙන් සමීප වීම:

රූප විස්තරය මෙහි ඇතුළත් කරන්න

තවත් සමීප වීමක්:

රූප විස්තරය මෙහි ඇතුළත් කරන්න

දැන් සියර්පින්ස්කි ත්‍රිකෝණය, නැඹුරු:

public int compare(Point t, Point t1) {
    int compareVal = (Integer.bitCount(t.x | t.y))
            - (Integer.bitCount(t1.x | t1.y));
    return compareVal < 0 ? -1 : compareVal == 0 ? 0 : 1;
}

රූප විස්තරය මෙහි ඇතුළත් කරන්න


8
පළමු රූපය CPU හෝ memory die photo ලෙස පෙනේ
නික් ටී

IckNickT මෙහි වෙනස සඳහා මතකය මිය යයි (ගූගල් පින්තූර අනුව): files.macbidouille.com/mbv2/news/news_05_10/25-nm-die.jpg
ජස්ටින්

4
හරි, මතකය එතරම්ම නිර්‍මාණයි ... බොහෝ විට බහු-හර ප්‍රොසෙසරයක්: extremetech.com/wp-content/uploads/2012/07/Aubrey_Isle_die.jpg
නික් ටී

1
මම ඇත්තටම මේ දෙවැන්න කැමතියි. ඉතා දිලිසෙන පෙනුමක් ඇති නමුත් යටින් පවතින සංවිධානාත්මක ව්‍යුහයක් සමඟ. මට XOR මෝස්තරය මෙන් වියන ලද රග් එකක් අවශ්‍යයි!
ජොනතන් වැන් මැට්රේ

මේවා ඇත්තෙන්ම සිසිල් ය; ඔවුන් මට කැඩුණු ආකේඩ් ක්‍රීඩාවක් හෝ කූඩුවක් ගැන මතක් කර දෙයි.
ජේසන් සී

30

ජාවා

බිට් 15 හෝ 18 වර්ණ නිර්මාණය කරන්නේ කෙසේදැයි මට නිශ්චිතවම විශ්වාස නැත, එබැවින් මම එක් එක් නාලිකාවේ බයිට් වලින් අවම වශයෙන් සැලකිය යුතු ප්‍රමාණයක් අතහැර දමා 2 ^ 18 වෙනස් 24-බිට් වර්ණ සාදනු ඇත. බොහෝ ශබ්දය වර්ග කිරීම මගින් ඉවත් කරනු ලැබේ, නමුත් noise ලදායී ශබ්දය ඉවත් කිරීම පෙනෙන්නේ සංසන්දකයා කරන ආකාරයට වරකට මූලද්‍රව්‍ය දෙකකට වඩා සංසන්දනය කිරීම අවශ්‍ය වන බවයි. මම විශාල කර්නල් භාවිතයෙන් හැසිරවීමට උත්සාහ කරමි, නමුත් මේ අතර, මෙය මට කළ හැකි හොඳම දේ වේ.

රූප විස්තරය මෙහි ඇතුළත් කරන්න

HD රූපය # 2 සඳහා ක්ලික් කරන්න

අඩු විභේදන රූපය # 2

import java.awt.*;
import java.awt.image.*;
import javax.swing.*;
import java.util.*;

public class ColorSpan extends JFrame{
    private int h, w = h = 512;
    private BufferedImage image = 
            new BufferedImage(w,h,BufferedImage.TYPE_INT_RGB);
    private WritableRaster raster = image.getRaster();
    private DataBufferInt dbInt = (DataBufferInt) 
            (raster.getDataBuffer());
    private int[] data = dbInt.getData();

    private JLabel imageLabel = new JLabel(new ImageIcon(image));
    private JPanel bordered = new JPanel(new BorderLayout());


    public <T> void transpose(ArrayList<T> objects){
        for(int i = 0; i < w; i++){
            for(int j = 0; j < i; j++){
                Collections.swap(objects,i+j*w,j+i*h);
            }
        }
    }

    public <T> void sortByLine(ArrayList<T> objects, Comparator<T> comp){
        for(int i = 0; i < h; i++){
            Collections.sort(objects.subList(i*w, (i+1)*w), comp);
        }
    }

    public void init(){
        ArrayList<Integer> colors = new ArrayList<Integer>();
        for(int i = 0, max = 1<<18; i < max; i++){
            int r = i>>12, g = (i>>6)&63, b = i&63;
            colors.add(((r<<16)+(g<<8)+b)<<2);
        }

        Comparator<Integer> comp1 = new Comparator<Integer>(){
            public int compare(Integer left, Integer right){
                int a = left.intValue(), b = right.intValue();

                int rA = a>>16, rB = b>>16,
                    gA = (a>>8)&255, gB = (b>>8)&255;
                /*double thA = Math.acos(gA*2d/255-1),
                        thB = Math.acos(gB*2d/255-1);*/
                double thA = Math.atan2(rA/255d-.5,gA/255d-.5),
                        thB = Math.atan2(rB/255d-.5,gB/255d-.5);
                return -Double.compare(thA,thB);
            }
        }, comp2 = new Comparator<Integer>(){
            public int compare(Integer left, Integer right){
                int a = left.intValue(), b = right.intValue();

                int rA = a>>16, rB = b>>16,
                    gA = (a>>8)&255, gB = (b>>8)&255,
                    bA = a&255, bB = b&255;
                double dA = Math.hypot(gA-rA,bA-rA),
                        dB = Math.hypot(gB-rB,bB-rB);
                return Double.compare(dA,dB);
            }
        }, comp3 = new Comparator<Integer>(){
            public int compare(Integer left, Integer right){
                int a = left.intValue(), b = right.intValue();

                int rA = a>>16, rB = b>>16,
                    gA = (a>>8)&255, gB = (b>>8)&255,
                    bA = a&255, bB = b&255;

                    return Integer.compare(rA+gA+bA,rB+gB+bB);
            }
        };

        /* Start: Image 1 */
        Collections.sort(colors, comp2);
        transpose(colors);
        sortByLine(colors,comp2);
        transpose(colors);
        sortByLine(colors,comp1);
        transpose(colors);
        sortByLine(colors,comp2);
        sortByLine(colors,comp3);
        /* End: Image 1 */

        /* Start: Image 2 */
        Collections.sort(colors, comp1);
        sortByLine(colors,comp2);

        transpose(colors);
        sortByLine(colors,comp2);
        transpose(colors);
        sortByLine(colors,comp1);
        transpose(colors);
        sortByLine(colors,comp1);
        /* End: Image 2 */

        int index = 0;
        for(Integer color : colors){
            int cInt = color.intValue();
            data[index] = cInt;
            index++;
        }

    }

    public ColorSpan(){
        super("512x512 Unique Colors");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        init();

        bordered.setBorder(BorderFactory.createEmptyBorder(2,2,2,2));
        bordered.add(imageLabel,BorderLayout.CENTER);
        add(bordered,BorderLayout.CENTER);
        pack();

    }

    public static void main(String[] args){
        new ColorSpan().setVisible(true);
    }
}

1
එම දෙවැන්න සැබවින්ම 4096 x 4096 24bit අනුවාදයක් ලැබීමට
සුදුසුයි

ඉම්ගුර් පැය භාගයක් පමණ රූපය සැකසෙමින් පවතී. මම හිතන්නේ එය සම්පීඩනය කිරීමට උත්සාහ කරනවා විය හැකිය. කෙසේ වෙතත්, මම සබැඳියක් එක් කළෙමි: SSend.it/hj4ovh
John P

2
බාගැනීමේදී ගැටලුවක් තිබේ.
SuperJedi224

29

සී #

ඇවැත්නි, මෙම අභියෝගය තුළ ඇත්තෙන්ම සිසිල් දේවල්. මම සී # හි දී පිහියක් ගෙන විනාඩි 3 කින් (i7 CPU) 4096x4096 රූපයක් රැන්ඩම් වෝක් තර්කනය හරහා සෑම වර්ණයක්ම භාවිතා කළෙමි.

හරි, කේතය සඳහා. පැය ගණනක පර්යේෂණයන්ගෙන් කලකිරීමෙන් හා කේතයේ ලූප සඳහා සෑම එච්එස්එල් වර්ණයක්ම උත්පාදනය කිරීමට උත්සාහ කිරීමෙන් පසුව, එච්එස්එල් වර්ණ කියවීම සඳහා පැතලි ගොනුවක් සෑදීමට මම සමථයකට පත් වීමි. මා කළේ සෑම RGB වර්ණයක්ම ලැයිස්තුවක් බවට පත් කිරීමයි, පසුව මම ඇණවුම් කළේ හියු, දීප්තිය, පසුව සන්තෘප්තිය. ඉන්පසු මම ලැයිස්තුව පෙළ ගොනුවකට සුරකිමි. ColorData යනු මා විසින් ලියන ලද කුඩා පංතියක් වන අතර එය RGB වර්ණයක් පිළිගන්නා අතර HSL හා සමාන ගබඩා කරයි. මෙම කේතය විශාල RAM අනුභව කරන්නෙකි. 4GB RAM lol පමණ භාවිතා කරයි.

public class RGB
{
    public double R = 0;
    public double G = 0;
    public double B = 0;
    public override string ToString()
    {
        return "RGB:{" + (int)R + "," + (int)G + "," + (int)B + "}";
    }
}
public class HSL
{
    public double H = 0;
    public double S = 0;
    public double L = 0;
    public override string ToString()
    {
        return "HSL:{" + H + "," + S + "," + L + "}";
    }
}
public class ColorData
{
    public RGB rgb;
    public HSL hsl;
    public ColorData(RGB _rgb)
    {
        rgb = _rgb;
        var _hsl = ColorHelper._color_rgb2hsl(new double[]{rgb.R,rgb.G,rgb.B});
        hsl = new HSL() { H = _hsl[0], S = _hsl[1], L = _hsl[2] };
    }
    public ColorData(double[] _rgb)
    {
        rgb = new RGB() { R = _rgb[0], G = _rgb[1], B = _rgb[2] };
        var _hsl = ColorHelper._color_rgb2hsl(_rgb);
        hsl = new HSL() { H = _hsl[0], S = _hsl[1], L = _hsl[2] };
    }
    public override string ToString()
    {
        return rgb.ToString() + "|" + hsl.ToString();
    }
    public int Compare(ColorData cd)
    {
        if (this.hsl.H > cd.hsl.H)
        {
            return 1;
        }
        if (this.hsl.H < cd.hsl.H)
        {
            return -1;
        }

        if (this.hsl.S > cd.hsl.S)
        {
            return 1;
        }
        if (this.hsl.S < cd.hsl.S)
        {
            return -1;
        }

        if (this.hsl.L > cd.hsl.L)
        {
            return 1;
        }
        if (this.hsl.L < cd.hsl.L)
        {
            return -1;
        }
        return 0;
    }
}
public static class ColorHelper
{


    public static void MakeColorFile(string savePath)
    {
        List<ColorData> Colors = new List<ColorData>();
        System.IO.File.Delete(savePath);

        for (int r = 0; r < 256; r++)
        {
            for (int g = 0; g < 256; g++)
            {
                for (int b = 0; b < 256; b++)
                {
                    double[] rgb = new double[] { r, g, b };
                    ColorData cd = new ColorData(rgb);
                    Colors.Add(cd);
                }
            }
        }
        Colors = Colors.OrderBy(x => x.hsl.H).ThenBy(x => x.hsl.L).ThenBy(x => x.hsl.S).ToList();

        string cS = "";
        using (System.IO.StreamWriter fs = new System.IO.StreamWriter(savePath))
        {

            foreach (var cd in Colors)
            {
                cS = cd.ToString();
                fs.WriteLine(cS);
            }
        }
    }


    public static IEnumerable<Color> NextColorHThenSThenL()
    {
        HashSet<string> used = new HashSet<string>();
        double rMax = 720;
        double gMax = 700;
        double bMax = 700;
        for (double r = 0; r <= rMax; r++)
        {
            for (double g = 0; g <= gMax; g++)
            {
                for (double b = 0; b <= bMax; b++)
                {
                    double h = (r / (double)rMax);
                    double s = (g / (double)gMax);
                    double l = (b / (double)bMax);
                    var c = _color_hsl2rgb(new double[] { h, s, l });
                    Color col = Color.FromArgb((int)c[0], (int)c[1], (int)c[2]);
                    string key = col.R + "-" + col.G + "-" + col.B;
                    if (!used.Contains(key))
                    {
                        used.Add(key);
                        yield return col;
                    }
                    else
                    {
                        continue;
                    }
                }
            }
        }
    }

    public static Color HSL2RGB(double h, double s, double l){
        double[] rgb= _color_hsl2rgb(new double[] { h, s, l });
        return Color.FromArgb((int)rgb[0], (int)rgb[1], (int)rgb[2]);
    }
    public static double[] _color_rgb2hsl(double[] rgb)
    {
        double r = rgb[0]; double g = rgb[1]; double b = rgb[2];
        double min = Math.Min(r, Math.Min(g, b));
        double max = Math.Max(r, Math.Max(g, b));
        double delta = max - min;
        double l = (min + max) / 2.0;
        double s = 0;
        if (l > 0 && l < 1)
        {
            s = delta / (l < 0.5 ? (2 * l) : (2 - 2 * l));
        }
        double h = 0;
        if (delta > 0)
        {
            if (max == r && max != g) h += (g - b) / delta;
            if (max == g && max != b) h += (2 + (b - r) / delta);
            if (max == b && max != r) h += (4 + (r - g) / delta);
            h /= 6;
        } return new double[] { h, s, l };
    }


    public static double[] _color_hsl2rgb(double[] hsl)
    {
        double h = hsl[0];
        double s = hsl[1];
        double l = hsl[2];
        double m2 = (l <= 0.5) ? l * (s + 1) : l + s - l * s;
        double m1 = l * 2 - m2;
        return new double[]{255*_color_hue2rgb(m1, m2, h + 0.33333),
           255*_color_hue2rgb(m1, m2, h),
           255*_color_hue2rgb(m1, m2, h - 0.33333)};
    }


    public static double _color_hue2rgb(double m1, double m2, double h)
    {
        h = (h < 0) ? h + 1 : ((h > 1) ? h - 1 : h);
        if (h * (double)6 < 1) return m1 + (m2 - m1) * h * (double)6;
        if (h * (double)2 < 1) return m2;
        if (h * (double)3 < 2) return m1 + (m2 - m1) * (0.66666 - h) * (double)6;
        return m1;
    }


}

ඒකෙන් එහාට. ජනනය කරන ලද ගොනුවෙන් ඊළඟ වර්ණය ලබා ගැනීම සඳහා මම පන්තියක් ලිවීය. එය ඔබට වර්ණ ආරම්භය සහ වර්ණ අවසානය සැකසීමට ඉඩ දෙයි. යථාර්ථය නම්, එය මුලින්ම ගොනුව කුමන මානයකට වර්ග කර ඇත්ද යන්න සාමාන්‍යකරණය කළ හැකිය. මෙහි කාර්ය සාධනය ඉහළ නැංවීම සඳහා, මට RGB අගයන් ගොනුවට දමා එක් එක් පේළිය ස්ථාවර දිගක තබා ගත හැකි බව මම තේරුම් ගතිමි. ඒ ආකාරයෙන් මට ආරම්භ කිරීමට අවශ්‍ය රේඛාවට ළඟා වන තෙක් සෑම පේළියක් හරහාම ලූප වෙනුවට බයිට් ඕෆ්සෙට් එක පහසුවෙන් නියම කළ හැකිය. නමුත් එය මට එතරම් කාර්ය සාධනයක් නොවීය. නමුත් මෙන්න ඒ පන්තිය

public class HSLGenerator
{

    double hEnd = 1;
    double hStart = 0;

    double colCount = 256 * 256 * 256;

    public static Color ReadRGBColorFromLine(string line)
    {
        string sp1 = line.Split(new string[] { "RGB:{" }, StringSplitOptions.None)[1];
        string sp2 = sp1.Split('}')[0];
        string[] sp3 = sp2.Split(',');
        return Color.FromArgb(Convert.ToInt32(sp3[0]), Convert.ToInt32(sp3[1]), Convert.ToInt32(sp3[2]));
    }
    public IEnumerable<Color> GetNextFromFile(string colorFile)
    {
        int currentLine = -1;
        int startLine = Convert.ToInt32(hStart * colCount);
        int endLine = Convert.ToInt32(hEnd * colCount);
        string line = "";
        using(System.IO.StreamReader sr = new System.IO.StreamReader(colorFile))
        {

            while (!sr.EndOfStream)
            {
                line = sr.ReadLine();
                currentLine++;
                if (currentLine < startLine) //begin at correct offset
                {
                    continue;
                }
                yield return ReadRGBColorFromLine(line);
                if (currentLine > endLine) 
                {
                    break;
                }
            }
    }

    HashSet<string> used = new HashSet<string>();

    public void SetHueLimits(double hueStart, double hueEnd)
    {
        hEnd = hueEnd;
        hStart = hueStart;
    }
}

දැන් අපට වර්ණ ගොනුව ඇති අතර, ගොනුව කියවීමට අපට ක්‍රමයක් ඇත, අපට දැන් ඇත්ත වශයෙන්ම රූපය සෑදිය හැකිය. ලොක්බිට්මැප් නමින් හැඳින්වෙන බිට්මැප් එකක පික්සෙල් සැකසීමේ කාර්ය සාධනය වැඩි කිරීමට මම සොයාගත් පන්තියක් භාවිතා කළෙමි. ලොක්බිට්මැප් ප්‍රභවය

ඛණ්ඩාංක ස්ථාන ගබඩා කිරීම සඳහා මම කුඩා දෛශික 2 පන්තියක් නිර්මාණය කළෙමි

public class Vector2
{
    public int X = 0;
    public int Y = 0;
    public Vector2(int x, int y)
    {
        X = x;
        Y = y;
    }
    public Vector2 Center()
    {
        return new Vector2(X / 2, Y / 2);
    }
    public override string ToString()
    {
        return X.ToString() + "-" + Y.ToString();
    }
}

අසල්වැසි පික්සෙල් සොයා ගැනීමට උපකාරී වන SearchArea නමින් පන්තියක් ද මම නිර්මාණය කළෙමි. ඔබට අසල්වැසියන් සොයා ගැනීමට අවශ්‍ය පික්සෙල්, ඇතුළත සෙවීමට ඇති සීමාවන් සහ සෙවීමට “අසල්වැසි චතුරස්රයේ” ප්‍රමාණය සඳහන් කරන්න. එබැවින් ප්‍රමාණය 3 නම්, එයින් අදහස් වන්නේ ඔබ 3x3 වර්ගයක් සොයන බවයි.

public class SearchArea
{
    public int Size = 0;
    public Vector2 Center;
    public Rectangle Bounds;

    public SearchArea(int size, Vector2 center, Rectangle bounds)
    {
        Center = center;
        Size = size;
        Bounds = bounds;
    }
    public bool IsCoordinateInBounds(int x, int y)
    {
        if (!IsXValueInBounds(x)) { return false; }
        if (!IsYValueInBounds(y)) { return false; }
        return true;

    }
    public bool IsXValueInBounds(int x)
    {
        if (x < Bounds.Left || x >= Bounds.Right) { return false; }
        return true;
    }
    public bool IsYValueInBounds(int y)
    {
        if (y < Bounds.Top || y >= Bounds.Bottom) { return false; }
        return true;
    }

}

මෙන්න ඊළඟ අසල්වැසියා තෝරා ගන්නා පන්තිය. මූලික වශයෙන් සෙවුම් ක්‍රම 2 ක් ඇත. අ) සම්පූර්ණ චතුරස්රය, ආ) චතුරස්රයේ පරිමිතිය පමණි. මෙය ප්‍රශස්තකරණයකි, චතුරස්රය පිරී ඇති බව වටහා ගැනීමෙන් පසු සම්පූර්ණ චතුරස්රය නැවත සෙවීම වැළැක්වීම සඳහා. එකම චතුරස්රයන් නැවත නැවතත් සෙවීම වැළැක්වීම සඳහා ගැඹුර සිතියම තවත් ප්රශස්තකරණයකි. කෙසේ වෙතත්, මම මෙය සම්පූර්ණයෙන්ම ප්‍රශස්තිකරණය කළේ නැත. GetNeighbers වෙත ලැබෙන සෑම ඇමතුමක්ම සෑම විටම මුලින් සම්පූර්ණ වර්ග සෙවීම සිදු කරයි. ආරම්භක පූර්ණ චතුරස්රය සම්පූර්ණ කිරීමෙන් පසුව පමණක් පරිමිතිය සෙවීම සඳහා මට මෙය ප්‍රශස්තිකරණය කළ හැකි බව මම දනිමි. මම තවම එම ප්‍රශස්තිකරණය වෙත ළඟා වී නැත, එය නොමැතිව පවා කේතය ඉතා වේගවත්ය. අදහස් දැක්වූ "අගුළු" රේඛා වන්නේ මම සමාන්තරව භාවිතා කරන බැවිනි. එක් එක් අවස්ථාවේදී, නමුත් මට වැටහී ගියේ මට අවශ්‍ය ප්‍රමාණයට වඩා කේත ලිවිය යුතු බවයි.

public class RandomWalkGenerator
{
    HashSet<string> Visited = new HashSet<string>();
    Dictionary<string, int> DepthMap = new Dictionary<string, int>();
    Rectangle Bounds;
    Random rnd = new Random();
    public int DefaultSearchSize = 3;
    public RandomWalkGenerator(Rectangle bounds)
    {
        Bounds = bounds;
    }
    private SearchArea GetSearchArea(Vector2 center, int size)
    {
        return new SearchArea(size, center, Bounds);
    }

    private List<Vector2> GetNeighborsFullSearch(SearchArea srchArea, Vector2 coord)
    {
        int radius = (int)Math.Floor((double)((double)srchArea.Size / (double)2));
        List<Vector2> pixels = new List<Vector2>();
        for (int rX = -radius; rX <= radius; rX++)
        {
            for (int rY = -radius; rY <= radius; rY++)
            {
                if (rX == 0 && rY == 0) { continue; } //not a new coordinate
                int x = rX + coord.X;
                int y = rY + coord.Y;
                if (!srchArea.IsCoordinateInBounds(x, y)) { continue; }
                var key = x + "-" + y;
                // lock (Visited)
                {
                    if (!Visited.Contains(key))
                    {
                        pixels.Add(new Vector2(x, y));
                    }
                }
            }
        }
        if (pixels.Count == 0)
        {
            int depth = 0;
            string vecKey = coord.ToString();
            if (!DepthMap.ContainsKey(vecKey))
            {
                DepthMap.Add(vecKey, depth);
            }
            else
            {
                depth = DepthMap[vecKey];
            }

            var size = DefaultSearchSize + 2 * depth;
            var sA = GetSearchArea(coord, size);
            pixels = GetNeighborsPerimeterSearch(sA, coord, depth);
        }
        return pixels;
    }
    private Rectangle GetBoundsForPerimeterSearch(SearchArea srchArea, Vector2 coord)
    {
        int radius = (int)Math.Floor((decimal)(srchArea.Size / 2));
        Rectangle r = new Rectangle(-radius + coord.X, -radius + coord.Y, srchArea.Size, srchArea.Size);
        return r;
    }
    private List<Vector2> GetNeighborsPerimeterSearch(SearchArea srchArea, Vector2 coord, int depth = 0)
    {
        string vecKey = coord.ToString();
        if (!DepthMap.ContainsKey(vecKey))
        {
            DepthMap.Add(vecKey, depth);
        }
        else
        {
            DepthMap[vecKey] = depth;
        }
        Rectangle bounds = GetBoundsForPerimeterSearch(srchArea, coord);
        List<Vector2> pixels = new List<Vector2>();
        int depthMax = 1500;

        if (depth > depthMax)
        {
            return pixels;
        }

        int yTop = bounds.Top;
        int yBot = bounds.Bottom;

        //left to right scan
        for (int x = bounds.Left; x < bounds.Right; x++)
        {

            if (srchArea.IsCoordinateInBounds(x, yTop))
            {
                var key = x + "-" + yTop;
                // lock (Visited)
                {
                    if (!Visited.Contains(key))
                    {
                        pixels.Add(new Vector2(x, yTop));
                    }
                }
            }
            if (srchArea.IsCoordinateInBounds(x, yBot))
            {
                var key = x + "-" + yBot;
                // lock (Visited)
                {
                    if (!Visited.Contains(key))
                    {
                        pixels.Add(new Vector2(x, yBot));
                    }
                }
            }
        }

        int xLeft = bounds.Left;
        int xRight = bounds.Right;
        int yMin = bounds.Top + 1;
        int yMax = bounds.Bottom - 1;
        //top to bottom scan
        for (int y = yMin; y < yMax; y++)
        {
            if (srchArea.IsCoordinateInBounds(xLeft, y))
            {
                var key = xLeft + "-" + y;
                // lock (Visited)
                {
                    if (!Visited.Contains(key))
                    {
                        pixels.Add(new Vector2(xLeft, y));
                    }
                }
            }
            if (srchArea.IsCoordinateInBounds(xRight, y))
            {
                var key = xRight + "-" + y;
                // lock (Visited)
                {
                    if (!Visited.Contains(key))
                    {
                        pixels.Add(new Vector2(xRight, y));
                    }
                }
            }
        }

        if (pixels.Count == 0)
        {
            var size = srchArea.Size + 2;
            var sA = GetSearchArea(coord, size);
            pixels = GetNeighborsPerimeterSearch(sA, coord, depth + 1);
        }
        return pixels;
    }
    private List<Vector2> GetNeighbors(SearchArea srchArea, Vector2 coord)
    {
        return GetNeighborsFullSearch(srchArea, coord);
    }
    public Vector2 ChooseNextNeighbor(Vector2 coord)
    {
        SearchArea sA = GetSearchArea(coord, DefaultSearchSize);
        List<Vector2> neighbors = GetNeighbors(sA, coord);
        if (neighbors.Count == 0)
        {
            return null;
        }
        int idx = rnd.Next(0, neighbors.Count);
        Vector2 elm = neighbors.ElementAt(idx);
        string key = elm.ToString();
        // lock (Visited)
        {
            Visited.Add(key);
        }
        return elm;
    }
}

හරි නියමයි, ඉතින් දැන් මෙන්න රූපය නිර්මාණය කරන පන්තිය

public class RandomWalk
{
    Rectangle Bounds;
    Vector2 StartPath = new Vector2(0, 0);
    LockBitmap LockMap;
    RandomWalkGenerator rwg;
    public int RandomWalkSegments = 1;
    string colorFile = "";

    public RandomWalk(int size, string _colorFile)
    {
        colorFile = _colorFile;
        Bounds = new Rectangle(0, 0, size, size);
        rwg = new RandomWalkGenerator(Bounds);
    }
    private void Reset()
    {
        rwg = new RandomWalkGenerator(Bounds);
    }
    public void CreateImage(string savePath)
    {
        Reset();
        Bitmap bmp = new Bitmap(Bounds.Width, Bounds.Height);
        LockMap = new LockBitmap(bmp);
        LockMap.LockBits();
        if (RandomWalkSegments == 1)
        {
            RandomWalkSingle();
        }
        else
        {
            RandomWalkMulti(RandomWalkSegments);
        }
        LockMap.UnlockBits();
        bmp.Save(savePath);

    }
    public void SetStartPath(int X, int Y)
    {
        StartPath.X = X;
        StartPath.Y = Y;
    }
    private void RandomWalkMulti(int buckets)
    {

        int Buckets = buckets;
        int PathsPerSide = (Buckets + 4) / 4;
        List<Vector2> Positions = new List<Vector2>();

        var w = Bounds.Width;
        var h = Bounds.Height;
        var wInc = w / Math.Max((PathsPerSide - 1),1);
        var hInc = h / Math.Max((PathsPerSide - 1),1);

        //top
        for (int i = 0; i < PathsPerSide; i++)
        {
            var x = Math.Min(Bounds.Left + wInc * i, Bounds.Right - 1);
            Positions.Add(new Vector2(x, Bounds.Top));
        }
        //bottom
        for (int i = 0; i < PathsPerSide; i++)
        {
            var x = Math.Max(Bounds.Right -1 - wInc * i, 0);
            Positions.Add(new Vector2(x, Bounds.Bottom - 1));
        }
        //right and left
        for (int i = 1; i < PathsPerSide - 1; i++)
        {
            var y = Math.Min(Bounds.Top + hInc * i, Bounds.Bottom - 1);
            Positions.Add(new Vector2(Bounds.Left, y));
            Positions.Add(new Vector2(Bounds.Right - 1, y));
        }
        Positions = Positions.OrderBy(x => Math.Atan2(x.X, x.Y)).ToList();
        double cnt = 0;
        List<IEnumerator<bool>> _execs = new List<IEnumerator<bool>>();
        foreach (Vector2 startPath in Positions)
        {
            double pct = cnt / (Positions.Count);
            double pctNext = (cnt + 1) / (Positions.Count);

            var enumer = RandomWalkHueSegment(pct, pctNext, startPath).GetEnumerator();

            _execs.Add(enumer);
            cnt++;
        }

        bool hadChange = true;
        while (hadChange)
        {
            hadChange = false;
            foreach (var e in _execs)
            {
                if (e.MoveNext())
                {
                    hadChange = true;
                }
            }
        }

    }
    private IEnumerable<bool> RandomWalkHueSegment(double hueStart, double hueEnd, Vector2 startPath)
    {
        var colors = new HSLGenerator();
        colors.SetHueLimits(hueStart, hueEnd);
        var colorFileEnum = colors.GetNextFromFile(colorFile).GetEnumerator();
        Vector2 coord = new Vector2(startPath.X, startPath.Y);
        LockMap.SetPixel(coord.X, coord.Y, ColorHelper.HSL2RGB(0, 0, 0));

        while (true)
        {
            if (!colorFileEnum.MoveNext())
            {
                break;
            }
            var rgb = colorFileEnum.Current;
            coord = ChooseNextNeighbor(coord);
            if (coord == null)
            {
                break;
            }
            LockMap.SetPixel(coord.X, coord.Y, rgb);
            yield return true;

        }
    }
    private void RandomWalkSingle()
    {
        Vector2 coord = new Vector2(StartPath.X, StartPath.Y);
        LockMap.SetPixel(coord.X, coord.Y, ColorHelper.HSL2RGB(0, 0, 0));
        int cnt = 1;
        var colors = new HSLGenerator();
        var colorFileEnum = colors.GetNextFromFile(colorFile).GetEnumerator();
        while (true)
        {
            if (!colorFileEnum.MoveNext())
            {
                return;
            }
            var rgb = colorFileEnum.Current;
            var newCoord = ChooseNextNeighbor(coord);
            coord = newCoord;
            if (newCoord == null)
            {
                return;
            }
            LockMap.SetPixel(newCoord.X, newCoord.Y, rgb);
            cnt++;

        }

    }

    private Vector2 ChooseNextNeighbor(Vector2 coord)
    {
        return rwg.ChooseNextNeighbor(coord);
    }


}

මෙන්න උදාහරණ ක්‍රියාත්මක කිරීමකි:

class Program
{
    static void Main(string[] args)
    {
        {
           // ColorHelper.MakeColorFile();
          //  return;
        }
        string colorFile = "colors.txt";
        var size = new Vector2(1000,1000);
        var ctr = size.Center();
        RandomWalk r = new RandomWalk(size.X,colorFile);
        r.RandomWalkSegments = 8;
        r.SetStartPath(ctr.X, ctr.Y);
        r.CreateImage("test.bmp");

    }
}

RandomWalkSegment = 1 නම්, එය මූලික වශයෙන් ඔබ කියන ඕනෑම තැනක ඇවිදීමට පටන් ගෙන ගොනුවේ පළමු පළමු වර්ණයෙන් ආරම්භ වේ.

එය මා පිළිගන්නා පිරිසිදුම කේතය නොවේ, නමුත් එය ඉතා වේගයෙන් ධාවනය වේ!

කැපූ නිමැවුම්

මාර්ග 3 යි

මාර්ග 128 යි

සංස්කරණය කරන්න:

ඒ නිසා මම OpenGL සහ Shaders ගැන ඉගෙන ගත්තා. මම සරල වර්ණ සෙවන ස්ක්‍රිප්ට් 2 ක් සමඟ GPU මත වේගයෙන් දැවෙන සෑම වර්ණ භාවිතා කරමින් 4096x4096 උත්පාදනය කළෙමි. ප්‍රතිදානය කම්මැලි ය, නමුත් යමෙකුට මෙය සිත්ගන්නාසුළු යැයි සිතිය හැකි අතර සිසිල් අදහස් කිහිපයක් ඉදිරිපත් කළ හැකිය:

සිරස් සෙවන

attribute vec3 a_position;
varying vec2 vTexCoord;
   void main() {
      vTexCoord = (a_position.xy + 1) / 2;
      gl_Position = vec4(a_position, 1);
  }

Frag Shader

void main(void){
    int num = int(gl_FragCoord.x*4096.0 + gl_FragCoord.y);
    int h = num % 256;
    int s = (num/256) % 256;
    int l = ((num/256)/256) % 256;
    vec4 hsl = vec4(h/255.0,s/255.0,l/255.0,1.0);
    gl_FragColor = hsl_to_rgb(hsl); // you need to implement a conversion method
}

සංස්කරණය කරන්න (10/15/16): ජානමය ඇල්ගොරිතමයක් පිළිබඳ සංකල්පයක් සනාථ කිරීමට අවශ්‍ය විය. මම පැය 24 කට පසුව අහඹු වර්ණ 100x100 කට්ටලයක් මත මෙම කේතය ධාවනය කරමි, නමුත් මෙතෙක් ප්‍රතිදානය ලස්සනයි!රූප විස්තරය මෙහි ඇතුළත් කරන්න

සංස්කරණය කරන්න (10/26/16): මම දැන් දින 12 ක් තිස්සේ ජානමය ඇල්ගොරිතම කේතය ක්‍රියාත්මක කරමින් සිටිමි .. එය තවමත් ප්‍රතිදානය ප්‍රශස්ත කරයි. එය මූලික වශයෙන් යම් දේශීය අවමයකට අභිසාරී වූ නමුත් පෙනෙන ආකාරයට එය තව දුරටත් වැඩිදියුණු වෙමින් පවතී:රූප විස්තරය මෙහි ඇතුළත් කරන්න

සංස්කරණය කරන්න: 8/12/17 - මම නව අහඹු ඇවිදීමේ ඇල්ගොරිතමයක් ලිව්වෙමි - මූලික වශයෙන් ඔබ "ඇවිදින්නන්" ගණනාවක් සඳහන් කරයි, නමුත් අහඹු ලෙස ඇවිදීම වෙනුවට - ඔවුන් අහඹු ලෙස වෙනත් ඇවිදින්නෙකු තෝරාගෙන ඒවා මඟ හරිනු ඇත (ඊළඟට ලබා ගත හැකි පික්සලය දුරින් තෝරන්න ) - හෝ ඔවුන් දෙසට ඇවිදින්න (ඔවුන්ට ළඟම ඇති ඊළඟ පික්සෙල් තෝරන්න). අළු පාට නිමැවුම් උදාහරණයක් මෙහි ඇත (මම වර්ණ ගැන්වූ පසු සම්පූර්ණ 4096x4096 වර්ණ විදැහුම් කිරීමක් කරමි!):රූප විස්තරය මෙහි ඇතුළත් කරන්න


4
ටිකක් ප්‍රමාද වූ නමුත් PPCG වෙත සාදරයෙන් පිළිගනිමු! මෙය විශිෂ්ට පළමු තනතුරකි.
යම් spaghetto

1
ඔබට ස්තුතියි! තවත් අභියෝග සම්පූර්ණ කිරීමට මම බලාපොරොත්තු වෙමි! මම මෑතකදී තවත් රූප කේතකරණ දේවල් කරමින් සිටිමි, එය මගේ නව විනෝදාංශයයි
applejacks01

වාව් මේවා නියමයි; මම අද මෙම තනතුරට පැමිණ පසුව ඇති සියලුම කරුණු පරීක්ෂා කර බැලීම සතුටට කරුණකි.
ජේසන් සී

ඔබට ස්තුතියි! සිත්ගන්නාසුලු ප්‍රමිතීන් නිපදවීම සඳහා මම දැන් ජානමය ඇල්ගොරිතම කේතීකරණයක් කරමි. මූලික වශයෙන්, වර්ණ 10000 ක් ගන්න, 100x100 ජාලකය සාදයි. සෑම පික්සෙල් සඳහාම අසල්වැසි පික්සෙල් ලබා ගන්න. එක් එක් සඳහා, CIEDE2000 දුර ලබා ගන්න. එය සාරාංශ කරන්න. සියලුම පික්සල් 10000 සඳහා එය එකතු කරන්න. ජානමය ඇල්ගොරිතම එම මුළු මුදල අඩු කිරීමට උත්සාහ කරයි. එහි මන්දගාමී, නමුත් 20x20 රූපයක් සඳහා එහි ප්‍රතිදානය ඇත්තෙන්ම සිත්ගන්නා සුළුය
applejacks01

මෙම විසඳුමේ ප්‍රතිදානයට මම විශේෂයෙන් කැමතියි.
r_alex_hall

28

පරිමාණය

එල්-සිස්ටම් එකක් හරහා ත්‍රිමාන හිල්බට් වක්රය ඇවිදීමෙන් මම සියලු වර්ණ ඇණවුම් කරමි . මම ප්‍රතිදාන රූපයේ පික්සල් ද්විමාන හිල්බට් වක්‍රය දිගේ ඇවිද ගොස් සියලු වර්ණ තබමි.

512 x 512 ප්‍රතිදානය:

රූප විස්තරය මෙහි ඇතුළත් කරන්න

මෙන්න කේතය. එය බොහෝමයක් ආවරණය කරන්නේ තාර / රෝල් / යාව හරහා ත්‍රිමාන හරහා ගමන් කිරීමේ තර්කනය සහ ගණිතය පමණි. මට විශ්වාසයි එම කොටස කිරීමට වඩා හොඳ ක්‍රමයක් ඇති බව, නමුත් හොඳයි.

import scala.annotation.tailrec
import java.awt.image.BufferedImage
import javax.imageio.ImageIO
import java.io.File

object AllColors {

  case class Vector(val x: Int, val y: Int, val z: Int) {
    def applyTransformation(m: Matrix): Vector = {
      Vector(m.r1.x * x + m.r1.y * y + m.r1.z * z, m.r2.x * x + m.r2.y * y + m.r2.z * z, m.r3.x * x + m.r3.y * y + m.r3.z * z)
    }
    def +(v: Vector): Vector = {
      Vector(x + v.x, y + v.y, z + v.z)
    }
    def unary_-(): Vector = Vector(-x, -y, -z)
  }

  case class Heading(d: Vector, s: Vector) {
    def roll(positive: Boolean): Heading = {
      val (axis, b) = getAxis(d)
      Heading(d, s.applyTransformation(rotationAbout(axis, !(positive ^ b))))
    }

    def yaw(positive: Boolean): Heading = {
      val (axis, b) = getAxis(s)
      Heading(d.applyTransformation(rotationAbout(axis, positive ^ b)), s)
    }

    def pitch(positive: Boolean): Heading = {
      if (positive) {
        Heading(s, -d)
      } else {
        Heading(-s, d)
      }
    }

    def applyCommand(c: Char): Heading = c match {
      case '+' => yaw(true)
      case '-' => yaw(false)
      case '^' => pitch(true)
      case 'v' => pitch(false)
      case '>' => roll(true)
      case '<' => roll(false)
    }
  }

  def getAxis(v: Vector): (Char, Boolean) = v match {
    case Vector(1, 0, 0) => ('x', true)
    case Vector(-1, 0, 0) => ('x', false)
    case Vector(0, 1, 0) => ('y', true)
    case Vector(0, -1, 0) => ('y', false)
    case Vector(0, 0, 1) => ('z', true)
    case Vector(0, 0, -1) => ('z', false)
  }

  def rotationAbout(axis: Char, positive: Boolean) = (axis, positive) match {
    case ('x', true) => XP
    case ('x', false) => XN
    case ('y', true) => YP
    case ('y', false) => YN
    case ('z', true) => ZP
    case ('z', false) => ZN
  }

  case class Matrix(val r1: Vector, val r2: Vector, val r3: Vector)

  val ZP = Matrix(Vector(0,-1,0),Vector(1,0,0),Vector(0,0,1))
  val ZN = Matrix(Vector(0,1,0),Vector(-1,0,0),Vector(0,0,1))

  val XP = Matrix(Vector(1,0,0),Vector(0,0,-1),Vector(0,1,0))
  val XN = Matrix(Vector(1,0,0),Vector(0,0,1),Vector(0,-1,0))

  val YP = Matrix(Vector(0,0,1),Vector(0,1,0),Vector(-1,0,0))
  val YN = Matrix(Vector(0,0,-1),Vector(0,1,0),Vector(1,0,0))

  @tailrec def applyLSystem(current: Stream[Char], rules: Map[Char, List[Char]], iterations: Int): Stream[Char] = {
    if (iterations == 0) {
      current
    } else {
      val nextStep = current flatMap { c => rules.getOrElse(c, List(c)) }
      applyLSystem(nextStep, rules, iterations - 1)
    }
  }

  def walk(x: Vector, h: Heading, steps: Stream[Char]): Stream[Vector] = steps match {
    case Stream() => Stream(x)
    case 'f' #:: rest => x #:: walk(x + h.d, h, rest)
    case c #:: rest => walk(x, h.applyCommand(c), rest)
  }

  def hilbert3d(n: Int): Stream[Vector] = {
    val rules = Map('x' -> "^>x<f+>>x<<f>>x<<+fvxfxvf+>>x<<f>>x<<+f>x<^".toList)
    val steps = applyLSystem(Stream('x'), rules, n) filterNot (_ == 'x')
    walk(Vector(0, 0, 0), Heading(Vector(1, 0, 0), Vector(0, 1, 0)), steps)
  }

  def hilbert2d(n: Int): Stream[Vector] = {
    val rules = Map('a' -> "-bf+afa+fb-".toList, 'b' -> "+af-bfb-fa+".toList)
    val steps = applyLSystem(Stream('a'), rules, n) filterNot (c => c == 'a' || c == 'b')
    walk(Vector(0, 0, 0), Heading(Vector(1, 0, 0), Vector(0, 0, 1)), steps)
  }

  def main(args: Array[String]): Unit = {
    val n = 4
    val img = new BufferedImage(1 << (3 * n), 1 << (3 * n), BufferedImage.TYPE_INT_RGB)
    hilbert3d(n * 2).zip(hilbert2d(n * 3)) foreach { case (Vector(r,g,b), Vector(x,y,_)) => img.setRGB(x, y, (r << (24 - 2 * n)) | (g << (16 - 2 * n)) | (b << (8 - 2 * n))) }
    ImageIO.write(img, "png", new File(s"out_$n.png"))
  }
}

22

HTML5 කැන්වස් + ජාවාස්ක්‍රිප්ට්

මම එය randoGraph ලෙස හඳුන්වන අතර ඔබට අවශ්‍ය තරම් ප්‍රමාණයක් මෙහි නිර්මාණය කළ හැකිය

උදාහරණ කිහිපයක්:

උදාහරණ 1

උදාහරණ 2

උදාහරණ 3

උදාහරණ 4

උදාහරණ 5

උදාහරණ 6

උදාහරණ 7

උදාහරණයක් ලෙස ෆයර්ෆොක්ස් හි ඔබට කැන්වසය මත දකුණු ක්ලික් කර (එය අවසන් වූ විට) එය රූපයක් ලෙස සුරැකිය හැක. සමහර බ්‍රව්සර් මතක සීමාව නිසා 4096x4096 රූපය නිපදවීම එක්තරා ආකාරයක ගැටළුවක් වේ.

අදහස තරමක් සරල නමුත් සෑම රූපයක්ම අද්විතීයයි. මුලින්ම අපි වර්ණ මාලාව නිර්මාණය කරමු. X ලකුණු වලින් ආරම්භ කිරීමෙන් අපි අහඹු ලෙස වර්ණාලේපයෙන් තෝරාගෙන ඒවා සඳහා ස්ථාන (අපි වර්ණ තෝරා ගන්නා සෑම අවස්ථාවකම අපි එය පලතුරෙන් මකා දමන්නෙමු) ඊළඟ පික්සෙල් එකම ස්ථානයේ නොයැවිය යුතු තැන අපි සටහන් කරමු.

ස්පර්ශ වන සෑම පික්සෙල් සඳහාම අපි හැකි වර්ණ (X) සංඛ්‍යාවක් නිර්මාණය කර එම පික්සෙල් වලට වඩාත්ම අදාළ දේ තෝරා ගනිමු. රූපය සම්පූර්ණ වන තුරු මෙය දිගටම පවතී.

HTML කේතය

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="el">
<head>
<script type="text/javascript" src="randoGraph.js"></script>
</head>
<body>
    <canvas id="randoGraphCanvas"></canvas> 
</body>
</html>

සහ randoGraph.js සඳහා ජාවාස්ක්‍රිප්ට්

window.onload=function(){
    randoGraphInstance = new randoGraph("randoGraphCanvas",256,128,1,1);
    randoGraphInstance.setRandomness(500, 0.30, 0.11, 0.59);
    randoGraphInstance.setProccesses(10);
    randoGraphInstance.init(); 
}

function randoGraph(canvasId,width,height,delay,startings)
{
    this.pixels = new Array();
    this.colors = new Array(); 
    this.timeouts = new Array(); 
    this.randomFactor = 500;
    this.redFactor = 0.30;
    this.blueFactor = 0.11;
    this.greenFactor  = 0.59;
    this.processes = 1;
    this.canvas = document.getElementById(canvasId); 
    this.pixelsIn = new Array(); 
    this.stopped = false;

    this.canvas.width = width;
    this.canvas.height = height;
    this.context = this.canvas.getContext("2d");
    this.context.clearRect(0,0, width-1 , height-1);
    this.shadesPerColor = Math.pow(width * height, 1/3);
    this.shadesPerColor = Math.round(this.shadesPerColor * 1000) / 1000;

    this.setRandomness = function(randomFactor,redFactor,blueFactor,greenFactor)
    {
        this.randomFactor = randomFactor;
        this.redFactor = redFactor;
        this.blueFactor = blueFactor;
        this.greenFactor = greenFactor;
    }

    this.setProccesses = function(processes)
    {
        this.processes = processes;
    }

    this.init = function()
    {
        if(this.shadesPerColor > 256 || this.shadesPerColor % 1 > 0) 
        { 
            alert("The dimensions of the image requested to generate are invalid. The product of width multiplied by height must be a cube root of a integer number up to 256."); 
        }
        else 
        {
            var steps = 256 / this.shadesPerColor;
            for(red = steps / 2; red <= 255;)
            {
                for(blue = steps / 2; blue <= 255;)
                {
                    for(green = steps / 2; green <= 255;)
                    {   
                        this.colors.push(new Color(Math.round(red),Math.round(blue),Math.round(green)));
                        green = green + steps;
                    }
                    blue = blue + steps; 
                }
                red = red + steps; 
            }   

            for(var i = 0; i < startings; i++)
            {
                var color = this.colors.splice(randInt(0,this.colors.length - 1),1)[0];
                var pixel = new Pixel(randInt(0,width - 1),randInt(0,height - 1),color);
                this.addPixel(pixel);       
            }

            for(var i = 0; i < this.processes; i++)
            {
                this.timeouts.push(null);
                this.proceed(i);
            }
        }
    }

    this.proceed = function(index) 
    { 
        if(this.pixels.length > 0)
        {
            this.proceedPixel(this.pixels.splice(randInt(0,this.pixels.length - 1),1)[0]);
            this.timeouts[index] = setTimeout(function(that){ if(!that.stopped) { that.proceed(); } },this.delay,this);
        }
    }

    this.proceedPixel = function(pixel)
    {
        for(var nx = pixel.getX() - 1; nx < pixel.getX() + 2; nx++)
        {
            for(var ny = pixel.getY() - 1; ny < pixel.getY() + 2; ny++)
            {
                if(! (this.pixelsIn[nx + "x" + ny] == 1 || ny < 0 || nx < 0 || nx > width - 1 || ny > height - 1 || (nx == pixel.getX() && ny == pixel.getY())) )
                {
                    var color = this.selectRelevantColor(pixel.getColor());
                    var newPixel = new Pixel(nx,ny,color);
                    this.addPixel(newPixel);
                }
            }
        }   
    }

    this.selectRelevantColor = function(color)
    {
        var relevancies = new Array(); 
        var relColors = new Array(); 
        for(var i = 0; i < this.randomFactor && i < this.colors.length; i++)
        {
            var index = randInt(0,this.colors.length - 1);
            var c = this.colors[index];
            var relevancy = Math.pow( ((c.getRed()-color.getRed()) * this.redFactor) , 2)
            + Math.pow( ((c.getBlue()-color.getBlue()) * this.blueFactor), 2)
            + Math.pow( ((c.getGreen()-color.getGreen()) * this.greenFactor) , 2);
            relevancies.push(relevancy); 
            relColors[relevancy+"Color"] = index;
        }
        return this.colors.splice(relColors[relevancies.min()+"Color"],1)[0]
    }

    this.addPixel = function(pixel)
    {
        this.pixels.push(pixel);
        this.pixelsIn[pixel.getX() + "x" + pixel.getY() ] = 1;
        var color = pixel.getColor();
        this.context.fillStyle = "rgb("+color.getRed()+","+color.getBlue()+","+color.getGreen()+")";
        this.context.fillRect( pixel.getX(), pixel.getY(), 1, 1);   
    }

    var toHex = function toHex(num) 
    {
        num = Math.round(num);
        var hex = num.toString(16);
        return hex.length == 1 ? "0" + hex : hex;
    }

    this.clear = function()
    {
        this.stopped = true;
    }
}

function Color(red,blue,green)
{   
    this.getRed = function() { return red; } 
    this.getBlue = function() { return blue; } 
    this.getGreen = function() { return green; } 
}

function Pixel(x,y,color)
{   
    this.getX = function() { return x; } 
    this.getY = function() { return y; } 
    this.getColor = function() { return color; } 
}


function randInt(min, max) 
{
    return Math.floor(Math.random() * (max - min + 1)) + min;
}


// @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/min
Array.prototype.min = function() 
{
      return Math.min.apply(null, this);
};

// @see http://stackoverflow.com/questions/5223/length-of-javascript-object-ie-associative-array
Object.size = function(obj) 
{
    var size = 0, key;
    for (key in obj) {
        if (obj.hasOwnProperty(key)) size++;
    }
    return size;
};

එය හොඳයි, නමුත් එය පෙනෙන්නේ ෆෙජෙස්ජෝකෝ වෙතින් සී # පිළිතුර ලෙස ය . එය අහම්බෙන් පමණක්ද?
ඒඑල්

1
ඇල්ගොරිතම මෙහි ඇති අතර ඕනෑම කෙනෙකුට කියවීමට හා තේරුම් ගැනීමට හැකිය. Fejesjoco වෙතින් C # පිළිතුරෙන් පසුව ප්‍රකාශයට පත් කරන ලද මෙම පිළිතුර ජයග්‍රාහකයා ලෙස ප්‍රකාශයට පත් කිරීමෙන් එහි ප්‍රති result ලය කෙතරම් හොඳද යන්න අභිප්‍රේරණය විය. එවිට මම සිතුවේ අසල්වැසි වර්ණ සැකසීමේ හා තෝරා ගැනීමේ සම්පූර්ණයෙන්ම වෙනස් ප්‍රවේශයක්, මෙය එයයි. දෘශ්‍ය වර්ණාවලිය දිගේ භාවිතා කරන වර්ණ ඒකාකාරව බෙදා හැරීම, අදාළ වර්ණ පිළිබඳ සංකල්පය සහ ආරම්භක ස්ථාන වැනි පිළිතුරු දෙකටම එකම පදනමක් ඇත. සමහර විට එම පදනමට අනුබල දීමෙන් නිෂ්පාදිත රූප සමහර අවස්ථාවල සමානකමක් ඇතැයි කෙනෙකුට සිතිය හැකිය.
konstantinosX

හරි, මම ඔබේ පිළිතුර විවේචනය කරනවා යැයි ඔබ සිතුවා නම් මට කණගාටුයි. එහි ප්‍රති output ලය සමාන වන බැවින් ඔබ ෆෙජෙස්ජෝකෝගේ පිළිතුරෙන් ආශ්වාදයක් ලැබුවාදැයි මම කල්පනා කළෙමි.
AL

1
"මූලාකෘති දාමය භාවිතා කරනවා වෙනුවට ඉදිකිරීම්කරු තුළ පන්තියක ක්‍රම නිර්වචනය කිරීම ඇත්තෙන්ම අකාර්යක්ෂමයි. විශේෂයෙන් පන්තිය කිහිප වතාවක් භාවිතා කළහොත්." පැට්‍රික් රොබට්ස්. එය වලංගු කරන උදාහරණ සමඟ ඔබට කිසියම් සඳහනක් තිබේද? , මෙම හිමිකම් පෑමට කිසියම් පදනමක් තිබේදැයි දැන ගැනීමට මම අවංකවම කැමතියි (එය භාවිතා කිරීම නැවැත්වීම සඳහා), සහ එය කුමක්ද.
konstantinosX

2
මූලාකෘති භාවිතය සම්බන්ධයෙන්: එය ස්ථිතික ක්‍රමයක් මෙන් බොහෝ දුරට ක්‍රියා කරයි. ඔබ වචනයේ පරිසමාප්ත අර්ථයෙන්ම ශ්‍රිතය අර්ථ දක්වා ඇති විට, ඔබ නිර්මාණය කරන සෑම නව වස්තුවක්ම ශ්‍රිතයේ නව පිටපතක් නිර්මාණය කළ යුතු අතර ඒවා එම වස්තු උදාහරණය සමඟ ගබඩා කළ යුතුය (එබැවින් වර්ණ වස්තු මිලියන 16 ක් යනු එම ශ්‍රිතයේම පිටපත් මිලියන 16 කි. මතකය). සංසන්දනය කිරීමෙන්, මූලාකෘතිය භාවිතා කිරීමෙන් එය එක් වරක් පමණක් නිර්මාණය වනු ඇත, වස්තුවට වඩා "පන්තිය" සමඟ සම්බන්ධ වීමට. මෙය පැහැදිලි මතක ප්‍රතිලාභ මෙන්ම වේගවත් ප්‍රතිලාභද ඇත.
Mwr247

20

පයිතන්

ඉතින් මෙන්න මගේ විසඳුම පයිතන් වල, එකක් සෑදීමට පැයකට ආසන්න කාලයක් ගත වේ, එබැවින් බොහෝ ප්‍රශස්තිකරණය කළ හැකිය:

import PIL.Image as Image
from random import shuffle
import math

def mulColor(color, factor):
    return (int(color[0]*factor), int(color[1]*factor), int(color[2]*factor))

def makeAllColors(arg):
    colors = []
    for r in range(0, arg):
        for g in range(0, arg):
            for b in range(0, arg):
                colors.append((r, g, b))
    return colors

def distance(color1, color2):
    return math.sqrt(pow(color2[0]-color1[0], 2) + pow(color2[1]-color1[1], 2) + pow(color2[2]-color1[2], 2))

def getClosestColor(to, colors):
    closestColor = colors[0]
    d = distance(to, closestColor)
    for color in colors:
        if distance(to, color) < d:
            closestColor = color
            d = distance(to, closestColor)
    return closestColor

imgsize = (256, 128)
#imgsize = (10, 10)
colors = makeAllColors(32)
shuffle(colors)
factor = 255.0/32.0
img = Image.new("RGB", imgsize, "white")
#start = (imgsize[0]/4, imgsize[1]/4)
start = (imgsize[0]/2, 0)
startColor = colors.pop()
img.putpixel(start, mulColor(startColor, factor))

#color = getClosestColor(startColor, colors)
#img.putpixel((start[0]+1, start[1]), mulColor(color, factor))

edgePixels = [(start, startColor)]
donePositions = [start]
for pixel in edgePixels:
    if len(colors) > 0:
        color = getClosestColor(pixel[1], colors)
    m = [(pixel[0][0]-1, pixel[0][1]), (pixel[0][0]+1, pixel[0][2]), (pixel[0][0], pixel[0][3]-1), (pixel[0][0], pixel[0][4]+1)]
    if len(donePositions) >= imgsize[0]*imgsize[1]:
    #if len(donePositions) >= 100:
        break
    for pos in m:
        if (not pos in donePositions):
            if not (pos[0]<0 or pos[1]<0 or pos[0]>=img.size[0] or pos[1]>=img.size[1]):
                img.putpixel(pos, mulColor(color, factor))
                #print(color)
                donePositions.append(pos)
                edgePixels.append((pos, color))
                colors.remove(color)
                if len(colors) > 0:
                    color = getClosestColor(pixel[1], colors)
    print((len(donePositions) * 1.0) / (imgsize[0]*imgsize[1]))
print len(donePositions)
img.save("colors.png")

උදාහරණ නිමැවුම් කිහිපයක් මෙන්න:

රූප විස්තරය මෙහි ඇතුළත් කරන්න රූප විස්තරය මෙහි ඇතුළත් කරන්න රූප විස්තරය මෙහි ඇතුළත් කරන්න රූප විස්තරය මෙහි ඇතුළත් කරන්න රූප විස්තරය මෙහි ඇතුළත් කරන්න


1
පිස්සු ශබ්ද තරංග ආකාර කිහිපයක් පෙනේ
මාර්ක් ජෙරොනිමස්

19

ජාවා

මෙම අභියෝගය අත්හදා බැලීමට මම තීරණය කළෙමි. මෙම පිළිතුරෙන් මා ආශ්වාදයක් ලැබීය තවත් කේතය ගොල්ෆ් කිරීමට. මගේ වැඩසටහන අවලස්සන රූප ජනනය කරයි, නමුත් ඒවාට සියලු වර්ණ ඇත.

එසේම, මගේ පළමු වරට කේත ගොල්ෆ් කිරීම. :)

(මගේ කුඩා උඩුගත කිරීමේ වේගය සඳහා පින්තූර 4k ඉතා විශාල විය, මම එකක් උඩුගත කිරීමට උත්සාහ කළ නමුත් පැයකට පසු එය උඩුගත කර නොමැත. ඔබට ඔබේම දෑ උත්පාදනය කළ හැකිය.)

සමීප රූපය:

මගේ යන්ත්‍රයේ තත්පර 70 කින් රූපයක් ජනනය කරයි, උත්පාදනය කිරීමේදී 1.5GB පමණ මතකයක් ගනී

Main.java

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Random;

import javax.imageio.ImageIO;


public class Main {
    static char[][] colors = new char[4096 * 4096][3];
    static short[][] pixels = new short[4096 * 4096][2];

    static short[][] iterMap = new short[4096][4096];  

    public static int mandel(double re0, double im0, int MAX_ITERS) {
        double re = re0;
        double im = im0;
        double _r;
        double _i;
        double re2;
        double im2;
        for (int iters = 0; iters < MAX_ITERS; iters++) {
            re2 = re * re;
            im2 = im * im;
            if (re2 + im2 > 4.0) {
                return iters;
            }
            _r = re;
            _i = im;
            _r = re2 - im2;
            _i = 2 * (re * im);
            _r += re0;
            _i += im0;
            re = _r;
            im = _i;
        }
        return MAX_ITERS;
    }

    static void shuffleArray(Object[] ar) {
        Random rnd = new Random();
        for (int i = ar.length - 1; i > 0; i--) {
          int index = rnd.nextInt(i + 1);
          // Simple swap
          Object a = ar[index];
          ar[index] = ar[i];
          ar[i] = a;
        }
      }

    public static void main(String[] args) {
        long startTime = System.nanoTime();

        System.out.println("Generating colors...");

        for (int i = 0; i < 4096 * 4096; i++) {
            colors[i][0] = (char)((i >> 16) & 0xFF); // Red
            colors[i][1] = (char)((i >> 8) & 0xFF);  // Green
            colors[i][2] = (char)(i & 0xFF);         // Blue
        }

        System.out.println("Sorting colors...");

        //shuffleArray(colors); // Not needed

        Arrays.sort(colors, new Comparator<char[]>() {
            @Override
            public int compare(char[] a, char[] b) {
                return (a[0] + a[1] + a[2]) - (b[0] + b[1] + b[2]);
            }
        });

        System.out.println("Generating fractal...");

        for (int y = -2048; y < 2048; y++) {
            for (int x = -2048; x < 2048; x++) {
                short iters = (short) mandel(x / 1024.0, y / 1024.0, 1024);
                iterMap[x + 2048][y + 2048] = iters;
            }
        }

        System.out.println("Organizing pixels in the image...");

        for (short x = 0; x < 4096; x++) {
            for (short y = 0; y < 4096; y++) {
                pixels[x * 4096 + y][0] = x;
                pixels[x * 4096 + y][1] = y;
            }
        }

        shuffleArray(pixels);

        Arrays.sort(pixels, new Comparator<short[]>() {
            @Override
            public int compare(short[] a, short[] b) {
                return iterMap[b[0]][b[1]] - iterMap[a[0]][a[1]];
            }
        });

        System.out.println("Writing image to BufferedImage...");

        BufferedImage img = new BufferedImage(4096, 4096, BufferedImage.TYPE_INT_RGB);
        Graphics2D g = img.createGraphics();

        for (int i = 0; i < 4096 * 4096; i++) {
            g.setColor(new Color(colors[i][0], colors[i][1], colors[i][2]));
            g.fillRect(pixels[i][0], pixels[i][1], 1, 1);
        }

        g.dispose();

        System.out.println("Writing image to file...");

        File imageFile = new File("image.png");

        try {
            ImageIO.write(img, "png", imageFile);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        System.out.println("Done!");
        System.out.println("Took " + ((System.nanoTime() - startTime) / 1000000000.) + " seconds.");
        System.out.println();
        System.out.println("The result is saved in " + imageFile.getAbsolutePath());

    }

}

18

ගණිතය

colors = Table[
r = y*256 + x; {BitAnd[r, 2^^111110000000000]/32768., 
BitAnd[r, 2^^1111100000]/1024., BitAnd[r, 2^^11111]/32.}, {y, 0, 
127}, {x, 0, 255}];
SeedRandom[1337];
maxi = 5000000;
Monitor[For[i = 0, i < maxi, i++,
x1 = RandomInteger[{2, 255}];
x2 = RandomInteger[{2, 255}];
y1 = RandomInteger[{2, 127}];
y2 = RandomInteger[{2, 127}];
c1 = colors[[y1, x1]];
c2 = colors[[y2, x2]];
ca1 = (colors[[y1 - 1, x1]] + colors[[y1, x1 - 1]] + 
  colors[[y1 + 1, x1]] + colors[[y1, x1 + 1]])/4.;
ca2 = (colors[[y2 - 1, x2]] + colors[[y2, x2 - 1]] + 
  colors[[y2 + 1, x2]] + colors[[y2, x2 + 1]])/4.;
d1 = Abs[c1[[1]] - ca1[[1]]] + Abs[c1[[2]] - ca1[[2]]] + 
Abs[c1[[3]] - ca1[[3]]];
d1p = Abs[c2[[1]] - ca1[[1]]] + Abs[c2[[2]] - ca1[[2]]] + 
Abs[c2[[3]] - ca1[[3]]];
d2 = Abs[c2[[1]] - ca2[[1]]] + Abs[c2[[2]] - ca2[[2]]] + 
Abs[c2[[3]] - ca2[[3]]];
d2p = Abs[c1[[1]] - ca2[[1]]] + Abs[c1[[2]] - ca2[[2]]] + 
Abs[c1[[3]] - ca2[[3]]];
If[(d1p + d2p < 
  d1 + d2) || (RandomReal[{0, 1}] < 
   Exp[-Log10[i]*(d1p + d2p - (d1 + d2))] && i < 1000000),
temp = colors[[y1, x1]];
colors[[y1, x1]] = colors[[y2, x2]];
colors[[y2, x2]] = temp
]
], ProgressIndicator[i, {1, maxi}]]
Image[colors]

ප්‍රති ult ලය (2x):

256x128 2x

මුල් 256x128 රූපය

සංස්කරණය කරන්න:

Log10 [i] වෙනුවට Log10 [i] / 5 ආදේශ කිරීමෙන් ඔබට ලැබෙන්නේ: රූප විස්තරය මෙහි ඇතුළත් කරන්න

ඉහත කේතය අනුකරණය කරන ලද ඇනලීකරණයට සම්බන්ධ වේ. මේ ආකාරයෙන් දුටු විට, පළමු රූපය 10 ^ 6 පියවරයන්හි වැඩි "උෂ්ණත්වයක්" සහිතව දෙවන රූපය නිර්මාණය වේ. ඉහළ “උෂ්ණත්වය” පික්සෙල් අතර වැඩි ප්‍රේරණයක් ඇති කරන අතර පළමු රූපයේ ඇණවුම් කළ රූපයේ ව්‍යුහය තවමත් තරමක් දෘශ්‍යමාන වේ.


18

සී #

ඒ නිසා මම මෙය විනෝද ව්‍යායාමයක් ලෙස වැඩ කිරීමට පටන් ගත් අතර අවම වශයෙන් මට පිළිවෙළකට පෙනෙන නිමැවුමක් සමඟ අවසන් විය. (අවම වශයෙන්) අනෙක් අයට මගේ විසඳුමේ ඇති ප්‍රධාන වෙනස නම්, ආරම්භ කිරීමට අවශ්‍ය වර්ණ ගණන හරියටම ජනනය කිරීම සහ පරම්පරාව පිරිසිදු සුදු සිට පිරිසිදු කළු දක්වා ඒකාකාරව පරතරය තැබීමයි. මම ද අභ්‍යන්තර සර්පිලාකාරයක වැඩ කරන වර්ණ සකසා ඇති අතර, සකසා ඇති සියලුම අසල්වැසියන් අතර වර්ණයේ වෙනස මත පදනම්ව ඊළඟ වර්ණය තෝරා ගනිමි.

මෙන්න මම මෙතෙක් නිපදවා ඇති කුඩා නියැදි නිමැවුමක්, මම 4k විදැහුම්කරණයක වැඩ කරමින් සිටිමි, නමුත් එය අවසන් වීමට දිනකට වැඩි කාලයක් ගතවනු ඇතැයි මම අපේක්ෂා කරමි.

256x128 හි පිරිවිතර ප්‍රතිදානයේ නියැදියක් මෙන්න:

පිරිවිතර විදැහුම්කරණය

තවමත් සාධාරණ විදැහුම් කාලයන් සහිත විශාල පින්තූර කිහිපයක්:

360 x 240 ට යොමු කරන්න

360 x 240 හි දෙවන ධාවනය වඩාත් සුමට රූපයක් නිපදවීය

360 x 240 ට # 2 යොමු කරන්න

කාර්ය සාධනය වැඩි දියුණු කිරීමෙන් පසු මට HD රෙන්ඩරයක් ධාවනය කිරීමට හැකි වූ අතර එය දින 2 ක් ගතවිය, මම තවම 4k අතහැර දමා නැති නමුත් සති කිහිපයක් ගතවනු ඇත.

HD විදැහුම්කරණය

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;

namespace SandBox
{
    class Program
    {
        private static readonly List<Point> directions = new List<Point>
        {
            new Point(1, 0),
            new Point(0, 1),
            new Point(-1, 0),
            new Point(0, -1)
        };

        static void Main(string[] args)
        {
            if (args.Length != 2)
            {
                HelpFile();
                return;
            }
            try
            {
                var config = new ColorGeneratorConfig
                {
                    XLength = int.Parse(args[0]),
                    YLength = int.Parse(args[1])
                };

                Console.WriteLine("Starting image generation with:");
                Console.WriteLine($"\tDimensions:\t\t{config.XLength} X {config.YLength}");
                Console.WriteLine($"\tSteps Per Channel:\t{config.NumOfSteps}");
                Console.WriteLine($"\tStep Size:\t\t{config.ColorStep}");
                Console.WriteLine($"\tSteps to Skip:\t\t{config.StepsToSkip}\n");

                var runner = new TaskRunner();
                var colors = runner.Run(() => GenerateColorList(config), "color selection");
                var pixels = runner.Run(() => BuildPixelArray(colors, config), "pixel array generation");
                runner.Run(() => OutputBitmap(pixels, config), "bitmap creation");
            }
            catch (Exception ex)
            {
               HelpFile("There was an issue in execution");
            }

            Console.ReadLine();
        }

        private static void HelpFile(string errorMessage = "")
        {
            const string Header = "Generates an image with every pixel having a unique color";
            Console.WriteLine(errorMessage == string.Empty ? Header : $"An error has occured: {errorMessage}\n Ensure the Arguments you have provided are valid");
            Console.WriteLine();
            Console.WriteLine($"{AppDomain.CurrentDomain.FriendlyName} X Y");
            Console.WriteLine();
            Console.WriteLine("X\t\tThe Length of the X dimension eg: 256");
            Console.WriteLine("Y\t\tThe Length of the Y dimension eg: 128");
        }

        public static List<Color> GenerateColorList(ColorGeneratorConfig config)
        {

            //Every iteration of our color generation loop will add the iterationfactor to this accumlator which is used to know when to skip
            decimal iterationAccumulator = 0;

            var colors = new List<Color>();
            for (var r = 0; r < config.NumOfSteps; r++)
                for (var g = 0; g < config.NumOfSteps; g++)
                    for (var b = 0; b < config.NumOfSteps; b++)
                    {
                        iterationAccumulator += config.IterationFactor;

                        //If our accumulator has reached 1, then subtract one and skip this iteration
                        if (iterationAccumulator > 1)
                        {
                            iterationAccumulator -= 1;
                            continue;
                        }

                        colors.Add(Color.FromArgb(r*config.ColorStep, g*config.ColorStep,b*config.ColorStep));
                    }
            return colors;
        }

        public static Color?[,] BuildPixelArray(List<Color> colors, ColorGeneratorConfig config)
        {
            //Get a random color to start with.
            var random = new Random(Guid.NewGuid().GetHashCode());
            var nextColor = colors[random.Next(colors.Count)];

            var pixels = new Color?[config.XLength, config.YLength];
            var currPixel = new Point(0, 0);

            var i = 0;

            //Since we've only generated exactly enough colors to fill our image we can remove them from the list as we add them to our image and stop when none are left.
            while (colors.Count > 0)
            {
                i++;

                //Set the current pixel and remove the color from the list.
                pixels[currPixel.X, currPixel.Y] = nextColor;
                colors.RemoveAt(colors.IndexOf(nextColor));

                //Our image generation works in an inward spiral generation GetNext point will retrieve the next pixel given the current top direction.
                var nextPixel = GetNextPoint(currPixel, directions.First());

                //If this next pixel were to be out of bounds (for first circle of spiral) or hit a previously generated pixel (for all other circles)
                //Then we need to cycle the direction and get a new next pixel
                if (nextPixel.X >= config.XLength || nextPixel.Y >= config.YLength || nextPixel.X < 0 || nextPixel.Y < 0 ||
                    pixels[nextPixel.X, nextPixel.Y] != null)
                {
                    var d = directions.First();
                    directions.RemoveAt(0);
                    directions.Add(d);
                    nextPixel = GetNextPoint(currPixel, directions.First());
                }

                //This code sets the pixel to pick a color for and also gets the next color
                //We do this at the end of the loop so that we can also support haveing the first pixel set outside of the loop
                currPixel = nextPixel;

                if (colors.Count == 0) continue;

                var neighbours = GetNeighbours(currPixel, pixels, config);
                nextColor = colors.AsParallel().Aggregate((item1, item2) => GetAvgColorDiff(item1, neighbours) <
                                                                            GetAvgColorDiff(item2, neighbours)
                    ? item1
                    : item2);
            }

            return pixels;
        }

        public static void OutputBitmap(Color?[,] pixels, ColorGeneratorConfig config)
        {
            //Now that we have generated our image in the color array we need to copy it into a bitmap and save it to file.
            var image = new Bitmap(config.XLength, config.YLength);

            for (var x = 0; x < config.XLength; x++)
                for (var y = 0; y < config.YLength; y++)
                    image.SetPixel(x, y, pixels[x, y].Value);

            using (var file = new FileStream($@".\{config.XLength}X{config.YLength}.png", FileMode.Create))
            {
                image.Save(file, ImageFormat.Png);
            }
        }

        static Point GetNextPoint(Point current, Point direction)
        {
            return new Point(current.X + direction.X, current.Y + direction.Y);
        }

        static List<Color> GetNeighbours(Point current, Color?[,] grid, ColorGeneratorConfig config)
        {
            var list = new List<Color>();
            foreach (var direction in directions)
            {
                var xCoord = current.X + direction.X;
                var yCoord = current.Y + direction.Y;
                if (xCoord < 0 || xCoord >= config.XLength|| yCoord < 0 || yCoord >= config.YLength)
                {
                    continue;
                }
                var cell = grid[xCoord, yCoord];
                if (cell.HasValue) list.Add(cell.Value);
            }
            return list;
        }

        static double GetAvgColorDiff(Color source, IList<Color> colors)
        {
            return colors.Average(color => GetColorDiff(source, color));
        }

        static int GetColorDiff(Color color1, Color color2)
        {
            var redDiff = Math.Abs(color1.R - color2.R);
            var greenDiff = Math.Abs(color1.G - color2.G);
            var blueDiff = Math.Abs(color1.B - color2.B);
            return redDiff + greenDiff + blueDiff;
        }
    }

    public class ColorGeneratorConfig
    {
        public int XLength { get; set; }
        public int YLength { get; set; }

        //Get the number of permutations for each color value base on the required number of pixels.
        public int NumOfSteps
            => (int)Math.Ceiling(Math.Pow((ulong)XLength * (ulong)YLength, 1.0 / ColorDimensions));

        //Calculate the increment for each step
        public int ColorStep
            => 255 / (NumOfSteps - 1);

        //Because NumOfSteps will either give the exact number of colors or more (never less) we will sometimes to to skip some
        //this calculation tells how many we need to skip
        public decimal StepsToSkip
            => Convert.ToDecimal(Math.Pow(NumOfSteps, ColorDimensions) - XLength * YLength);

        //This factor will be used to as evenly as possible spread out the colors to be skipped so there are no large gaps in the spectrum
        public decimal IterationFactor => StepsToSkip / Convert.ToDecimal(Math.Pow(NumOfSteps, ColorDimensions));

        private double ColorDimensions => 3.0;
    }

    public class TaskRunner
    {
        private Stopwatch _sw;
        public TaskRunner()
        {
            _sw = new Stopwatch();
        }

        public void Run(Action task, string taskName)
        {
            Console.WriteLine($"Starting {taskName}...");
            _sw.Start();
            task();
            _sw.Stop();
            Console.WriteLine($"Finished {taskName}. Elapsed(ms): {_sw.ElapsedMilliseconds}");
            Console.WriteLine();
            _sw.Reset();
        }

        public T Run<T>(Func<T> task, string taskName)
        {
            Console.WriteLine($"Starting {taskName}...");
            _sw.Start();
            var result = task();
            _sw.Stop();
            Console.WriteLine($"Finished {taskName}. Elapsed(ms): {_sw.ElapsedMilliseconds}");
            Console.WriteLine();
            _sw.Reset();
            return result;
        }
    }
}

වර්ණ තේරීමේ ඇල්ගොරිතමයේ ක්‍රියාකාරිත්වය වැඩි දියුණු කරන්නේ කෙසේද යන්න පිළිබඳව යමෙකුට යම් අදහසක් ඇත්නම් කරුණාකර මට දන්වන්න, 360 * 240 විදැහුම්කරණයට මිනිත්තු 15 ක් පමණ ගත වේ. එය සමාන්තරගත කළ හැකි යැයි මම විශ්වාස නොකරමි, නමුත් අවම වර්ණ වෙනස ලබා ගැනීමට වේගවත් ක්‍රමයක් තිබේදැයි මම කල්පනා කරමි.

360 * 240 රූපයක් 'සියලු වර්ණ' වලින් සමන්විත වන්නේ කෙසේද? ඔබ එක් සංරචකයකට වර්ණ cbrt (360 * 240) = 44.208377983684639269357874002958 නිෂ්පාදනය කරන්නේ කෙසේද?
මාර්ක් ජෙරොනිමස්

මෙය කුමන භාෂාවද? මෙම ඇල්ගොරිතමය හා ක්රියාත්මක මත පදනම්ව එය පක්ෂග්රාහී ප්රතිඵල හෝ බව පවසමින් ව්යතිරේකයක් ඇති හැකි බැවින් ලැයිස්තුව ආකාරයක හා සසම්භාවී Randomizing නරක අදහසක්, නොතකා ය "Comparison method violates its general contract!"කොන්ත්රාත්තුව බවයි නිසා: (x.compareTo(y)>0 && y.compareTo(z)>0) implies x.compareTo(z)>0. ලැයිස්තුවක් අහඹු ලෙස කිරීමට, සපයා ඇති ෂෆල් ක්‍රමයක් භාවිතා කරන්න. ( colors.Shuffle()?)
මාර්ක් ජෙරොනිමස්

Ark මාක් ජෙරොනිමස් 256x128 රූපය පිළිබඳ පිරිවිතර මට මග හැරී ඇති බව මම පිළිගනිමි, එම ප්‍රමාණයන් භාවිතා කරමින් සරල විදැහුම් කිරීම් මම නැවත කරමි, සෑම පික්සෙල් එකකම මම අවධානය යොමු කළේ අභියෝගයේ අද්විතීය වර්ණ අංගයක් වන අතර අනෙකුත් ඉදිරිපත් කිරීම් සිදු කර ඇති ආකාරයට විශාල විදැහුම්කරණයකි.

Ark මාක් ජෙරොනිමස් අහඹු ලෙස වර්ග කිරීම නරක බව මට වැටහී ඇත, ඇත්ත වශයෙන්ම අදහස් දැක්වීමක් තිබේ. මෙය මා විසින් ආරම්භ කිරීමට පටන් ගත් තවත් ප්‍රවේශයක ඉතිරියක් පමණක් වන අතර විශාල විදැහුම්කරණයන් සෑහෙන කාලයක් ගත වන බැවින් ඒවා ලබා ගැනීමට මම ප්‍රමුඛත්වය දුනිමි.

17

ජාවාස්ක්‍රිප්ට්

තවමත් ශිෂ්‍යයෙකු සහ මගේ පළමු වරට පළ කිරීම නිසා මගේ කේත බොහෝ විට අවුල් සහගත වන අතර මගේ පින්තූරවලට අවශ්‍ය වර්ණ ඇති බව මට 100% ක් විශ්වාස නැත, නමුත් මගේ ප්‍රති results ල ගැන මම අතිශයින් සතුටු වෙමි, එබැවින් මම ඒවා පළ කරනු ඇතැයි සිතුවෙමි.

තරගය අවසන් බව මම දනිමි, නමුත් මේවායේ ප්‍රති results ල වලට මම සැබවින්ම ඇලුම් කළෙමි. පුනරාවර්තන පසුපෙළ ජනනය කරන ලද මේස් වල පෙනුමට මම සැමවිටම ඇලුම් කළෙමි. එබැවින් වර්ණ පික්සල් තැබුවහොත් එහි පෙනුම කෙබඳුදැයි බැලීමට එය සිසිල් යැයි මම සිතුවෙමි. ඒ නිසා මම අරාවෙහි සියලු වර්ණ උත්පාදනය කිරීමෙන් ආරම්භ කරමි, පසුව මම අරාව වෙතින් වර්ණ පිටවන අතර පුනරාවර්තන පසුපෙළ කිරීම කරමි.

මෙන්න මගේ JSFiddle http://jsfiddle.net/Kuligoawesome/3VsCu/

// Global variables
const FPS = 60;// FrameRate
var canvas = null;
var ctx = null;

var bInstantDraw = false;
var MOVES_PER_UPDATE = 50; //How many pixels get placed down
var bDone = false;
var width; //canvas width
var height; //canvas height
var colorSteps = 32;

var imageData;
var grid;
var colors;

var currentPos;
var prevPositions;

// This is called when the page loads
function Init()
{
    canvas = document.getElementById('canvas'); // Get the HTML element with the ID of 'canvas'
    width = canvas.width;
    height = canvas.height;
    ctx = canvas.getContext('2d'); // This is necessary, but I don't know exactly what it does

    imageData = ctx.createImageData(width,height); //Needed to do pixel manipulation

    grid = []; //Grid for the labyrinth algorithm
    colors = []; //Array of all colors
    prevPositions = []; //Array of previous positions, used for the recursive backtracker algorithm

    for(var r = 0; r < colorSteps; r++)
    {
        for(var g = 0; g < colorSteps; g++)
        {
            for(var b = 0; b < colorSteps; b++)
            {
                colors.push(new Color(r * 255 / (colorSteps - 1), g * 255 / (colorSteps - 1), b * 255 / (colorSteps - 1)));
                //Fill the array with all colors
            }
        }
    }

    colors.sort(function(a,b)
    {
        if (a.r < b.r)
            return -1;
        if (a.r > b.r)
            return 1;
        if (a.g < b.g)
            return -1;
        if (a.g > b.g)
            return 1;
        if (a.b < b.b)
            return -1;
        if (a.b > b.b)
            return 1;
        return 0;
    });

    for(var x = 0; x < width; x++)
    {
        grid.push(new Array());
        for(var y = 0; y < height; y++)
        {
            grid[x].push(0); //Set up the grid
            //ChangePixel(imageData, x, y, colors[x + (y * width)]);
        }
    }

    currentPos = new Point(Math.floor(Math.random() * width),Math.floor(Math.random() * height)); 

    grid[currentPos.x][currentPos.y] = 1;
    prevPositions.push(currentPos);
    ChangePixel(imageData, currentPos.x, currentPos.y, colors.pop());

    if(bInstantDraw)
    {
        do
        {
            var notMoved = true;
            while(notMoved)
            {
                var availableSpaces = CheckForSpaces(grid);

                if(availableSpaces.length > 0)
                {
                    var test = availableSpaces[Math.floor(Math.random() * availableSpaces.length)];
                    prevPositions.push(currentPos);
                    currentPos = test;
                    grid[currentPos.x][currentPos.y] = 1;
                    ChangePixel(imageData, currentPos.x, currentPos.y, colors.pop());
                    notMoved = false;
                }
                else
                {
                    if(prevPositions.length != 0)
                    {
                        currentPos = prevPositions.pop();
                    }
                    else
                    {
                        break;
                    }
                }
            }
        }
        while(prevPositions.length > 0)

        ctx.putImageData(imageData,0,0);
    }
    else
    {
        setInterval(GameLoop, 1000 / FPS);
    }
}

// Main program loop
function GameLoop()
{
    Update();
    Draw();
}

// Game logic goes here
function Update()
{
    if(!bDone)
    {
        var counter = MOVES_PER_UPDATE;
        while(counter > 0) //For speeding up the drawing
        {
            var notMoved = true;
            while(notMoved)
            {
                var availableSpaces = CheckForSpaces(grid); //Find available spaces

                if(availableSpaces.length > 0) //If there are available spaces
                {
                    prevPositions.push(currentPos); //add old position to prevPosition array
                    currentPos = availableSpaces[Math.floor(Math.random() * availableSpaces.length)]; //pick a random available space
                    grid[currentPos.x][currentPos.y] = 1; //set that space to filled
                    ChangePixel(imageData, currentPos.x, currentPos.y, colors.pop()); //pop color of the array and put it in that space
                    notMoved = false;
                }
                else
                {
                    if(prevPositions.length != 0)
                    {
                        currentPos = prevPositions.pop(); //pop to previous position where spaces are available
                    }
                    else
                    {
                        bDone = true;
                        break;
                    }
                }
            }
            counter--;
        }
    }
}
function Draw()
{
    // Clear the screen
    ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
    ctx.fillStyle='#000000';
    ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height);

    ctx.putImageData(imageData,0,0);
}

function CheckForSpaces(inGrid) //Checks for available spaces then returns back all available spaces
{
    var availableSpaces = [];

    if(currentPos.x > 0 && inGrid[currentPos.x - 1][currentPos.y] == 0)
    {
        availableSpaces.push(new Point(currentPos.x - 1, currentPos.y));
    }

    if(currentPos.x < width - 1 && inGrid[currentPos.x + 1][currentPos.y] == 0)
    {
        availableSpaces.push(new Point(currentPos.x + 1, currentPos.y));
    }

    if(currentPos.y > 0 && inGrid[currentPos.x][currentPos.y - 1] == 0)
    {
        availableSpaces.push(new Point(currentPos.x, currentPos.y - 1));
    }

    if(currentPos.y < height - 1 && inGrid[currentPos.x][currentPos.y + 1] == 0)
    {
        availableSpaces.push(new Point(currentPos.x, currentPos.y + 1));
    }

    return availableSpaces;
}

function ChangePixel(data, x, y, color) //Quick function to simplify changing pixels
{
    data.data[((x + (y * width)) * 4) + 0] = color.r;
    data.data[((x + (y * width)) * 4) + 1] = color.g;
    data.data[((x + (y * width)) * 4) + 2] = color.b;
    data.data[((x + (y * width)) * 4) + 3] = 255;
}

/*Needed Classes*/
function Point(xIn, yIn)
{
    this.x = xIn;
    this.y = yIn;
}

function Color(r, g, b)
{
    this.r = r;
    this.g = g;
    this.b = b;
    this.hue = Math.atan2(Math.sqrt(3) * (this.g - this.b), 2 * this.r - this.g, this.b);
    this.min = Math.min(this.r, this.g);
    this.min = Math.min(this.min, this.b);
    this.min /= 255;
    this.max = Math.max(this.r, this.g);
    this.max = Math.max(this.max, this.b);
    this.max /= 255;
    this.luminance = (this.min + this.max) / 2;
    if(this.min === this.max)
    {
        this.saturation = 0;
    }
    else if(this.luminance < 0.5)
    {
        this.saturation = (this.max - this.min) / (this.max + this.min);
    }
    else if(this.luminance >= 0.5)
    {
        this.saturation = (this.max - this.min) / (2 - this.max - this.min);
    }
}

256x128 පින්තූරය, වර්ණ වර්ග රතු-> කොළ-> නිල්
RGB වර්ග කළ වර්ණ

256x128 පින්තූරය, වර්ණ වර්ග කළ නිල්-> කොළ-> රතු
BGR වර්ග කළ වර්ණ

256x128 පින්තූරය, වර්ණ වර්ග කළ වර්ණ-> දීප්තිය-> සන්තෘප්තිය
HLS වර්ග කළ වර්ණ

අවසානයේදී ජනනය වන එකක GIF එකක්
වර්ණ ලැබ්රින්ත් GIF


ඔබේ වර්ණ දීප්තිමත්ම කලාපවල ඇලවී ඇති අතර අනුපිටපත් ඇති වේ. වෙනස් r * Math.ceil(255 / (colorSteps - 1)කිරීමට r * Math.floor(255 / (colorSteps - 1), හෝ ඊටත් වඩා හොඳින්: r * 255 / (colorSteps - 1)(, පරීක්ෂා නොකල ඔබ jsfiddle සැපයීමට නැති නිසා)
මාර්ක් Jeronimus

අපොයි, ඔව්, මට හැඟීමක් ඇති විය, එය දැන් ස්ථාවර වී ඇති අතර, jsfiddle හි lack නතාවය ගැන කණගාටුයි (එය පවතින බව මම දැන සිටියේ නැත!) ස්තූතියි!
කුලිගෝවොව්

ඇණවුම් කළ අවුල් සහගත / ශබ්දය දෙස බලන ප්‍රතිදානයට සහ සමාන ප්‍රතිදානයක් නිපදවන තවත් විසඳුමකට මම කැමතියි.
r_alex_hall

17

මෙම රූප "ලැන්ග්ටන්ගේ දේදුන්න" ය. ඒවා සරලව ඇද ඇත: ලැන්ග්ටන්ගේ කුහුඹුවා ගමන් කරන විට, පළමු වරට පික්සෙල් දර්ශනය වූ විට එක් එක් පික්සෙල් මත වර්ණයක් අඳිනු ලැබේ. ඊළඟට ඇඳිය ​​යුතු වර්ණය 1 කින් සරලව වැඩි කර වර්ණ 2 ^ 15 භාවිතා කරන බව සහතික කරයි, එක් එක් පික්සෙල් සඳහා එකක්.

සංස්කරණය කරන්න: මම වර්ණ 2 ^ 24 භාවිතා කරමින් පින්තූර 4096X4096 විදහා දක්වන අනුවාදයක් සාදන ලදී. වර්ණ ද 'පරාවර්තනය' වන බැවින් ඒවා සිනිඳු ශ්‍රේණියක් සාදයි. මම ඔවුන්ට සබැඳි ලබා දෙන්නේ ඒවා විශාල බැවින් (> 28 MB)

ලැන්ග්ටන්ගේ දේදුන්න විශාල, පාලනය එල්.ආර්

ලැන්ග්ටන්ගේ දේදුන්න විශාලයි, එල්එල්ආර් පාලනය කරන්න

// සංස්කරණයේ අවසානය.

මෙය සම්භාව්‍ය LR රීති කට්ටලය සඳහා:

ලැන්ග්ටන්ගේ රේන්බෝ එල්.ආර්

මෙන්න එල්එල්ආර්ආර්:

ලැන්ග්ටන්ගේ රේන්බෝ එල්එල්ආර්ආර්

අවසාන වශයෙන්, මෙය LRRRRRLLR රීසෙට් එක භාවිතා කරයි:

ලැන්ග්ටන්ගේ රේන්බෝ එල්ආර්ආර්ආර්ආර්එල්එල්ආර්

ග්‍රැෆික් සඳහා CImg භාවිතා කරමින් C ++ හි ලියා ඇත. වර්ණ තෝරාගත් ආකාරය ද මා සඳහන් කළ යුතුය: පළමුව, මම RGB වර්ණ දත්ත අඩංගු කිරීම සඳහා අත්සන් නොකළ කෙටි භාවිතා කරමි. සෛලයක් ප්‍රථම වරට දර්ශනය වූ සෑම අවස්ථාවකම, මම බිටු 5 න් ගුණනයකින්, 31 කින්, පසුව 8 කින් ගුණ කරන්නෙමි. එවිට අත්සන් නොකළ කෙටි වර්ණය 1 කින් වැඩි වේ. මෙය 0 සිට 248 දක්වා අගයන් නිපදවයි. කෙසේ වෙතත්, මම මෙම අගය රතු සහ නිල් සංරචක 255 සිට අඩු කරමි , එබැවින් R සහ B 8 ගුණක වලින් යුක්ත වන අතර එය 255 සිට 7 දක්වා පහත වේ:

c[0]=255-((color&0x1F)*8);
c[2]=255-(((color>>5)&0x1F)*8);
c[1]=(((color>>10)&0x1F)*8);

කෙසේ වෙතත්, මෙය හරිත සං component ටකයට අදාළ නොවේ, එය 0 සිට 248 දක්වා 8 කින් ගුණ කළ යුතුය. ඕනෑම අවස්ථාවක, සෑම පික්සෙල් එකකම අද්විතීය වර්ණයක් අඩංගු විය යුතුය.

කෙසේ වෙතත්, ප්‍රභව කේතය පහතින්:

#include "CImg.h"
using namespace cimg_library;
CImgDisplay screen;
CImg<unsigned char> surf;
#define WIDTH 256
#define HEIGHT 128
#define TOTAL WIDTH*HEIGHT
char board[WIDTH][HEIGHT];


class ant
{
  public:
  int x,y;
  char d;
  unsigned short color;
  void init(int X, int Y,char D)
  {
    x=X;y=Y;d=D;
    color=0;
  }

  void turn()
  {
    ///Have to hard code for the rule set here.
    ///Make sure to set RULECOUNT to the number of rules!
    #define RULECOUNT 9
    //LRRRRRLLR
    char get=board[x][y];
    if(get==0||get==6||get==7){d+=1;}
    else{d-=1;}
    if(d<0){d=3;}
    else if(d>3){d=0;}
  }

  void forward()
  {
    if(d==0){x++;}
    else if(d==1){y--;}
    else if(d==2){x--;}
    else {y++;}
    if(x<0){x=WIDTH-1;}
    else if(x>=WIDTH){x=0;}
    if(y<0){y=HEIGHT-1;}
    else if(y>=HEIGHT){y=0;}
  }

  void draw()
  {
    if(board[x][y]==-1)
    {
      board[x][y]=0;
      unsigned char c[3];
      c[0]=255-((color&0x1F)*8);
      c[2]=255-(((color>>5)&0x1F)*8);
      c[1]=(((color>>10)&0x1F)*8);
      surf.draw_point(x,y,c);
      color++;
    }

    board[x][y]++;
    if(board[x][y]==RULECOUNT){board[x][y]=0;}

  }

  void step()
  {
    draw();
    turn();
    forward();
  }
};

void renderboard()
{
  unsigned char white[]={200,190,180};
  surf.draw_rectangle(0,0,WIDTH,HEIGHT,white);
  for(int x=0;x<WIDTH;x++)
  for(int y=0;y<HEIGHT;y++)
  {
    char get=board[x][y];
    if(get==1){get=1;unsigned char c[]={255*get,255*get,255*get};
    surf.draw_point(x,y,c);}
    else if(get==0){get=0;unsigned char c[]={255*get,255*get,255*get};
    surf.draw_point(x,y,c);}
  }
}

int main(int argc, char** argv)
{

  screen.assign(WIDTH*3,HEIGHT*3);
  surf.assign(WIDTH,HEIGHT,1,3);
  ant a;
  a.init(WIDTH/2,HEIGHT/2,2);
  surf.fill(0);
  for(int x=0;x<WIDTH;x++)
  for(int y=0;y<HEIGHT;y++)
  {
    board[x][y]=-1;
  }

  while(a.color<TOTAL)
  {
    a.step();
  }

  screen=surf;
  while(screen.is_closed()==false)
  {
    screen.wait();
  }
  surf.save_bmp("LangtonsRainbow.bmp");
  return 0;
}

1
සාදරයෙන් පිළිගනිමු, සමාජ ශාලාවට බැඳෙන්න. Code.google.com/p/ruletablerepository/wiki/… වෙතින් වෙනත් ටර්මිටයිට් අත්හදා බැලීම සිත්ගන්නාසුළු විය හැකිය (මා එයට සහභාගී විය)
මාර්ක් ජෙරොනිමස්

3
ඩ්‍රොප්බොක්ස් පොදු ෆෝල්ඩර මරා දැමූ නිසා රූප සබැඳි මිය ගොස් ඇත.
user2428118

16

යන්න

මෙන්න මගෙන් තවත් එකක්, මම හිතන්නේ එය වඩාත් රසවත් ප්‍රති results ල ලබා දෙයි:

package main

import (
    "image"
    "image/color"
    "image/png"
    "os"

    "math"
    "math/rand"
)

func distance(c1, c2 color.Color) float64 {
    r1, g1, b1, _ := c1.RGBA()
    r2, g2, b2, _ := c2.RGBA()
    rd, gd, bd := int(r1)-int(r2), int(g1)-int(g2), int(b1)-int(b2)
    return math.Sqrt(float64(rd*rd + gd*gd + bd*bd))
}

func main() {
    allcolor := image.NewRGBA(image.Rect(0, 0, 256, 128))
    for y := 0; y < 128; y++ {
        for x := 0; x < 256; x++ {
            allcolor.Set(x, y, color.RGBA{uint8(x%32) * 8, uint8(y%32) * 8, uint8(x/32+(y/32*8)) * 8, 255})
        }
    }

    for y := 0; y < 128; y++ {
        for x := 0; x < 256; x++ {
            rx, ry := rand.Intn(256), rand.Intn(128)

            c1, c2 := allcolor.At(x, y), allcolor.At(rx, ry)
            allcolor.Set(x, y, c2)
            allcolor.Set(rx, ry, c1)
        }
    }

    for i := 0; i < 16384; i++ {
        for y := 0; y < 128; y++ {
            for x := 0; x < 256; x++ {
                xl, xr := (x+255)%256, (x+1)%256
                cl, c, cr := allcolor.At(xl, y), allcolor.At(x, y), allcolor.At(xr, y)
                dl, dr := distance(cl, c), distance(c, cr)
                if dl < dr {
                    allcolor.Set(xl, y, c)
                    allcolor.Set(x, y, cl)
                }

                yu, yd := (y+127)%128, (y+1)%128
                cu, c, cd := allcolor.At(x, yu), allcolor.At(x, y), allcolor.At(x, yd)
                du, dd := distance(cu, c), distance(c, cd)
                if du < dd {
                    allcolor.Set(x, yu, c)
                    allcolor.Set(x, y, cu)
                }
            }
        }
    }

    filep, err := os.Create("EveryColor.png")
    if err != nil {
        panic(err)
    }
    err = png.Encode(filep, allcolor)
    if err != nil {
        panic(err)
    }
    filep.Close()
}

එය ආරම්භ වන්නේ මගේ අනෙක් පිළිතුරේ ඇති gif හා සමාන රටාවෙනි . ඉන්පසුව, එය මෙයට මාරු කරයි:

ශබ්දය පමණි

අසල්වැසි සංසන්දනය කිරීමේ ඇල්ගොරිතම මම වැඩි වැඩියෙන් ක්‍රියාත්මක කරන විට දේදුන්න රටාව වඩාත් පැහැදිලිව පෙනේ.

මෙන්න 16384:

16384 පුනරාවර්තන වලදී ඉතා is ෝෂාකාරී දේදුන්නක්

සහ 65536:

රූප විස්තරය මෙහි ඇතුළත් කරන්න


6
+1 මම කැමතියි එයින් රටාවක් මතු වේ; ඔබ එය සජීවිකරණය කළ යුතුයි!
ජේසන් සී

15

රූබි

මම තීරණය කළා මම ඉදිරියට ගොස් PNG මුල සිටම සාදන්න, එය සිත්ගන්නාසුළු යැයි මා සිතූ නිසා. මෙම කේතය වචනාර්ථයෙන් අමු ප්‍රතිදානය කරයි ද්විමය දත්ත ගොනුවකට .

මම 512x512 අනුවාදය කළා. (ඇල්ගොරිතම තරමක් උනන්දුවක් නොදක්වයි.) එය මගේ යන්ත්‍රයෙන් තත්පර 3 කින් අවසන් වේ.

require 'zlib'

class RBPNG
  def initialize
    # PNG header
    @data = [137, 80, 78, 71, 13, 10, 26, 10].pack 'C*'
  end

  def chunk name, data = ''
    @data += [data.length].pack 'N'
    @data += name
    @data += data
    @data += [Zlib::crc32(name + data)].pack 'N'
  end

  def IHDR opts = {}
    opts = {bit_depth: 8, color_type: 6, compression: 0, filter: 0, interlace: 0}.merge opts
    raise 'IHDR - Missing width param' if !opts[:width]
    raise 'IHDR - Missing height param' if !opts[:height]

    self.chunk 'IHDR', %w[width height].map {|x| [opts[x.to_sym]].pack 'N'}.join +
                       %w[bit_depth color_type compression filter interlace].map {|x| [opts[x.to_sym]].pack 'C'}.join
  end

  def IDAT data; self.chunk 'IDAT', Zlib.deflate(data); end
  def IEND; self.chunk 'IEND'; end
  def write filename; IO.binwrite filename, @data; end
end

class Color
  attr_accessor :r, :g, :b, :a

  def initialize r = 0, g = 0, b = 0, a = 255
    if r.is_a? Array
      @r, @g, @b, @a = @r
      @a = 255 if !@a
    else
      @r = r
      @g = g
      @b = b
      @a = a
    end
  end

  def hex; '%02X' * 4 % [@r, @g, @b, @a]; end
  def rgbhex; '%02X' * 3 % [@r, @g, @b]; end
end

img = RBPNG.new
img.IHDR({width: 512, height: 512, color_type: 2})
#img.IDAT ['00000000FFFFFF00FFFFFF000000'].pack 'H*'
r = g = b = 0
data = Array.new(512){ Array.new(512){
  c = Color.new r, g, b
  r += 4
  if r == 256
    r = 0
    g += 4
    if g == 256
      g = 0
      b += 4
    end
  end
  c
} }
img.IDAT [data.map {|x| '00' + x.map(&:rgbhex).join }.join].pack 'H*'
img.IEND
img.write 'all_colors.png'

ප්‍රතිදානය (තුළ all_colors.png) (මෙම පින්තූර විශාල කර ගැනීමට ඒවායින් එකක් ක්ලික් කරන්න):

ප්‍රතිදානය

තරමක් රසවත් ග්‍රේඩියෙන්ට්-ඊෂ් ප්‍රතිදානය (4 වන සිට අවසාන පේළිය දක්වා වෙනස් කිරීමෙන් }.shuffle }):

නිමැවුම් 2

එය වෙනස් කිරීමෙන් }.shuffle }.shuffleඔබට පිස්සු වර්ණ රේඛා ලැබේ:

නිමැවුම් 3


ඒක නියමයි. ඔබට එය වඩාත් ලස්සන කළ හැකි ක්‍රමයක් තිබේද? සමහර විට පික්සෙල් අහඹු ලෙස වෙනස් කළ හැකිද? Scoring is by vote. Vote for the most beautiful images made by the most elegant code.

1
OwerLowerClassOverflowian හරි, සංස්කරණය කරන ලදි
Doorknob

වඩා හොඳයි !!!!!!!

1
ඔබ 4 වන සිට අවසාන පේළිය දක්වා වෙනස් කළහොත් කුමක් සිදුවේද }.shuffle }.shuffle }.shuffle?
ජෝන් ඕඩම්

6
@ ජෝන් අර්ම්, සින්ටැක්ස් දෝෂය, බොහෝ විට?
දොරක්නොබ්

14

පයිතන්

ප්ලාස්මා

දීප්තියෙන් වර්ණ වර්ග කිරීම සඳහා පයිතන් භාවිතා කිරීම, දීප්තිමත් රටාවක් ජනනය කිරීම සහ වඩාත් සුදුසු වර්ණය තෝරා ගැනීම. පික්සෙල් අහඹු ලෙස අනුපිළිවෙලට සකසා ඇති අතර එමඟින් ලබා ගත හැකි වර්ණ ලැයිස්තුව කුඩා වන විට ස්වභාවිකව සිදුවන අඩු වාසිදායක දීප්තිය ගැලපීම් පින්තූරය පුරා ඒකාකාරව පැතිරෙයි.

#!/usr/bin/env python

from PIL import Image
from math import pi, sin, cos
import random

WIDTH = 256
HEIGHT = 128

img = Image.new("RGB", (WIDTH, HEIGHT))

colors = [(x >> 10, (x >> 5) & 31, x & 31) for x in range(32768)]
colors = [(x[0] << 3, x[1] << 3, x[2] << 3) for x in colors]
colors.sort(key=lambda x: x[0] * 0.2126 + x[1] * 0.7152 + x[2] * 0.0722)

def get_pixel(lum):
    for i in range(len(colors)):
        c = colors[i]
        if c[0] * 0.2126 + c[1] * 0.7152 + c[2] * 0.0722 > lum:
            break
    return colors.pop(i)

def plasma(x, y):
    x -= WIDTH / 2
    p = sin(pi * x / (32 + 10 * sin(y * pi / 32)))
    p *= cos(pi * y / 64)
    return 128 + 127 * p

xy = []
for x in range(WIDTH):
    for y in range(HEIGHT):
        xy.append((x, y))
random.shuffle(xy)

count = 0
for x, y in xy:
    l = int(plasma(x, y))
    img.putpixel((x, y), get_pixel(plasma(x, y)))
    count += 1
    if not count & 255:
        print "%d pixels rendered" % count

img.save("test.png")

13

ජාවා

import java.awt.Point;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;

/**
 *
 * @author Quincunx
 */
public class AllColorImage {

    public static void main(String[] args) {
        BufferedImage img = new BufferedImage(4096, 4096, BufferedImage.TYPE_INT_RGB);
        int num = 0;
        ArrayList<Point> points = new ArrayList<>();
        for (int y = 0; y < 4096; y++) {
            for (int x = 0; x < 4096 ; x++) {
                points.add(new Point(x, y));
            }
        }
        for (Point p : points) {
            int x = p.x;
            int y = p.y;

            img.setRGB(x, y, num);
            num++;
        }
        try {
            ImageIO.write(img, "png", new File("Filepath"));
        } catch (IOException ex) {
            Logger.getLogger(AllColorImage.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}

මම 4096 ට 4096 ට ගියෙමි, එසේ නොකර සියලු වර්ණ ලබා ගන්නේ කෙසේදැයි මට සිතාගත නොහැකි විය.

ප්‍රතිදානය:

මෙහි ගැළපෙන තරමට විශාලයි. මෙය තිර රුවක්:

රූප විස්තරය මෙහි ඇතුළත් කරන්න

කුඩා වෙනසක් සමඟ, අපට වඩාත් ලස්සන පින්තූරයක් ලබා ගත හැකිය:

Collections.shuffle(points, new Random(0));ලකුණු උත්පාදනය කිරීම සහ වර්ණ කිරීම අතර එකතු කරන්න :

import java.awt.Point;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Random;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;

/**
 *
 * @author Quincunx
 */
public class AllColorImage {

    public static void main(String[] args) {
        BufferedImage img = new BufferedImage(4096, 4096, BufferedImage.TYPE_INT_RGB);
        int num = 0;
        ArrayList<Point> points = new ArrayList<>();
        for (int y = 0; y < 4096; y++) {
            for (int x = 0; x < 4096 ; x++) {
                points.add(new Point(x, y));
            }
        }
        Collections.shuffle(points, new Random(0));
        for (Point p : points) {
            int x = p.x;
            int y = p.y;

            img.setRGB(x, y, num);
            num++;
        }
        try {
            ImageIO.write(img, "png", new File("Filepath"));
        } catch (IOException ex) {
            Logger.getLogger(AllColorImage.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}

රූප විස්තරය මෙහි ඇතුළත් කරන්න

සමීප රූපය:

රූප විස්තරය මෙහි ඇතුළත් කරන්න


29
ඔබ විශාල අළු මලකට "ලස්සන" යැයි කියන්නේ?
දොරක්නොබ්

22
O ඩෝර්ක්නොබ් ඔව්. මම එය ඉතා ලස්සන ලෙස හඳුන්වමි. සියලු වර්ණ විශාල අළු පැහැති මල් පිපීමකට සකසා ගත හැකි වීම පුදුම සහගතය. මම විශාලනය කරන විට බ්ලොබ් එක වඩාත් සිත්ගන්නාසුළුය. තව ටිකක් විස්තර සහිතව, ජාවාගේ අහඹු අහඹු ආකාරය ඔබට දැක ගත හැකිය. දෙවන තිර දර්ශනය මෙන් අපි ඊටත් වඩා විශාලනය කරන විට, එම දෙයෙහි වර්ණ කීයක් තිබේද යන්න පැහැදිලි වේ. මම තව දුරටත් විශාලනය කරන විට, එය පියට් වැඩසටහනක් සේ පෙනේ.
ජස්ටින්

මම පහළ බිටු අතහැර කුඩා අනුවාද වල වර්ණ ලබා ගතිමි.
මාර්ක් ජෙරොනිමස්

ඔව්, ඒ සඳහා අඩු බිටු r, gසහ b, ෙවන් ෙවන් වශෙයන්, නමුත් මම එක සංඛ්යාව ලෙස ඔවුන් සමඟ කටයුතු කරන ලදී.
ජස්ටින්

ඔබේ ඊළඟ පිළිතුරෙන් ඔබ තේ 1 බී මැජික් හදුනාගෙන ඇති බව මට පෙනේ. මාතෘකාව මත, Randomඊටත් වඩා අඩු පරිපූර්ණ අහඹු සංඛ්‍යා නිපදවන ඔබේම උප පංතිය සමඟ අත්හදා බැලීම සිත්ගන්නා සුළු විය හැකිය .
මාර්ක් ජෙරොනිමස්

13

සී ++ 11

( යාවත්කාලීන කිරීම:හා සමාන ප්‍රවේශයක් දැනටමත් උත්සාහ කර ඇති බව මා දුටුවේ --- පුනරාවර්තන ගණන සම්බන්ධයෙන් වඩාත් ඉවසීමෙන්.)

සෑම පික්සෙල් සඳහාම, මම අසල්වැසි පික්සෙල් කට්ටලයක් අර්ථ දක්වමි. පික්සල් දෙකක් අතර ඇති විෂමතාවය ඒවායේ R / G / B වෙනස්කම් වල වර්ගවල එකතුව ලෙස මම අර්ථ දක්වන්නෙමි. දී ඇති පික්සෙල් එකක ද penalty ුවම නම් පික්සෙල් සහ එහි අසල්වැසියන් අතර ඇති විෂමතාවන්ගේ එකතුවයි.

දැන්, මම පළමුව අහඹු ලෙස ප්‍රේරණයක් ජනනය කර, පසුව අහඹු ලෙස පික්සල් යුගල තෝරා ගැනීම ආරම්භ කරමි. පික්සෙල් දෙක මාරු කිරීමෙන් සියලු පික්සෙල්වල මුළු ද ties ුවම් එකතුව අඩු වේ නම්, හුවමාරුව සිදු වේ. මම මෙය මිලියනයකට වරක් පුනරාවර්තනය කරමි.

ප්‍රතිදානය පීපීඑම් ආකෘතියෙන් වන අතර එය සම්මත උපයෝගීතා භාවිතයෙන් මම පීඑන්ජී බවට පරිවර්තනය කර ඇත්තෙමි.

මූලාශ්රය:

#include <iostream>
#include <fstream>
#include <cstdlib>
#include <random>

static std::mt19937 rng;

class Pixel
{
public:
    int r, g, b;

    Pixel() : r(0), g(0), b(0) {}
    Pixel(int r, int g, int b) : r(r), g(g), b(b) {}

    void swap(Pixel& p)
    {
        int r = this->r,  g = this->g,    b = this->b;
        this->r = p.r;    this->g = p.g;  this->b = p.b;
        p.r = r;          p.g = g;        p.b = b;
    }
};

class Image
{
public:
    static const int width = 256;
    static const int height = 128;
    static const int step = 32;
    Pixel pixel[width*height];
    int penalty[width*height];
    std::vector<int>** neighbors;

    Image()
    {
        if (step*step*step != width*height)
        {
            std::cerr << "parameter mismatch" << std::endl;
            exit(EXIT_FAILURE);
        }

        neighbors = new std::vector<int>*[width*height];

        for (int i = 0; i < width*height; i++)
        {
            penalty[i] = -1;
            neighbors[i] = pixelNeighbors(i);
        }

        int i = 0;
        for (int r = 0; r < step; r++)
        for (int g = 0; g < step; g++)
        for (int b = 0; b < step; b++)
        {
            pixel[i].r = r * 255 / (step-1);
            pixel[i].g = g * 255 / (step-1);
            pixel[i].b = b * 255 / (step-1);
            i++;
        }
    }

    ~Image()
    {
        for (int i = 0; i < width*height; i++)
        {
            delete neighbors[i];
        }
        delete [] neighbors;
    }

    std::vector<int>* pixelNeighbors(const int pi)
    {
        // 01: X-shaped structure
        //const int iRad = 7, jRad = 7;
        //auto condition = [](int i, int j) { return abs(i) == abs(j); };
        //
        // 02: boring blobs
        //const int iRad = 7, jRad = 7;
        //auto condition = [](int i, int j) { return true; };
        //
        // 03: cross-shaped
        //const int iRad = 7, jRad = 7;
        //auto condition = [](int i, int j) { return i==0 || j == 0; };
        //
        // 04: stripes
        const int iRad = 1, jRad = 5;
        auto condition = [](int i, int j) { return i==0 || j == 0; };

        std::vector<int>* v = new std::vector<int>;

        int x = pi % width;
        int y = pi / width;

        for (int i = -iRad; i <= iRad; i++)
        for (int j = -jRad; j <= jRad; j++)
        {
            if (!condition(i,j))
                continue;

            int xx = x + i;
            int yy = y + j;

            if (xx < 0 || xx >= width || yy < 0 || yy >= height)
                continue;

            v->push_back(xx + yy*width);
        }

        return v;
    }

    void shuffle()
    {
        for (int i = 0; i < width*height; i++)
        {
            std::uniform_int_distribution<int> dist(i, width*height - 1);
            int j = dist(rng);
            pixel[i].swap(pixel[j]);
        }
    }

    void writePPM(const char* filename)
    {
        std::ofstream fd;
        fd.open(filename);
        if (!fd.is_open())
        {
            std::cerr << "failed to open file " << filename
                      << "for writing" << std::endl;
            exit(EXIT_FAILURE);
        }
        fd << "P3\n" << width << " " << height << "\n255\n";
        for (int i = 0; i < width*height; i++)
        {
            fd << pixel[i].r << " " << pixel[i].g << " " << pixel[i].b << "\n";
        }
        fd.close();
    }

    void updatePixelNeighborhoodPenalty(const int pi)
    {
        for (auto j : *neighbors[pi])
            updatePixelPenalty(j);
    }

    void updatePixelPenalty(const int pi)
    {
        auto pow2 = [](int x) { return x*x; };
        int pen = 0;
        Pixel* p1 = &pixel[pi];
        for (auto j : *neighbors[pi])
        {
            Pixel* p2 = &pixel[j];
            pen += pow2(p1->r - p2->r) + pow2(p1->g - p2->g) + pow2(p1->b - p2->b);
        }
        penalty[pi] = pen / neighbors[pi]->size();
    }

    int getPixelPenalty(const int pi)
    {
        if (penalty[pi] == (-1))
        {
            updatePixelPenalty(pi);
        }
        return penalty[pi];
    }

    int getPixelNeighborhoodPenalty(const int pi)
    {
        int sum = 0;
        for (auto j : *neighbors[pi])
        {
            sum += getPixelPenalty(j);
        }
        return sum;
    }

    void iterate()
    {
        std::uniform_int_distribution<int> dist(0, width*height - 1);       

        int i = dist(rng);
        int j = dist(rng);

        int sumBefore = getPixelNeighborhoodPenalty(i)
                        + getPixelNeighborhoodPenalty(j);

        int oldPenalty[width*height];
        std::copy(std::begin(penalty), std::end(penalty), std::begin(oldPenalty));

        pixel[i].swap(pixel[j]);
        updatePixelNeighborhoodPenalty(i);
        updatePixelNeighborhoodPenalty(j);

        int sumAfter = getPixelNeighborhoodPenalty(i)
                       + getPixelNeighborhoodPenalty(j);

        if (sumAfter > sumBefore)
        {
            // undo the change
            pixel[i].swap(pixel[j]);
            std::copy(std::begin(oldPenalty), std::end(oldPenalty), std::begin(penalty));
        }
    }
};

int main(int argc, char* argv[])
{
    int seed;
    if (argc >= 2)
    {
        seed = atoi(argv[1]);
    }
    else
    {
        std::random_device rd;
        seed = rd();
    }
    std::cout << "seed = " << seed << std::endl;
    rng.seed(seed);

    const int numIters = 1000000;
    const int progressUpdIvl = numIters / 100;
    Image img;
    img.shuffle();
    for (int i = 0; i < numIters; i++)
    {
        img.iterate();
        if (i % progressUpdIvl == 0)
        {
            std::cout << "\r" << 100 * i / numIters << "%";
            std::flush(std::cout);
        }
    }
    std::cout << "\rfinished!" << std::endl;
    img.writePPM("AllColors2.ppm");

    return EXIT_SUCCESS;
}

අසල්වැසියන්ගේ පියවර වෙනස් කිරීමෙන් වෙනස් ප්‍රති .ල ලැබේ. Image :: pixelNeighbers () ශ්‍රිතයේ මෙය වෙනස් කළ හැකිය. කේතයට විකල්ප හතරක් සඳහා උදාහරණ ඇතුළත් වේ: (මූලාශ්‍රය බලන්න)

උදාහරණ 01 උදාහරණ 02 උදාහරණ 03 උදාහරණ 04

සංස්කරණය කරන්න: ඉහත හතරවන උදාහරණයට සමාන නමුත් විශාල කර්නලයක් සහ තවත් පුනරාවර්තන සහිත තවත් උදාහරණයක්:

උදාහරණ 05

තව එකක්: භාවිතා කිරීම

const int iRad = 7, jRad = 7;
auto condition = [](int i, int j) { return (i % 2==0 && j % 2==0); };

සහ පුනරාවර්තන මිලියන දහයක්, මට මෙය ලැබුණි:

උදාහරණ 06


12

AWK සහ මිතුරන්.

බලන්න අම්මා! මම වර්ණ ඉවතට විසි කර දැමුවෙමි!

'X' ගොනුව:

BEGIN {
    N=5
    C=2^N
    print "P3\n"2^(3*N-int(3*N/2))" "2^int(3*N/2)"\n"C-1
    for(x=0;x<C;x++)
        for(y=0;y<C;y++)
            for(z=0;z<C;z++)
                print x^4+y^4+z^4"\t"x" "y" "z | "sort -n | cut -f2-" 
}

ධාවනය:

awk -f x > x.ppm

ප්‍රතිදානය:

N = 5:

N = 5.png

N = 6:

N = 6.png


11

වඩාත්ම අලංකාර කේතය නොව, කරුණු දෙකක් මත සිත්ගන්නා සුළුය: මානයන්ගෙන් වර්ණ ගණන ගණනය කිරීම (මානයන්හි නිෂ්පාදිතය දෙකක බලයක් පවතින තාක් කල්), සහ ත්‍රිත්ව වර්ණ අවකාශ දේවල් කිරීම:

void Main()
{
    var width = 256;
    var height = 128;
    var colorCount = Math.Log(width*height,2);
    var bitsPerChannel = colorCount / 3;
    var channelValues = Math.Pow(2,bitsPerChannel);
    var channelStep = (int)(256/channelValues);

    var colors = new List<Color>();

    var m1 = new double[,] {{0.6068909,0.1735011,0.2003480},{0.2989164,0.5865990,0.1144845},{0.00,0.0660957,1.1162243}};
    for(var r=0;r<255;r+=channelStep)
    for(var g=0;g<255;g+=channelStep)
    for(var b=0;b<255;b+=channelStep)   
    {
        colors.Add(Color.FromArgb(0,r,g,b));
    }
    var sortedColors = colors.Select((c,i)=>
                            ToLookupTuple(MatrixProduct(m1,new[]{c.R/255d,c.G/255d,c.B/255d}),i))
                            .Select(t=>new
                                            {
                                                x = (t.Item1==0 && t.Item2==0 && t.Item3==0) ? 0 : t.Item1/(t.Item1+t.Item2+t.Item3),
                                                y = (t.Item1==0 && t.Item2==0 && t.Item3==0) ? 0 :t.Item2/(t.Item1+t.Item2+t.Item3),
                                                z = (t.Item1==0 && t.Item2==0 && t.Item3==0) ? 0 :t.Item3/(t.Item1+t.Item2+t.Item3),
                                                Y = t.Item2,
                                                i = t.Item4
                                            })
                            .OrderBy(t=>t.x).Select(t=>t.i).ToList();
    if(sortedColors.Count != (width*height))
    {
        throw new Exception(string.Format("Some colors fell on the floor: {0}/{1}",sortedColors.Count,(width*height)));
    }
    using(var bmp = new Bitmap(width,height,PixelFormat.Format24bppRgb))
    {
        for(var i=0;i<colors.Count;i++)
        {
            var y = i % height;
            var x = i / height;

            bmp.SetPixel(x,y,colors[sortedColors[i]]);
        }
        //bmp.Dump(); //For LINQPad use
        bmp.Save("output.png");
    }
}
static Tuple<double,double,double,int>ToLookupTuple(double[] t, int index)
{
    return new Tuple<double,double,double,int>(t[0],t[1],t[2],index);
}

public static double[] MatrixProduct(double[,] matrixA,
    double[] vectorB)
{
    double[] result=new double[3];
    for (int i=0; i<3; ++i) // each row of A
        for (int k=0; k<3; ++k)
            result[i]+=matrixA[i,k]*vectorB[k];
    return result;
}

OrderBy වගන්තිය වෙනස් කිරීමෙන් සමහර රසවත් වෙනස්කම් තිබිය හැකිය:

x:

රූප විස්තරය මෙහි ඇතුළත් කරන්න

y:

රූප විස්තරය මෙහි ඇතුළත් කරන්න

z:

රූප විස්තරය මෙහි ඇතුළත් කරන්න

වයි:

රූප විස්තරය මෙහි ඇතුළත් කරන්න

පළමු තුනේ අමුතු රේඛා ඇතිවීමට හේතුව කුමක්දැයි මට දැනගත හැකි යැයි මම ප්‍රාර්ථනා කරමි


2
එම අමුතු රේඛා බොහෝ විට යම් ආකාරයක හෝ බැලීමේ ක්‍රමයක නැඹුරුව විය හැකිය (ද්විමය සෙවීම / ක්වික්සෝර්ට්?)
මාර්ක් ජෙරොනිමස්

මම ඇත්තටම මෙහි රේඛාවලට කැමතියි.
ජේසන් සී
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.