static public object DoesGoTrCirc(CartesianCoordinates pos_LED, CartesianCoordinates finPoint, GeometricalObject ballStruct) { double R = ballStruct.radius; var P1 = new { x = pos_LED.x, y = pos_LED.y, z = pos_LED.z }; var P2 = new { x = finPoint.x, y = finPoint.y, z = finPoint.z }; var P3 = new { x = ballStruct.x, y = ballStruct.y, z = ballStruct.z }; double a = Math.Pow(P2.x - P1.x, 2) + Math.Pow(P2.y - P1.y, 2) + Math.Pow(P2.z - P1.z, 2); double b = 2 * ((P2.x - P1.x) * (P1.x - P3.x) + (P2.y - P1.y) * (P1.y - P3.y) + (P2.z - P1.z) * (P1.z - P3.z)); double c = P3.x * P3.x + P3.y * P3.y + P3.z * P3.z + P1.x * P1.x + P1.y * P1.y + P1.z * P1.z - 2 * (P3.x * P1.x + P3.y * P1.y + P3.z * P1.z) - R * R; double t = P1.z / (P1.z - P2.z); double x1 = P1.x + (P2.x - P1.x) * t; double y1 = P1.y + (P2.y - P1.y) * t; double[] Po1 = new double[] { x1, y1, 0 }; if (Math.Sqrt(x1 * x1 + y1 * y1) <= R * R) { return(new { x = Po1[0], y = Po1[1], z = Po1[2] }); } else { return(new { x = 0, y = 0, z = -1 }); } }
static public CartesianCoordinates SubtractVectors(CartesianCoordinates vector1, CartesianCoordinates vector2) { vector1.x -= vector2.x; vector1.y -= vector2.y; vector1.z -= vector2.z; return(vector1); }
static public CartesianCoordinates AddVectors(CartesianCoordinates vector1, CartesianCoordinates vector2) { vector1.x += vector2.x; vector1.y += vector2.y; vector1.z += vector2.z; return(vector1); }
public GeometricalObject(CartesianCoordinates cartPoint, SphericalCoordinates spherPoint, double radius, double side) { this.x = cartPoint.x; this.y = cartPoint.y; this.z = cartPoint.z; this.r = spherPoint.r; this.tetha = spherPoint.tetha; this.phi = spherPoint.phi; this.radius = radius; this.side = side; }
static public object DoesHitBall(CartesianCoordinates pos_LED, CartesianCoordinates finPoint, GeometricalObject ballStruct) { double R = ballStruct.radius; var P1 = new { x = pos_LED.x, y = pos_LED.y, z = pos_LED.z }; var P2 = new { x = finPoint.x, y = finPoint.y, z = finPoint.z }; var P3 = new { x = ballStruct.x, y = ballStruct.y, z = ballStruct.z }; double a = Math.Pow(P2.x - P1.x, 2) + Math.Pow(P2.y - P1.y, 2) + Math.Pow(P2.z - P1.z, 2); double b = 2 * ((P2.x - P1.x) * (P1.x - P3.x) + (P2.y - P1.y) * (P1.y - P3.y) + (P2.z - P1.z) * (P1.z - P3.z)); double c = P3.x * P3.x + P3.y * P3.y + P3.z * P3.z + P1.x * P1.x + P1.y * P1.y + P1.z * P1.z - 2 * (P3.x * P1.x + P3.y * P1.y + P3.z * P1.z) - R * R; double delta = b * b - 4 * a * c; double[] odp = new double[] { 0, 0, 0 }; if (delta >= 0) { double t1 = (-b - Math.Sqrt(delta)) / (2 * a); double t2 = (-b + Math.Sqrt(delta)) / (2 * a); double x1 = P1.x + (P2.x - P1.x) * t1; double y1 = P1.y + (P2.y - P1.y) * t1; double z1 = P1.z + (P2.z - P1.z) * t1; double x2 = P1.x + (P2.x - P1.x) * t2; double y2 = P1.y + (P2.y - P1.y) * t2; double z2 = P1.z + (P2.z - P1.z) * t2; double[] Po1 = new double[] { x1, y1, z1 }; double[] Po2 = new double[] { x2, y2, z2 }; if (z2 < z1) { Po2.CopyTo(odp, 0); } else { Po1.CopyTo(odp, 0); } } else { odp = new double[] { 0, 0, -1 }; } return(new { x = odp[0], y = odp[1], z = odp[2] }); }
static public SphericalCoordinates Cart2Sphere(CartesianCoordinates kart) { double r = Math.Sqrt(kart.x * kart.x + kart.y * kart.y + kart.z * kart.z); double tetha = (Math.Acos(kart.z / r) * 180 / Math.PI); double phi = 0.0; if (kart.x > 0 && kart.y > 0) { phi = (Math.Atan(kart.y / kart.x) * 180 / Math.PI); } else if (kart.x < 0 && kart.y > 0) { phi = (90 + Math.Atan(kart.y / kart.x) * 180 / Math.PI) + 90; } else if (kart.x < 0 && kart.y < 0) { phi = (Math.Atan(kart.y / kart.x) * 180 / Math.PI) + 180; } else { phi = (90 + Math.Atan(kart.y / kart.x) * 180 / Math.PI) + 270; } if (kart.x > 0 && kart.y == 0) { phi = 0; } else if (kart.x == 0 && kart.y > 0) { phi = 90; } else if (kart.x < 0 && kart.y == 0) { phi = 180; } else if (kart.x == 0 && kart.y < 0) { phi = 270; } else if (kart.x == 0 && kart.y == 0) { phi = 0; } return(new SphericalCoordinates(r: r, tetha: tetha, phi: phi)); }
public static CartesianCoordinates PointRotation(CartesianCoordinates cartPoint, SphericalCoordinates spherPoint) { double tetha = spherPoint.tetha; double phi = spherPoint.phi; double[,] RotZ = new double[, ] { { Math.Cos(phi * Math.PI / 180), -Math.Sin(phi * Math.PI / 180), 0 }, { Math.Sin(phi * Math.PI / 180), Math.Cos(phi * Math.PI / 180), 0 }, { 0, 0, 1 } }; double[,] RotY = new double[, ] { { Math.Cos(tetha * Math.PI / 180), 0, Math.Sin(tetha * Math.PI / 180) }, { 0, 1, 0 }, { -Math.Sin(tetha * Math.PI / 180), 0, Math.Cos(tetha * Math.PI / 180) } }; double[] point2Rotate = new double[] { cartPoint.x, cartPoint.y, cartPoint.z }; point2Rotate = MatrixProduct(RotY, point2Rotate); point2Rotate = MatrixProduct(RotZ, point2Rotate); return(new CartesianCoordinates(x: point2Rotate[0], y: point2Rotate[1], z: point2Rotate[2])); }
static public double DistanceFind(CartesianCoordinates point1, CartesianCoordinates point2) { CartesianCoordinates tempPoint = SubtractVectors(point1, point2); return(Math.Sqrt(tempPoint.x * tempPoint.x + tempPoint.y * tempPoint.y + tempPoint.z * tempPoint.z)); }
public void GreatLoop(object param) { var _SimulationParameters = Cast(param, new { Ax = 0.0, Ay = 0.0, Az = 0.0, Ar = 0.0 }); double xcObst = _SimulationParameters.Ax; double ycObst = _SimulationParameters.Ay; double zcObst = _SimulationParameters.Az; double rcObst = _SimulationParameters.Ar; CartesianCoordinates ballC = new CartesianCoordinates(x: xcObst, y: ycObst, z: zcObst); ballStruct = new GeometricalObject(cartPoint: ballC, spherPoint: Elementary.Cart2Sphere(ballC), radius: rcObst, side: 0); Random localRandom = new Random(Form1.GLOBAL_RANDOM_VAR.Next() & DateTime.Now.Millisecond); double[,] pixelHITtemp = new double[NUM_PIXELS_SIDE, NUM_PIXELS_SIDE]; double[,] siatkaHITTemp = new double[NUM_PIXELS_SIDE, NUM_PIXELS_SIDE]; GeometricalObject tempLED = null; CartesianCoordinates posLED = new CartesianCoordinates(x: 0, y: 0, z: 0); double[] Lsa = new double[LEDStruct.Length]; for (int iled = 0; iled < LEDStruct.Length; iled++) { tempLED = LEDStruct[iled]; posLED = new CartesianCoordinates(x: LEDStruct[iled].x, y: LEDStruct[iled].y, z: LEDStruct[iled].z); Lsa[iled] = Elementary.DistanceFind(posLED, new CartesianCoordinates(x: ballStruct.x, y: ballStruct.y, z: ballStruct.z)); } // angle of the most wide beam from a LED double alfaSA = Math.Asin(ballStruct.radius / Lsa.Min()) * 180.0 / Math.PI; // angle of the most wide beam to the pinhole dynamic BallHitPointT = Elementary.DoesHitBall(new CartesianCoordinates(x: 0, y: 0, z: 0), new CartesianCoordinates(x: ballStruct.x, y: ballStruct.y, z: ballStruct.z), ballStruct); double Lphc = Elementary.DistanceFind(new CartesianCoordinates(x: BallHitPointT.x, y: BallHitPointT.y, z: BallHitPointT.z), new CartesianCoordinates(x: 0, y: 0, z: 0)); double alfaPH = Math.Atan(pinholeStuct.radius / Lphc) * 180.0 / Math.PI; for (int iPhoton = 1; iPhoton <= PHOTONS_PER_LED; iPhoton++) { for (int iled = 0; iled < LEDStruct.Length; iled++) { tempLED = LEDStruct[iled]; posLED = new CartesianCoordinates(x: LEDStruct[iled].x, y: LEDStruct[iled].y, z: LEDStruct[iled].z); double _tetha = localRandom.NextDouble() * alfaSA; double _phi = localRandom.NextDouble() * 360.0; double _r = 100.0; CartesianCoordinates photonEndPoint = Elementary.Sphere2Kart(new SphericalCoordinates(r: _r, tetha: _tetha, phi: _phi)); newOriginCart = new CartesianCoordinates(x: ballStruct.x - tempLED.x, y: ballStruct.y - tempLED.y, z: ballStruct.z - tempLED.z); newOriginSpher = Elementary.Cart2Sphere(newOriginCart); photonEndPoint = Elementary.PointRotation(photonEndPoint, newOriginSpher); photonEndPoint = Elementary.AddVectors(photonEndPoint, posLED); dynamic BallHitPoint = Elementary.DoesHitBall(posLED, photonEndPoint, ballStruct); double Llh = Elementary.DistanceFind(new CartesianCoordinates(x: BallHitPoint.x, y: BallHitPoint.y, z: BallHitPoint.z), posLED); double alfa_p = Math.Acos(BallHitPoint.z / Llh) * 180.0 / Math.PI; angleEff[0] = Math.Cos(alfa_p * Math.PI / 180.0); if (BallHitPoint.z != -1) { L1 = Elementary.DistanceFind(new CartesianCoordinates(x: BallHitPoint.x, y: BallHitPoint.y, z: BallHitPoint.z), posLED); double Lc = Elementary.DistanceFind(new CartesianCoordinates(x: ballStruct.x, y: ballStruct.y, z: ballStruct.z), posLED); alfa_p = Math.Acos((L1 * L1 + ballStruct.radius * ballStruct.radius - Lc * Lc) / (2 * ballStruct.radius * L1)) * 180 / Math.PI; angleEff[1] = Math.Cos((180.0 - alfa_p) * Math.PI / 180.0); if (Double.IsNaN(angleEff[1])) { //System.Console.Write("traingle error"); angleEff[1] = 0.0; // BUG : triangle sides a+b<c } for (int ipFot = 0; ipFot < SECONDARY_EMISSION_PHOTONS; ipFot++) { //sampling the end position of new emitting photon _tetha = 180.0 + localRandom.NextDouble() * alfaPH; _phi = localRandom.NextDouble() * 360.0; _r = 100.0; CartesianCoordinates photonEndPointFinal = Elementary.Sphere2Kart(new SphericalCoordinates(r: _r, tetha: _tetha, phi: _phi)); newOriginCart = new CartesianCoordinates(x: BallHitPoint.x, y: BallHitPoint.y, z: BallHitPoint.z); newOriginSpher = Elementary.Cart2Sphere(newOriginCart); double[] wek = new double[] { 0, 0 }; // rotation with respect to hitBall point photonEndPointFinal = Elementary.PointRotation(photonEndPointFinal, newOriginSpher); // translation Elementary.AddVectors(photonEndPointFinal, new CartesianCoordinates(x: BallHitPoint.x, y: BallHitPoint.y, z: BallHitPoint.z)); // secondary emission angle double Lh = Elementary.DistanceFind(new CartesianCoordinates(x: BallHitPoint.x, y: BallHitPoint.y, z: BallHitPoint.z), photonEndPointFinal); Lc = Elementary.DistanceFind(photonEndPointFinal, new CartesianCoordinates(x: ballStruct.x, y: ballStruct.y, z: ballStruct.z)); alfa_p = Math.Acos((Lh * Lh + ballStruct.radius * ballStruct.radius - Lc * Lc) / (2 * ballStruct.radius * Lh)) * 180 / Math.PI; angleEff[2] = Math.Cos((180.0 - alfa_p) * Math.PI / 180.0); dynamic CircHitPoint = Elementary.DoesGoTrCirc(new CartesianCoordinates(x: BallHitPoint.x, y: BallHitPoint.y, z: BallHitPoint.z), photonEndPointFinal, ballStructh); if (CircHitPoint.z != -1) //Photon goes trhough pinhole { double z0 = QPStruct.z; double x2 = photonEndPointFinal.x; double y2 = photonEndPointFinal.y; double z2 = photonEndPointFinal.z; double x1 = BallHitPoint.x; double y1 = BallHitPoint.y; double z1 = BallHitPoint.z; // parametric form solution double t = (z0 - z1) / (z2 - z1); double x = x1 + (x2 - x1) * t; double y = y1 + (y2 - y1) * t; double z = z1 + (z2 - z1) * t; L2 = Elementary.DistanceFind(new CartesianCoordinates(x: BallHitPoint.x, y: BallHitPoint.y, z: BallHitPoint.z), new CartesianCoordinates(x: x, y: y, z: z)); SphericalCoordinates hitParams = Elementary.Cart2Sphere(new CartesianCoordinates(x: x1 - x, y: y1 - y, z: z1 - z)); angleEff[3] = Math.Cos(hitParams.tetha * Math.PI / 180); double I0 = 1; double Ifin = (I0 * angleEff[0] / (L1 * L1)) * angleEff[1] * angleEff[2] * angleEff[3] / (L2 * L2); if (Double.IsNaN(Ifin)) { Ifin = 0; } int posx = 0, posy = 0; if (x > 0) { posx = Convert.ToInt16(Math.Floor(x / resolution) + sideLength / resolution / 2); } else { posx = Convert.ToInt16(Math.Ceiling(x / resolution) + sideLength / resolution / 2) - 1; } if (y > 0) { posy = Convert.ToInt16(Math.Floor(y / resolution) + sideLength / resolution / 2); } else { posy = Convert.ToInt16(Math.Ceiling(y / resolution) + sideLength / resolution / 2) - 1; } if (posx < Math.Floor(sideLength / resolution) && posy < Math.Floor(sideLength / resolution) && posx >= 0 && posy >= 0) { pixelHITtemp[posx, posy] = pixelHITtemp[posx, posy] + Ifin; siatkaHITTemp[posx, posy] = siatkaHITTemp[posx, posy] + 1; } } } } } if (iPhoton % REFRESH_STEP == 0 && iPhoton > 0) { refrcnt++; updateHitMesh(pixelHITtemp); if (refrcnt % NUM_THREADS == 0) { progressBar1.Invoke(new Action(delegate() { double temppr = (double)(1.0 / NUM_THREADS) * refrcnt * STEPPERCENT; temppr = temppr > 99.0 ? 100.0 : temppr; lProgress.Text = String.Format("Progress: {0:0}%", temppr); labelPerc.Text = String.Format("Progress: {0:0}%", temppr); progressBar1.Value = (int)temppr; })); lock (GLOBAL_RANDOM_VAR) { previewImage = CreateImage(pixelHIT); } //automatically copy the resulting Image to clipboard after the simulation is performed pictureBox1.BeginInvoke(new Action(delegate() { pictureBox1.Image = previewImage; pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage; Clipboard.SetImage(previewImage); try { //pictureBox1.Image.Save(imgPath + imc2 + ".png", ImageFormat.Png); using (MemoryStream memory = new MemoryStream()) { using (FileStream fs = new FileStream(imgPath + imc2 + ".png", FileMode.Create, FileAccess.ReadWrite)) { pictureBox1.Image.Save(memory, ImageFormat.Png); byte[] bytes = memory.ToArray(); fs.Write(bytes, 0, bytes.Length); } } BitmapSource bSource = new BitmapImage(new Uri(imgPath + imc2 + ".png")); encoder.Frames.Add(BitmapFrame.Create(bSource)); imc2++; } catch (Exception eb2) { System.Console.WriteLine(eb2.Message); } })); } //update the time elapsed label lTimeElapsed.BeginInvoke(new Action(delegate() { lTimeElapsed.Text = String.Format("Time: {0:00}:{1:00}:{2:00}.{3:00}", sw.Elapsed.Hours, sw.Elapsed.Minutes, sw.Elapsed.Seconds, sw.Elapsed.Milliseconds / 10); })); } } updateHitMesh(pixelHITtemp); }
private async void bStart_Click(object sender, EventArgs e) { encoder = new GifBitmapEncoder(); FileStream stream = null; try { stream = new FileStream(tbFileName.Text + ".gif", FileMode.Create); } catch (Exception eb) { System.Console.WriteLine(eb.Message); } imc2 = 0; InitializeSimulationProperties(); InitializeEnvironment(); //alert - ball too close if (Convert.ToDouble(nudZs.Value) <= ballStruct.radius) { MessageBox.Show("The ball is too close to the pinhole surface (z<=R)!" + " Change one of the values to start the simulation.", "Attention!", MessageBoxButtons.OK, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button1); } else { progressBar1.Value = 0; PHOTONSqueue.Clear(); ERRORqueue.Clear(); chartError.ChartAreas[0].AxisX.IsLogarithmic = false; chartError.Series[0].Points.Clear(); chartLOC.Series[0].Points.Clear(); gbLEDs.Enabled = false; gbSE.Enabled = false; gbSP.Enabled = false; sw = new Stopwatch(); sw.Start(); bStart.Enabled = false; //---------------------------------------------------------------------- SLDocument sl = new SLDocument(); sl.RenameWorksheet(SLDocument.DefaultFirstSheetName, "Settings"); sl.AddWorksheet("Res1"); Random r0 = new Random(Form1.GLOBAL_RANDOM_VAR.Next() & DateTime.Now.Millisecond); double xstart = Convert.ToDouble(nudXs.Value); double xstep = Convert.ToDouble(nudXst.Value); double xfinni = Convert.ToDouble(nudXsp.Value); double ystart = Convert.ToDouble(nudYs.Value); double ystep = Convert.ToDouble(nudYst.Value); double yfinni = Convert.ToDouble(nudYsp.Value); double zstart = Convert.ToDouble(nudZs.Value); double zstep = Convert.ToDouble(nudZst.Value); double zfinni = Convert.ToDouble(nudZsp.Value); int imc = 0; for (int phRad = 1; phRad <= 35; phRad++) { for (int zc = 0; zc <= (zfinni - zstart) / zstep; zc++) { for (int yc = 0; yc <= (yfinni - ystart) / ystep; yc++) { for (int xc = 0; xc <= (xfinni - xstart) / xstep; xc++) { CartesianCoordinates pinholeCoordinates = new CartesianCoordinates(x: 0, y: 0, z: 0); pinholeStuct = new GeometricalObject(pinholeCoordinates, Elementary.Cart2Sphere(pinholeCoordinates), radius: phRad * 0.01, side: 0); CartesianCoordinates ballCh = new CartesianCoordinates(x: 0, y: 0, z: 0); ballStructh = new GeometricalObject(ballCh, Elementary.Cart2Sphere(ballCh), radius: pinholeStuct.radius, side: 0); labelCP.Invoke(new Action(delegate() { labelCP.Text = String.Format("({0:0.00}, {1:0.00}, {2:0.00})", xstart + (xstep * xc), ystart + (ystep * yc), zstart + (zstep * zc)); })); imc++; // update the position of the ball var _inputParameters = new { Ax = -xstart - (xstep * xc), Ay = -ystart - (ystep * yc), Az = zstart + (zstep * zc), Ar = ballStruct.radius }; await Task.Run(() => { Thread[] threadsArray = new Thread[NUM_THREADS]; for (int threadIterator = 0; threadIterator < NUM_THREADS; threadIterator++) { threadsArray[threadIterator] = new Thread(GreatLoop); threadsArray[threadIterator].Priority = ThreadPriority.Highest; threadsArray[threadIterator].Start(_inputParameters); } foreach (Thread t in threadsArray) { t.Join(); } }); refrcnt = 0; double qpA = pixelHIT[NUM_PIXELS_SIDE / 2 - 1, NUM_PIXELS_SIDE / 2]; double qpB = pixelHIT[NUM_PIXELS_SIDE / 2, NUM_PIXELS_SIDE / 2]; double qpC = pixelHIT[NUM_PIXELS_SIDE / 2, NUM_PIXELS_SIDE / 2 - 1]; double qpD = pixelHIT[NUM_PIXELS_SIDE / 2 - 1, NUM_PIXELS_SIDE / 2 - 1]; double tmpX = (qpA + qpD - qpB - qpC) / (qpA + qpB + qpC + qpD); double tmpY = (qpA + qpB - qpC - qpD) / (qpA + qpB + qpC + qpD); chartLOC.Series[0].Points.AddXY(tmpX, tmpY); sl.AddWorksheet(String.Format("Res{0}", imc)); for (int w = 0; w < NUM_PIXELS_SIDE; w++) { for (int k = 0; k < NUM_PIXELS_SIDE; k++) { try { double tmp1 = pixelHIT[w, k]; sl.SetCellValue(w + 1, k + 1, tmp1); } catch (Exception erorWrite) { System.Console.WriteLine(erorWrite.Message); } } } Array.Clear(pixelHIT, 0, NUM_PIXELS_SIDE * NUM_PIXELS_SIDE); } sw.Stop(); System.Console.WriteLine("Time: " + sw.Elapsed); } } } sl.SaveAs((tbFileName.Text.Length > 0 ? tbFileName.Text : "test") + ".xlsx"); try { InitializeGifParams(imc2 - 1); encoder.Save(stream); } catch (Exception e3) { System.Console.WriteLine(e3.Message); } bStart.Enabled = true; gbLEDs.Enabled = true; gbSE.Enabled = true; gbSP.Enabled = true; } }
public void InitializeEnvironment() { NUM_PIXELS_SIDE = Convert.ToInt16(sideLength / resolution); pixelHIT = new double[NUM_PIXELS_SIDE, NUM_PIXELS_SIDE]; siatkaHIT = new double[NUM_PIXELS_SIDE, NUM_PIXELS_SIDE]; _1Dprevimage = new double[NUM_PIXELS_SIDE * NUM_PIXELS_SIDE]; double ballRad = Convert.ToDouble(nudPSEbr.Value) * 0.1; //create ball CartesianCoordinates ballCoordinates = new CartesianCoordinates(x: 0, y: 0, z: 3); ballStruct = new GeometricalObject(ballCoordinates, Elementary.Cart2Sphere(ballCoordinates), radius: ballRad, side: 0); double phRad = Convert.ToDouble(nudPSEphr.Value) * 0.1; //create pinhole CartesianCoordinates pinholeCoordinates = new CartesianCoordinates(x: 0, y: 0, z: 0); pinholeStuct = new GeometricalObject(pinholeCoordinates, Elementary.Cart2Sphere(pinholeCoordinates), radius: phRad, side: 0); //create LEDs if (rbCircle.Checked) { int numLEDS = Convert.ToInt16(nudPCnl.Value); double r_dist = Convert.ToDouble(nudPCr.Value) * 0.1; LEDStruct = new GeometricalObject[numLEDS]; for (int ledsIterator = 0; ledsIterator < numLEDS; ledsIterator++) { SphericalCoordinates sphericalTemp = new SphericalCoordinates(r: r_dist, tetha: 90.0, phi: 360 * ledsIterator / numLEDS); LEDStruct[ledsIterator] = new GeometricalObject(Elementary.Sphere2Kart(sphericalTemp), sphericalTemp, 0, 0); } } else if (rbGrid.Checked) { int cols = Convert.ToInt16(nudPGc.Value); int rows = Convert.ToInt16(nudPGr.Value); double spacing = Convert.ToInt16(nudPGs.Value) * 0.1; int numLEDS = cols * rows; LEDStruct = new GeometricalObject[numLEDS]; int helpIter = 0; for (int colit = 0; colit < cols; colit++) { for (int rowit = 0; rowit < rows; rowit++) { CartesianCoordinates tempC = new CartesianCoordinates(x: spacing * ((cols + 1) / 2.0 - colit) - spacing, y: spacing * ((rows + 1) / 2.0 - rowit) - spacing, z: 0.0); LEDStruct[helpIter++] = new GeometricalObject(tempC, Elementary.Cart2Sphere(tempC), radius: 0.0, side: 0.0); } } } //create ball helper CartesianCoordinates ballCh = new CartesianCoordinates(x: 0, y: 0, z: 0); ballStructh = new GeometricalObject(ballCh, Elementary.Cart2Sphere(ballCh), radius: pinholeStuct.radius, side: 0); double imagePlaneDist = -Convert.ToDouble(nudPSEip.Value) * 0.1; double quadSide = Convert.ToDouble(nudPSEqps.Value) * 0.1; //create quad photodiode CartesianCoordinates qpC = new CartesianCoordinates(x: 0, y: 0, z: imagePlaneDist); QPStruct = new GeometricalObject(qpC, Elementary.Cart2Sphere(qpC), 0, quadSide); REFRESH_STEP = STEPPERCENT * PHOTONS_PER_LED / 100; }