Esempio n. 1
0
        private void buttonGenerate_Click(object sender, EventArgs e)
        {
            // Lorentz attractor constants:
            // see http://paulbourke.net/fractals/lorenz/
            const double DT    = 0.004;
            const double DELTA = 10.0;
            const double R     = 28.0;
            const double B     = 8.0 / 3.0;

            // Lorentz attractor variables:
            double lx = 0.1;
            double ly = 0.0;
            double lz = 0.0;
            double dt, dx, dy, dz;

            Cursor.Current = Cursors.WaitCursor;

            // target image:
            pictureBox1.Image = null;
            if (output != null)
            {
                output.Dispose();
            }
            if (checkVisual.Checked)
            {
                output = new Bitmap(SIZE, SIZE, PixelFormat.Format24bppRgb);
            }
            else
            {
                output = null;
            }

            // random number generator:
            int    seed = (int)numericSeed.Value;
            Random rnd  = (seed == 0) ? new Random() : new Random(seed);

            // set size (number of line segments):
            int size = (int)numericSize.Value;

            segments = new List <Segment2D>(size);

            // line segment size:
            double lineMin = 300.0 / Math.Sqrt(size); // 0.3 for 10^6
            double lineRng = 500.0 / Math.Sqrt(size); // 0.5 for 10^6

            double x, y, x1, y1, x2, y2;

            for (int i = 0; i < size; i++)
            {
                do
                {
                    dt  = DT * (1.0 + rnd.NextDouble());
                    dx  = dt * (DELTA * (ly - lx));
                    dy  = dt * (lx * (R - lz) - ly);
                    dz  = dt * (lx * ly - B * lz);
                    lx += dx;
                    ly += dy;
                    lz += dz;
                    x   = 0.5 + 0.04 * lx;
                    y   = -0.2 + 0.03 * lz;
                } while (x < 0.0 || x > 1.0 ||
                         y < 0.0 || y > 1.0);

                x *= SIZE;
                y *= SIZE;
                double rad = lineMin + lineRng * rnd.NextDouble();
                double a   = rnd.NextDouble() * Math.PI;
                x2  = rad * Math.Sin(a);
                y2  = rad * Math.Cos(a);
                x1  = x - x2;
                y1  = y - y2;
                x2 += x;
                y2 += y;

                // the new line segment is ready:
                segments.Add(new Segment2D((float)x1, (float)y1, (float)x2, (float)y2));

                // draw the segment eventually:
                if (output != null)
                {
                    Draw.Line(output, (int)x1, (int)y1, (int)x2, (int)y2, Color.Blue);
                }
            }

            // Stopwatch - measuring the real time of KD-tree construction:
            Stopwatch sw = new Stopwatch();

            sw.Start();

            // Build the tree:
            tree = new KDTree();
            tree.BuildTree(segments);

            sw.Stop();
            // Build-phase statistics:
            long segStat, boxStat, heapStat;

            tree.GetStatistics(out segStat, out boxStat, out heapStat);
            string stat1 = string.Format(CultureInfo.InvariantCulture, "Elapsed: {0:f} s [{1:D}-{2:D}-{3:D}]",
                                         1.0e-3 * sw.ElapsedMilliseconds,
                                         segStat, boxStat, heapStat);

            labelStat.Text = stat1;
            Util.LogFormat("Build[ {0}, {1} ]: {2}", size, seed, stat1);

            if (output != null)
            {
                pictureBox1.Image = output;
            }

            Cursor.Current = Cursors.Default;
        }
Esempio n. 2
0
        private void buttonGenerate_Click( object sender, EventArgs e )
        {
            // Lorentz attractor constants:
              // see http://astronomy.swin.edu.au/~pbourke/fractals/lorenz/
              const double DT    = 0.004;
              const double DELTA = 10.0;
              const double R     = 28.0;
              const double B     = 8.0 / 3.0;

              const double LINE_RADIUS_MIN = 0.3;
              const double LINE_RADIUS_MAX = 1.0;

              // Lorentz attractor variables:
              double lx = 0.1;
              double ly = 0.0;
              double lz = 0.0;
              double dt, dx, dy, dz;

              Cursor.Current = Cursors.WaitCursor;

              // target image:
              if ( checkVisual.Checked )
            output = new Bitmap( SIZE, SIZE, System.Drawing.Imaging.PixelFormat.Format24bppRgb );
              else
            output = null;

              // random number generator:
              int seed = (int)numericSeed.Value;
              Random rnd = (seed == 0) ? new Random() : new Random( seed );

              // set size (number of line segments):
              int size = (int)numericSize.Value;
              segments = new List<Segment2D>( size );

              double x, y, x1, y1, x2, y2;
              for ( int i = 0; i < size; i++ )
              {
            do
            {
              dt = DT * (1.0 + rnd.NextDouble());
              dx = dt * (DELTA * (ly - lx));
              dy = dt * (lx * (R - lz) - ly);
              dz = dt * (lx * ly - B * lz);
              lx += dx;
              ly += dy;
              lz += dz;
              x =  0.5 + 0.04 * lx;
              y = -0.2 + 0.03 * lz;
            } while ( x < 0.0 || x > 1.0 ||
                  y < 0.0 || y > 1.0 );

            x *= SIZE;
            y *= SIZE;
            double rad = LINE_RADIUS_MIN + (LINE_RADIUS_MAX - LINE_RADIUS_MIN) * rnd.NextDouble();
            double a   = rnd.NextDouble() * Math.PI;
            x2 = rad * Math.Sin( a );
            y2 = rad * Math.Cos( a );
            x1 = x - x2;
            y1 = y - y2;
            x2 += x;
            y2 += y;

            // the new line segment is ready:
            segments.Add( new Segment2D( (float)x1, (float)y1, (float)x2, (float)y2 ) );

            // draw the segment eventually:
            if ( output != null )
              Draw.Line( output, (int)x1, (int)y1, (int)x2, (int)y2, Color.Blue );
              }

              // Stopwatch - measuring the real time of KD-tree construction:
              Stopwatch sw = new Stopwatch();
              sw.Start();

              // Build the tree:
              tree = new KDTree();
              tree.BuildTree( segments );

              sw.Stop();
              // Build-phase statistics:
              long segStat, boxStat, heapStat;
              tree.GetStatistics( out segStat, out boxStat, out heapStat );
              labelStat.Text = String.Format( "Elapsed: {0:f} s [{1:D}-{2:D}-{3:D}]",
                                      1.0e-3 * sw.ElapsedMilliseconds,
                                      segStat, boxStat, heapStat );
              if ( output != null )
            pictureBox1.Image = output;

              Cursor.Current = Cursors.Default;
        }
Esempio n. 3
0
        private void buttonQuery_Click(object sender, EventArgs e)
        {
            const int NEAREST = 200;

            Cursor.Current = Cursors.WaitCursor;

            // random number generator:
            int    seed = (int)numericSeed.Value;
            Random rnd  = (seed == 0) ? new Random() : new Random(seed);

            // set size (number of rays):
            int  size   = (int)numericQuery.Value;
            bool visual = (output != null) && checkVisual.Checked;

            // hash accumulator:
            long hash = 0L;

            int[]        result   = new int[NEAREST];
            const double colorMul = 1.0 / NEAREST;

            // reset the picture:
            if (visual)
            {
                foreach (Segment2D seg in segments)
                {
                    Draw.Line(output, (int)seg.x1, (int)seg.y1, (int)seg.x2, (int)seg.y2, Color.Blue);
                }
            }

            // Stopwatch - measuring the real time of KD-tree queries:
            Stopwatch sw = new Stopwatch();
            long      segStat, boxStat, heapStat, segCount = 0L;

            tree.GetStatistics(out segStat, out boxStat, out heapStat); // to be sure
            sw.Start();

            // Query loop:
            for (int i = 0; i++ < size;)
            {
                float  x0    = (float)(1.0 + (SIZE - 2.0) * rnd.NextDouble());
                float  y0    = (float)(1.0 + (SIZE - 2.0) * rnd.NextDouble());
                double angle = rnd.NextDouble() * Math.PI * 2.0;
                float  dx    = (float)Math.Sin(angle);
                float  dy    = (float)Math.Cos(angle);

                int n = tree.RayIntersect(x0, y0, dx, dy, NEAREST, result);
                if (n == 0)
                {
                    continue;
                }

                // check (and draw) the intersections:
                double last = 0.0; // distance of the last intersection

                for (int j = 0; j < n; j++)
                {
                    double dist = KDTree.RaySegment2D(x0, y0, dx, dy,
                                                      segments[result[j]].x1, segments[result[j]].y1,
                                                      segments[result[j]].x2, segments[result[j]].y2);
                    if (dist < last)
                    {
                        throw new Exception("Error in result ordering");
                    }
                    last = dist;

                    // the line segment is valid:
                    segCount++;
                    hash = hash * 348937L + result[j] * 8999L + 4831L;

                    // eventually draw the intersected segment in nice color:
                    if (visual)
                    {
                        Draw.Line(output,
                                  (int)segments[result[j]].x1, (int)segments[result[j]].y1,
                                  (int)segments[result[j]].x2, (int)segments[result[j]].y2,
                                  Draw.ColorRamp(1.0 - colorMul * j));
                    }
                }
#if LOG
                StringBuilder sb = new StringBuilder("Result[");
                sb.Append(i).Append("]:");
                for (int j = 0; j < n; j++)
                {
                    sb.Append(' ').Append(result[j]);
                }
                Util.Log(sb.ToString());
#endif
            }

            sw.Stop();

            // Query-phase statistics:
            tree.GetStatistics(out segStat, out boxStat, out heapStat);
            string stat1 = string.Format(CultureInfo.InvariantCulture, "Elapsed: {0:f} s [{1:D}-{2:D}-{3:D}-{4:D}]",
                                         1.0e-3 * sw.ElapsedMilliseconds,
                                         segCount, segStat, boxStat, heapStat);
            labelStat.Text = stat1;
            string stat2 = string.Format("{0:X}", hash);
            labelHash.Text = stat2;
            Util.LogFormat("Query[ {0}, {1}, {2} ]: hash: {3,16}, {4}",
                           (int)numericSize.Value, seed, size, stat2, stat1);

            if (visual)
            {
                pictureBox1.Invalidate();
            }
            Cursor.Current = Cursors.Default;
        }