예제 #1
0
        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            fpsCounter = 0;
            fpsStart   = DateTime.Now;
            double angle           = (double)e.Argument;
            int    counter         = 0;
            int    pctCounterValue = (trackBar1.Maximum * currentTimeFactor) / 100;

            if (pctCounterValue == 0)
            {
                pctCounterValue = 1;
            }
            //for (int ii = 0; ii < trackBar1.Maximum * currentTimeFactor; ii++)
            System.Threading.Tasks.Parallel.For(0, trackBar1.Maximum * currentTimeFactor, (ii) =>
            {
                int i = System.Threading.Interlocked.Increment(ref counter);
                if (backgroundWorker1.CancellationPending)
                {
                    e.Cancel = true;
                    return;
                }
                double currentTime = (double)i / currentTimeFactor;
                root.PlaceInTime(currentTime);
                var tmpDists = new DistPoint[pictureBox2.Width, pictureBox2.Height];
                List <RendererHelper.StarMoved> stars = RendererHelper.GetAngledStars(root, currentTime, angle);
                renderer.Render(stars, tmpDists, flux, i);
                SetDists(tmpDists);
                System.Threading.Interlocked.Increment(ref fpsCounter);
                if (i % pctCounterValue == 0)
                {
                    backgroundWorker1.ReportProgress(i * 100 / trackBar1.Maximum, i);
                }
            });
        }
예제 #2
0
        public void Render(List <RendererHelper.StarMoved> stars, DistPoint[,] dists, double[] flux, int fluxIndex)
        {
            DistPoint.Reset(dists);

            stars.Sort((a, b) => a.center.y.CompareTo(b.center.y));

            double width, height;

            RendererHelper.GetBoundingBox(stars, out width, out height);

            // +++ HACK
            //width = 45;
            //height = 10;
            // -- HACK

            int    xxmax      = dists.GetLength(0);
            int    yymax      = dists.GetLength(1);
            double zoomX      = xxmax / width;
            double zoomY      = yymax / height;
            double zoom       = Math.Min(zoomX, zoomY);
            int    xxoffs     = xxmax / 2;
            int    yyoffs     = yymax / 2;
            double brightness = 0;

            foreach (RendererHelper.StarMoved star in stars)
            {
                int x1 = (int)((star.center.x - star.radius) * zoom + xxoffs);
                int x2 = (int)((star.center.x + star.radius) * zoom + xxoffs + 1);
                int y1 = (int)((star.center.z - star.radius) * zoom + yyoffs);
                int y2 = (int)((star.center.z + star.radius) * zoom + yyoffs + 1);

                for (int yy = Math.Max(y1, 0); yy < Math.Min(y2, yymax); yy++)
                {
                    for (int xx = Math.Max(x1, 0); xx < Math.Min(x2, xxmax); xx++)
                    {
                        //if (!Double.IsInfinity(dists[xx, yy].dist))
                        //{ continue; }

                        double x = (xx - xxoffs) / zoom;
                        double z = (yy - yyoffs) / zoom;

                        double dist = Extensions.Distance(x - star.center.x, z - star.center.z);
                        if ((dist <= star.radius))
                        {
                            double theta    = Math.Asin(dist / star.radius);
                            double cosTheta = Math.Cos(theta);

                            //double ydist = star.center.y - dist;
                            double ydist = star.center.y - star.radius * cosTheta;
                            if (dists[xx, yy].dist < ydist)
                            {
                                continue;
                            }

                            double br = Physics.LimbDarkening(star.exitance, cosTheta);
                            dists[xx, yy].dist       = ydist;
                            dists[xx, yy].brightness = br;
                            brightness += br;
                        }
                    }
                }
            }

            #region Naivni

            /*
             * foreach (Star star in stars)
             * {
             *  for (int yy = 0; yy < yymax; yy++)
             *  {
             *      for (int xx = 0; xx < xxmax; xx++)
             *      {
             *          double x = (xx - xxoffs) / zoom;
             *          double z = (yy - yyoffs) / zoom;
             *
             *          double dist = Extensions.Distance(x - star.x, z);
             *          double ydist = star.y;
             *          if ((dist <= star.radius) && (dists[xx, yy].dist > ydist))
             *          {
             *              double theta = dist / star.radius;
             *              dists[xx, yy].dist = ydist;
             *              dists[xx, yy].brightness = (int)(Math.Cos(theta * Math.PI / 2) * 200) + 50;
             *          }
             *
             *      }
             *  }
             * }
             * for (int yy = 0; yy < yymax; yy++)
             * {
             *  for (int xx = 0; xx < xxmax; xx++)
             *  { brightness += dists[xx, yy].brightness; }
             * }
             */

            #endregion

            flux[fluxIndex] = brightness / (zoom * zoom);
        }
예제 #3
0
        public void Render(List <RendererHelper.StarMoved> stars, DistPoint[,] dists, double[] flux, int fluxIndex)
        {
            DistPoint.Reset(dists);

            double width, height;

            RendererHelper.GetBoundingBox(stars, out width, out height);

            // +++ HACK
            //width = 45;
            //height = 10;
            // -- HACK

            double viewAngle = 0;

            int    xxmax      = dists.GetLength(0);
            int    yymax      = dists.GetLength(1);
            double zoomX      = xxmax / width;
            double zoomY      = yymax / height;
            double zoom       = Math.Min(zoomX, zoomY);
            int    xxoffs     = xxmax / 2;
            int    yyoffs     = yymax / 2;
            double brightness = 0;

            double wdy = Math.Cos(viewAngle);
            double wdz = Math.Sin(viewAngle);

            double woy = -200 * wdy;
            double woz = -200 * wdz;

            for (int yy = 0; yy < yymax; yy++)
            {
                double y = (yy - yyoffs) / zoom;

                for (int xx = 0; xx < xxmax; xx++)
                {
                    Geometry.Line ray = new Geometry.Line(
                        origin: new Geometry.Point(
                            x: (xx - xxoffs) / zoom,
                            y: woy - y * wdz,
                            z: woz + y * wdy
                            ),
                        vector: new Geometry.Vector(
                            dx: 0,
                            dy: wdy,
                            dz: wdz
                            )
                        );

                    RendererHelper.StarMoved star;
                    double t = FindIntersection(stars, null, ray, out star);

                    if (star != null)
                    {
                        dists[xx, yy].dist = t;
                        Geometry.Point  hitPoint = ray.GetPoint(t);
                        Geometry.Vector normal   = star.sphere.GetNormal(hitPoint);
                        Geometry.Line   view     = new Geometry.Line(hitPoint, normal);
                        double          cosTheta = -Geometry.DotProduct(ray.vector, normal); // should be Geometry.CosAngle(...) but as both vectors are normalized this is the same
                        double          br       = Physics.LimbDarkening(star.exitance, cosTheta);

                        // ILLUMINATION
                        {
                            foreach (RendererHelper.StarMoved star2 in stars)
                            {
                                if (star2 == star)
                                {
                                    continue;
                                }

                                Geometry.Vector toStar2     = new Geometry.Vector(hitPoint, star2.center);
                                double          toStar2Size = toStar2.Size;
                                toStar2 = toStar2.Normalize();
                                double dp = Geometry.DotProduct(toStar2, normal);
                                if (dp > 0)
                                {
                                    double shadow = double.PositiveInfinity;
                                    foreach (RendererHelper.StarMoved star3 in stars)
                                    {
                                        if ((star3 == star) || (star3 == star2))
                                        {
                                            continue;
                                        }

                                        double p = Geometry.GetIntersectionMin(hitPoint, toStar2, star3.sphere);
                                        if (double.IsNaN(p) || double.IsInfinity(p))
                                        {
                                            continue;
                                        }

                                        if (p < shadow)
                                        {
                                            shadow = p;
                                        }
                                    }
                                    double d = toStar2Size - star2.radius;
                                    //if ((d > star2.radius / 10) && (d < shadow))
                                    if (d < shadow)
                                    {
                                        br += star2.exitance * dp / (d * d);
                                    }
                                }

                                #region failed attempt to count in nonzero radius

                                /*
                                 * failed attempt to count in nonzero radius
                                 *
                                 * Geometry.Point star2Closest = view.GetClosestPointTo(star2.center);
                                 * Geometry.Vector star2ToClosest = new Geometry.Vector(star2.center, star2Closest);
                                 * double u = Math.Min(star2ToClosest.Size, star2.radius);
                                 * Geometry.Point star2ViewClosest = new Geometry.Line(star2.center, star2ToClosest).GetPoint(u);
                                 * Geometry.Vector toStar2ViewClosest = new Geometry.Vector(hitPoint, star2ViewClosest);
                                 * toStar2ViewClosest.Normalize();
                                 * double dp2 = -Geometry.DotProduct(toStar2ViewClosest, normal);
                                 * if (dp2 > 0)
                                 * {
                                 *  double p1;
                                 *  double p2;
                                 *  Geometry.Line viewToClosest = new Geometry.Line(hitPoint, toStar2ViewClosest);
                                 *  int results = Geometry.GetIntersections(viewToClosest, star2.sphere, out p1, out p2);
                                 *  if (results > 0)
                                 *  {
                                 *      double p;
                                 *      if (p1 < 0)
                                 *      { p = p2; }
                                 *      else if (p2 < 0)
                                 *      { p = p1; }
                                 *      else
                                 *      { p = Math.Min(p1, p2); }
                                 *
                                 *      if (p > 0)
                                 *      {
                                 *          br += star2.exitance;// / (p * p));
                                 *      }
                                 *  }
                                 * }
                                 */
                                #endregion
                            }
                        }

                        #region NORMAL ILLUMINATION

                        /*
                         * {
                         *  Geometry.Sphere star2;
                         *  double t2 = FindIntersection(stars, star, star.origin, normal, out star2);
                         *  if (star2 != null)
                         *  { br += star2.exitance / (t2 * t2); }
                         * }
                         */
                        #endregion

                        #region REFLECTION

                        /*
                         * {
                         *  var reflection = new Geometry.Vector(normal);
                         *  reflection.Multiply(2 * -Geometry.DotProduct(ray.vector, normal));
                         *  reflection.Add(ray.vector);
                         *
                         *  RendererHelper.StarMoved star2;
                         *  double t2 = FindIntersection(stars, star, hitPoint, reflection, out star2);
                         *  if (star2 != null)
                         *  { br += star2.exitance / (t2 * t2); }
                         * }
                         */
                        #endregion

                        #region REFRACTION

                        /*
                         * {
                         *  double c1 = -Geometry.DotProduct(ray.vector, normal);
                         *  double n = 1.3;
                         *  double c2 = Math.Sqrt(1 - n * n * (1 - c1 * c1));
                         *  var V = new Geometry.Vector(ray.vector);
                         *  V.Multiply(n);
                         *  var refraction = new Geometry.Vector(normal);
                         *  refraction.Multiply(n * c1 - c2);
                         *  refraction.Add(V);
                         *
                         *  Star star2;
                         *  double t2 = FindIntersection(stars, star, hitPoint, refraction, out star2);
                         *  if (star2 != null)
                         *  { br += star2.exitance / (t2 * t2); }
                         * }
                         */
                        #endregion

                        dists[xx, yy].brightness = br;
                        brightness += br;
                    }
                }
            }

            flux[fluxIndex] = brightness / (zoom * zoom);
        }