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); } }); }
private void rendererComboBox_SelectedIndexChanged(object sender, EventArgs e) { renderer = renderers[rendererComboBox.SelectedIndex]; List <RendererHelper.StarMoved> stars = RendererHelper.GetAngledStars(root, currentTime, Extensions.DegToRad(trackBar2.Value)); DistPoint[,] tmpDists = LockDists(); renderer.Render(stars, tmpDists, flux, currentTime * currentTimeFactor); SetDists(tmpDists); pictureBox2.Invalidate(); }
private void trackBar1_Scroll(object sender, EventArgs e) { angleLabel.Text = trackBar2.Value.ToString() + "°"; currentTime = trackBar1.Value; root.PlaceInTime(currentTime); List <RendererHelper.StarMoved> stars = RendererHelper.GetAngledStars(root, currentTime, Extensions.DegToRad(trackBar2.Value)); DistPoint[,] tmpDists = LockDists(); renderer.Render(stars, tmpDists, flux, currentTime * currentTimeFactor); SetDists(tmpDists); pictureBox1.Invalidate(); pictureBox2.Invalidate(); pictureBox3.Invalidate(); }
public static List <StarMoved> GetAngledStars(IPointObject obj, double angle) { var stars = new List <StarMoved>(); double sin = Math.Sin(angle); double cos = Math.Cos(angle); foreach (Star origStar in RendererHelper.GetStars(obj)) { var star = new StarMoved( radius: origStar.radius, exitance: origStar.exitance, x: origStar.center.x, y: origStar.center.y * cos - origStar.center.z * sin, z: -origStar.center.y * sin - origStar.center.z * cos ); stars.Add(star); } return(stars); }
private Bitmap MakeRenderBitmap() { Color[] palette = new Color[256]; for (int i = 0; i < palette.Length; i++) { palette[i] = Color.FromArgb(i, i, i); } double max = double.NegativeInfinity; foreach (var star in RendererHelper.GetStars(root)) { if (star.exitance > max) { max = star.exitance; } } DistPoint[,] tmpDists = LockDists(); max /= 9; Bitmap bmp = new Bitmap(pictureBox2.Width, pictureBox2.Height); for (int yy = 0; yy < pictureBox2.Height; yy++) { for (int xx = 0; xx < pictureBox2.Width; xx++) { double br = tmpDists[xx, yy].brightness / max; int color = (int)(Math.Log10(1 + br) * 250); if (color > 255) { color = 255; } bmp.SetPixel(xx, yy, palette[color]); } } return(bmp); }
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); }
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); }
private void pictureBox1_Paint(object sender, PaintEventArgs e) { Graphics g = e.Graphics; g.FillRectangle(Brushes.Black, new Rectangle(new Point(0, 0), pictureBox1.Size)); // +++ HACK //Bitmap bmp = MakeRenderBitmap(); //g.DrawImage(bmp, (pictureBox1.Width - bmp.Width) / 2, 0); //double minFlux = double.PositiveInfinity; //double maxFlux = double.NegativeInfinity; //for (int i = 0; i < flux.Length; i++) //{ // if (flux[i] < minFlux) // { minFlux = flux[i]; } // if (flux[i] > maxFlux) // { maxFlux = flux[i]; } //} //g.DrawString("© Václav Přibík", DefaultFont, Brushes.DarkOrange, new PointF(510, 480)); //if (double.IsInfinity(minFlux) || (minFlux >= maxFlux)) //{ return; } //// CzeV343 ////minFlux = 0.0000000000000081410896090826384; ////maxFlux = 0.00000000000001076468493898098; //// Zasche //minFlux = 1.986293394705849; //maxFlux = 2.1336499894654914; //int maxWidth = pictureBox1.Width; //int maxHeight = 200; //int yOffs = bmp.Height; //for (int i = 0; i < flux.Length; i++) //{ mags[i] = -2.5 * Math.Log10(flux[i] / maxFlux); } //double minMag = -2.5 * Math.Log10(minFlux / maxFlux); //int logStep = (int)Math.Ceiling(Math.Log10(minMag)) - 1; //double magStepFactor = Math.Pow(10, logStep); //int minX = int.MinValue; //for (int i = 0; i < flux.Length; i++) //{ // int x = i * maxWidth / flux.Length; // double mag = mags[i]; // if ((flux[i] > int.MinValue) && !double.IsNaN(mag) && !double.IsInfinity(mag)) // { // int y = yOffs + (int)(mag * (maxHeight - 20) / minMag + 10); // g.FillRectangle(Brushes.Yellow, x, y, 2, 2); // if ((minX == int.MinValue) && (mags[i] == minMag)) // { minX = x; } // } //} //return; // --- HACK double w, h; RendererHelper.GetBoundingBoxTop(root, out w, out h); float max = (float)Math.Max(w, h); float zoom = pictureBox1.Width * 1f / max; PaintPoint(g, zoom, pictureBox1.Width / 2, root); }