Search Unity

c# trouble creating seamless voronoi....

Discussion in 'Scripting' started by Veqtor, May 1, 2012.

  1. Veqtor

    Veqtor

    Joined:
    Apr 17, 2012
    Posts:
    21
    So I'm trying to extend some functionality of libnoise, but I've hit a bump....

    $voronoi.jpg

    Note how some cells seem to be wrapping seamlessly, but not others...

    The part you're looking at now is the "if (this.m_distance)" part which creates gradients in the cells.

    I'm not too good with this type of math, I just tried to strap on some more distances and this seamless code:
    http://brianin3d-demos.appspot.com/static/demos/random/voronoi.xml

    Code (csharp):
    1. using System;
    2. using System.Collections.Generic;
    3. using System.Linq;
    4. using System.Text;
    5.  
    6. namespace LibNoise.Unity.Generator
    7. {
    8.     /// <summary>
    9.     /// Provides a noise module that outputs Voronoi cells. [GENERATOR]
    10.     /// </summary>
    11.     public class Voronoi : ModuleBase
    12.     {
    13.         #region Fields
    14.  
    15.         private double m_displacement = 1.0;
    16.         private double m_frequency = 1.0;
    17.         private int m_seed = 0;
    18.         private bool m_distance = false;
    19.         private bool m_showcells = true;
    20.         private int m_dist_type = 1;
    21.         private double w = 1.0, h = 1.0, dpt = 1.0;
    22.         private bool m_wrap = true;
    23.        
    24.         public int EUCLIDEAN = 1;
    25.         public int CITYBLOCK = 2;
    26.         public int MANHATTAN = 3;
    27.         public int QUADRATIC = 4;
    28.  
    29.         #endregion
    30.  
    31.         #region Constructors
    32.  
    33.         /// <summary>
    34.         /// Initializes a new instance of Voronoi.
    35.         /// </summary>
    36.         public Voronoi()
    37.             : base(0)
    38.         {
    39.         }
    40.  
    41.         /// <summary>
    42.         /// Initializes a new instance of Voronoi.
    43.         /// </summary>
    44.         /// <param name="frequency">The frequency of the first octave.</param>
    45.         /// <param name="displacement">The displacement of the ridged-multifractal noise.</param>
    46.         /// <param name="persistence">The persistence of the ridged-multifractal noise.</param>
    47.         /// <param name="seed">The seed of the ridged-multifractal noise.</param>
    48.         /// <param name="distance">Indicates whether the distance from the nearest seed point is applied to the output value.</param>
    49.         public Voronoi(double frequency, double displacement, int seed, bool distance)
    50.             : base(0)
    51.         {
    52.             this.Frequency = frequency;
    53.             this.Displacement = displacement;
    54.             this.Seed = seed;
    55.             this.UseDistance = distance;
    56.             this.Seed = seed;
    57.         }
    58.  
    59.         #endregion
    60.  
    61.         #region Properties
    62.  
    63.         /// <summary>
    64.         /// Gets or sets the displacement value of the Voronoi cells.
    65.         /// </summary>
    66.         public double Displacement
    67.         {
    68.             get { return this.m_displacement; }
    69.             set { this.m_displacement = value; }
    70.         }
    71.  
    72.         /// <summary>
    73.         /// Gets or sets the frequency of the seed points.
    74.         /// </summary>
    75.         public double Frequency
    76.         {
    77.             get { return this.m_frequency; }
    78.             set { this.m_frequency = value; }
    79.         }
    80.  
    81.         /// <summary>
    82.         /// Gets or sets the seed value used by the Voronoi cells.
    83.         /// </summary>
    84.         public int Seed
    85.         {
    86.             get { return this.m_seed; }
    87.             set { this.m_seed = value; }
    88.         }
    89.  
    90.         /// <summary>
    91.         /// Gets or sets a value whether the distance from the nearest seed point is applied to the output value.
    92.         /// </summary>
    93.         public bool UseDistance
    94.         {
    95.             get { return this.m_distance; }
    96.             set { this.m_distance = value; }
    97.         }
    98.        
    99.         public int DistType
    100.         {
    101.             get { return this.m_dist_type; }
    102.             set { this.m_dist_type = value; }
    103.         }
    104.         public bool ShowCells
    105.         {
    106.             get { return this.m_showcells; }
    107.             set { this.m_showcells = value; }
    108.         }
    109.  
    110.         #endregion
    111.  
    112.         #region ModuleBase Members
    113.  
    114.         /// <summary>
    115.         /// Returns the output value for the given input coordinates.
    116.         /// </summary>
    117.         /// <param name="x">The input coordinate on the x-axis.</param>
    118.         /// <param name="y">The input coordinate on the y-axis.</param>
    119.         /// <param name="z">The input coordinate on the z-axis.</param>
    120.         /// <returns>The resulting output value.</returns>
    121.         public override double GetValue(double x, double y, double z)
    122.         {
    123.             x *= this.m_frequency;
    124.             y *= this.m_frequency;
    125.             z *= this.m_frequency;
    126.             w = 1.0;
    127.             h = 1.0;
    128.             //dpt = this.m_frequency;
    129.             int xi = (x > 0.0 ? (int)x : (int)x - 1);
    130.             int iy = (y > 0.0 ? (int)y : (int)y - 1);
    131.             int iz = (z > 0.0 ? (int)z : (int)z - 1);
    132.             double md = 2147483647.0;
    133.             double xc = 0;
    134.             double yc = 0;
    135.             double zc = 0;
    136.             for (int zcu = iz - 2; zcu <= iz + 2; zcu++)
    137.             {
    138.                 for (int ycu = iy - 2; ycu <= iy + 2; ycu++)
    139.                 {
    140.                     for (int xcu = xi - 2; xcu <= xi + 2; xcu++)
    141.                     {
    142.                         double xp = xcu + Utils.ValueNoise3D(xcu, ycu, zcu, this.m_seed);
    143.                         double yp = ycu + Utils.ValueNoise3D(xcu, ycu, zcu, this.m_seed + 1);
    144.                         double zp = zcu + Utils.ValueNoise3D(xcu, ycu, zcu, this.m_seed + 2);
    145.                         double xd = xp - x;
    146.                         double yd = yp - y;
    147.                         double zd = zp - z;
    148.                         double d;
    149.                        
    150.                         if(m_wrap)
    151.                         {
    152.                             xd = Math.Abs(xd);
    153.                             yd = Math.Abs(yd);
    154.                             zd = Math.Abs(zd);
    155.                            
    156.                                 if ( xd > w / 2.0 ) {
    157.                                     if ( xp < x ) {
    158.                                         xd = xp + ( w - x );
    159.                                     } else {
    160.                                         xd = x + ( w - xp );
    161.                                     }
    162.                                 }
    163.                                 if ( yd > h / 2.0 ) {
    164.                                     if ( yp < y ) {
    165.                                         yd = yp + ( h - y );
    166.                                     } else {
    167.                                         yd = y + ( h - yp );
    168.                                     }
    169.                                 }
    170.                                 if ( zd > dpt / 2.0 ) {
    171.                                     if ( zp < z ) {
    172.                                         zd = zp + ( dpt - z );
    173.                                     } else {
    174.                                         zd = z + ( dpt - zp );
    175.                                     }
    176.                                 }
    177.                         }
    178.                        
    179.                         if (m_dist_type == CITYBLOCK) {
    180.                             d = Math.Max( Math.Max(Math.Abs(xd), Math.Abs(yd)), Math.Abs(zd));
    181.                             d *= d;
    182.                         } else if (m_dist_type == MANHATTAN) {
    183.                             d = Math.Abs(xd) + Math.Abs(yd) + Math.Abs(zd);
    184.                             d *= d;
    185.                         } else if (m_dist_type == QUADRATIC) {
    186.                             d = xd*xd + yd*yd + zd*zd + xd*yd + xd*zd + yd*zd;
    187.                             d *= d;
    188.                         } else {
    189.                             d = xd * xd + yd * yd + zd * zd;
    190.                         }
    191.                        
    192.                         if (d < md)
    193.                         {
    194.                             md = d;
    195.                             xc = xp;
    196.                             yc = yp;
    197.                             zc = zp;
    198.                         }
    199.                     }
    200.                 }
    201.             }
    202.             double v;
    203.             if (this.m_distance)
    204.             {  
    205.                
    206.                 double xd = xc - x;
    207.                 double yd = yc - y;
    208.                 double zd = zc - z;
    209.                
    210.                 if(m_wrap)
    211.                         {
    212.                             xd = Math.Abs(xd);
    213.                             yd = Math.Abs(yd);
    214.                             zd = Math.Abs(zd);
    215.                            
    216.                                 if ( xd > w / 2.0 ) {
    217.                                     if ( xc < x ) {
    218.                                         xd = xc + ( w - x );
    219.                                     } else {
    220.                                         xd = x + ( w - xc );
    221.                                     }
    222.                                 }
    223.                                 if ( yd > h / 2.0 ) {
    224.                                     if ( yc < y ) {
    225.                                         yd = yc + ( h - y );
    226.                                     } else {
    227.                                         yd = y + ( h - yc );
    228.                                     }
    229.                                 }
    230.                                 if ( zd > dpt / 2.0 ) {
    231.                                     if ( zc < z ) {
    232.                                         zd = zc + ( dpt - z );
    233.                                     } else {
    234.                                         zd = z + ( dpt - zc );
    235.                                     }
    236.                                 }
    237.                         }
    238.                
    239.                
    240.                 v = (Math.Sqrt(xd * xd + yd * yd + zd * zd)) * Utils.Sqrt3 - 1.0;
    241.             }
    242.             else
    243.             {
    244.                 v = 0.0;
    245.             }
    246.             if(this.m_showcells)
    247.             {
    248.             return v + (this.m_displacement * (double)Utils.ValueNoise3D((int)(Math.Floor(xc)), (int)(Math.Floor(yc)),
    249.               (int)(Math.Floor(zc)), 0));
    250.             }
    251.             return v;
    252.         }
    253.  
    254.         #endregion
    255.     }
    256. }
     
  2. UrKungFuNoGood

    UrKungFuNoGood

    Joined:
    Oct 25, 2014
    Posts:
    1
    Hi there. I know this is old but how I create tiling voronoi is to have a 3x3 array of tiles where each perimeter tile is an instance of the points created in the central tile. Do the math for all nine tiles and then clamp the resolution to only include the center.
    I really REALLY like your gradient solution. :cheers: