public override bool shoot(Hare.Geometry.Ray R, out double u, out double v, out int Poly_ID, out List <Hare.Geometry.Point> X_PT, out List <double> t, out List <int> code) { /////////////////////// //double L2 = (R.direction.x * R.direction.x + R.direction.y * R.direction.y + R.direction.z *R.direction.z); //if (L2 > 1.05 || L2 < 0.95) //{ // Rhino.RhinoApp.Write("Vectors have lost normalization..."); //} /////////////////////// //R.direction.Normalize(); /////////////////////// Hare.Geometry.X_Event X = new Hare.Geometry.X_Event(); if (SP.Shoot(R, 0, out X)) { Poly_ID = X.Poly_id; X_Event_NH XNH = X as X_Event_NH; if (XNH != null) { X_PT = XNH.P_Points; t = XNH.t_trav; code = XNH.SPCode; } else { X_PT = new List <Hare.Geometry.Point> { X.X_Point }; t = new List <double> { X.t }; code = new List <int> { 0 }; } u = 0; v = 0; return(true); } Poly_ID = 0; X_PT = new List <Hare.Geometry.Point>(); //Rhino.RhinoDoc.ActiveDoc.Objects.Add(new Rhino.Geometry.LineCurve(Utilities.PachTools.HPttoRPt(R.origin), Utilities.PachTools.HPttoRPt(R.origin + R.direction))); t = new List <double>(); u = 0; v = 0; code = new List <int>() { 0 }; return(false); }
/// <summary> /// Fire a ray into the model. /// </summary> /// <param name="R"> The ray to be entered. Make certain the Ray has a unique Ray_ID variable. </param> /// <param name="top_index"> Indicates the topology the ray is to intersect. </param> /// <param name="Ret_Event"> The nearest resulting intersection information, if any. </param> /// <returns> Indicates whether or not an intersection was found. </returns> public override bool Shoot(Ray R, int top_index, out X_Event Ret_Event)//, On3dPoint EndPt, int Octave_in) { int X, Y, Z; //////////////////////// double VPrev = 0; //////////////////////// //Identify whether the Origin is inside the voxel grid... //Identify which voxel the Origin point is located in... X = (int)Math.Floor((R.origin.x - OBox.Min_PT.x) / VoxelDims.x); Y = (int)Math.Floor((R.origin.y - OBox.Min_PT.y) / VoxelDims.y); Z = (int)Math.Floor((R.origin.z - OBox.Min_PT.z) / VoxelDims.z); double tDeltaX, tDeltaY, tDeltaZ; double tMaxX = 0, tMaxY = 0, tMaxZ = 0; int stepX, stepY, stepZ, OutX, OutY, OutZ; double t_start = 0; if (X < 0 || X >= VoxelCtX || Y < 0 || Y >= VoxelCtY || Z < 0 || Z >= VoxelCtZ) //return false; { if (!OBox.Intersect(R, ref t_start, ref R.origin)) { Ret_Event = new X_Event(); return(false); } X = (int)Math.Floor((R.origin.x - OBox.Min_PT.x + R.direction.x) / VoxelDims.x); Y = (int)Math.Floor((R.origin.y - OBox.Min_PT.y + R.direction.y) / VoxelDims.y); Z = (int)Math.Floor((R.origin.z - OBox.Min_PT.z + R.direction.z) / VoxelDims.z); } if (R.direction.x < 0) { OutX = -1; stepX = -1; tMaxX = (float)((Voxels[X, Y, Z].Min_PT.x - R.origin.x) / R.direction.x); tDeltaX = (float)(VoxelDims.x / R.direction.x * stepX); } else { OutX = VoxelCtX; stepX = 1; tMaxX = (float)((Voxels[X, Y, Z].Max_PT.x - R.origin.x) / R.direction.x); tDeltaX = (float)(VoxelDims.x / R.direction.x * stepX); } if (R.direction.y < 0) { OutY = -1; stepY = -1; tMaxY = (float)((Voxels[X, Y, Z].Min_PT.y - R.origin.y) / R.direction.y); tDeltaY = (float)(VoxelDims.y / R.direction.y * stepY); } else { OutY = VoxelCtY; stepY = 1; tMaxY = (float)((Voxels[X, Y, Z].Max_PT.y - R.origin.y) / R.direction.y); tDeltaY = (float)(VoxelDims.y / R.direction.y * stepY); } if (R.direction.z < 0) { OutZ = -1; stepZ = -1; tMaxZ = (float)((Voxels[X, Y, Z].Min_PT.z - R.origin.z) / R.direction.z); tDeltaZ = (float)(VoxelDims.z / R.direction.z * stepZ); } else { OutZ = VoxelCtZ; stepZ = 1; tMaxZ = (float)((Voxels[X, Y, Z].Max_PT.z - R.origin.z) / R.direction.z); tDeltaZ = (float)(VoxelDims.z / R.direction.z * stepZ); } List <double> t_list = new List <double>(); List <int> Codes = new List <int>(); List <Point> Path_pts = new List <Point>(); List <int> voxelCodes = new List <int>(); List <Point> X_LIST = new List <Point>(); List <double> ulist = new List <double>(); List <double> vlist = new List <double>(); List <double> tlist = new List <double>(); List <int> pidlist = new List <int>(); while (true) { //Check all polygons in the current voxel... foreach (int i in Voxel_Inv[X, Y, Z, top_index]) { if (Poly_Ray_ID[R.ThreadID, top_index][i] != R.Ray_ID) { Poly_Ray_ID[R.ThreadID, top_index][i] = R.Ray_ID; Point Pt; double u = 0, v = 0, t = 0; if (Model[top_index].intersect(i, R, out Pt, out u, out v, out t) && t > 0.0000000001) { X_LIST.Add(Pt); } ulist.Add(u); vlist.Add(v); tlist.Add(t); pidlist.Add(i); } } for (int c = 0; c < X_LIST.Count; c++) { if (this.Voxels[X, Y, Z].IsPointInBox(X_LIST[c])) { int choice = c; //Ret_Event = X_LIST[c]; for (int s = c; s < X_LIST.Count; s++) { if (tlist[s] < tlist[choice]) { choice = s; //Ret_Event = X_LIST[s]; } } Path_pts.Add(X_LIST[choice]); t_list.Add(tlist[choice]); Ret_Event = new X_Event_NH(Path_pts, ulist[choice], vlist[choice], t_list, pidlist[choice], Codes); //Ret_Event.t += t_start; return(true); } } ///////////////////////////////////////// VPrev = Velocities[X, Y, Z]; ///////////////////////////////////////// //Find the Next Voxel... ///////////////////////////////////////////////// if (tMaxX < tMaxY) { if (tMaxX < tMaxZ) { X += stepX; if (X < 0 || X >= VoxelCtX) { Ret_Event = new X_Event(); return(false); /* outside grid */ } tMaxX += tDeltaX; if (VPrev != Velocities[X, Y, Z]) { R.direction = XRefraction(R.direction, VPrev, Velocities[X, Y, Z]); if (R.direction.x < 0) { stepX = -1; } else { stepX = 1; } if (R.direction.y < 0) { stepY = -1; } else { stepY = 1; } if (R.direction.z < 0) { stepZ = -1; } else { stepZ = 1; } tDeltaX = (float)(VoxelDims.x / R.direction.x * stepX); tDeltaY = (float)(VoxelDims.y / R.direction.y * stepY); tDeltaZ = (float)(VoxelDims.z / R.direction.z * stepZ); t_list.Add(tDeltaX); Codes.Add(VoxelCode(X, Y, Z)); R.origin += R.direction * tDeltaX; Path_pts.Add(R.origin); X_LIST.Clear(); } } else { Z += stepZ; if (Z < 0 || Z >= VoxelCtZ) { Ret_Event = new X_Event(); return(false); /* outside grid */ } tMaxZ += tDeltaZ; if (VPrev != Velocities[X, Y, Z]) { R.direction = ZRefraction(R.direction, VPrev, Velocities[X, Y, Z]); if (R.direction.x < 0) { stepX = -1; } else { stepX = 1; } if (R.direction.y < 0) { stepY = -1; } else { stepY = 1; } if (R.direction.z < 0) { stepZ = -1; } else { stepZ = 1; } tDeltaX = (float)(VoxelDims.x / R.direction.x * stepX); tDeltaY = (float)(VoxelDims.y / R.direction.y * stepY); tDeltaZ = (float)(VoxelDims.z / R.direction.z * stepZ); t_list.Add(tDeltaZ); R.origin += R.direction * tDeltaZ; Path_pts.Add(R.origin); X_LIST.Clear(); } } } else { if (tMaxY < tMaxZ) { Y += stepY; if (Y < 0 || Y >= VoxelCtY) { Ret_Event = new X_Event(); return(false); /* outside grid */ } tMaxY += tDeltaY; if (VPrev != Velocities[X, Y, Z]) { R.direction = YRefraction(R.direction, VPrev, Velocities[X, Y, Z]); if (R.direction.x < 0) { stepX = -1; } else { stepX = 1; } if (R.direction.y < 0) { stepY = -1; } else { stepY = 1; } if (R.direction.z < 0) { stepZ = -1; } else { stepZ = 1; } tDeltaX = (float)(VoxelDims.x / R.direction.x * stepX); tDeltaY = (float)(VoxelDims.y / R.direction.y * stepY); tDeltaZ = (float)(VoxelDims.z / R.direction.z * stepZ); t_list.Add(tDeltaY); R.origin += R.direction * tDeltaY; Path_pts.Add(R.origin); X_LIST.Clear(); } } else { Z += stepZ; if (Z < 0 || Z >= VoxelCtZ) { Ret_Event = new X_Event(); return(false); /* outside grid */ } tMaxZ += tDeltaZ; if (VPrev != Velocities[X, Y, Z]) { R.direction = ZRefraction(R.direction, VPrev, Velocities[X, Y, Z]); if (R.direction.x < 0) { stepX = -1; } else { stepX = 1; } if (R.direction.y < 0) { stepY = -1; } else { stepY = 1; } if (R.direction.z < 0) { stepZ = -1; } else { stepZ = 1; } tDeltaX = (float)(VoxelDims.x / R.direction.x * stepX); tDeltaY = (float)(VoxelDims.y / R.direction.y * stepY); tDeltaZ = (float)(VoxelDims.z / R.direction.z * stepZ); t_list.Add(tDeltaZ); R.origin += R.direction * tDeltaZ; Path_pts.Add(R.origin); X_LIST.Clear(); } } } } }
/// <summary> /// Fire a ray into the model. /// </summary> /// <param name="R"> The ray to be entered. Make certain the Ray has a unique Ray_ID variable. </param> /// <param name="top_index"> Indicates the topology the ray is to intersect. </param> /// <param name="Ret_Event"> The nearest resulting intersection information, if any. </param> /// <returns> Indicates whether or not an intersection was found. </returns> public override bool Shoot(Ray R, int top_index, out X_Event Ret_Event)//, On3dPoint EndPt, int Octave_in) { int X, Y, Z; //////////////////////// double VPrev = 0; //////////////////////// //Identify whether the Origin is inside the voxel grid... //Identify which voxel the Origin point is located in... X = (int)Math.Floor((R.origin.x - OBox.Min_PT.x) / VoxelDims.x); Y = (int)Math.Floor((R.origin.y - OBox.Min_PT.y) / VoxelDims.y); Z = (int)Math.Floor((R.origin.z - OBox.Min_PT.z) / VoxelDims.z); double tDeltaX, tDeltaY, tDeltaZ; double tMaxX = 0, tMaxY = 0, tMaxZ = 0; int stepX, stepY, stepZ, OutX, OutY, OutZ; double t_start = 0; if (X < 0 || X >= VoxelCtX || Y < 0 || Y >= VoxelCtY || Z < 0 || Z >= VoxelCtZ) //return false; { if (!OBox.Intersect(R, ref t_start, ref R.origin)) { Ret_Event = new X_Event(); return false; } X = (int)Math.Floor((R.origin.x - OBox.Min_PT.x + R.direction.x) / VoxelDims.x); Y = (int)Math.Floor((R.origin.y - OBox.Min_PT.y + R.direction.y) / VoxelDims.y); Z = (int)Math.Floor((R.origin.z - OBox.Min_PT.z + R.direction.z) / VoxelDims.z); } if (R.direction.x < 0) { OutX = -1; stepX = -1; tMaxX = (float)((Voxels[X, Y, Z].Min_PT.x - R.origin.x) / R.direction.x); tDeltaX = (float)(VoxelDims.x / R.direction.x * stepX); } else { OutX = VoxelCtX; stepX = 1; tMaxX = (float)((Voxels[X, Y, Z].Max_PT.x - R.origin.x) / R.direction.x); tDeltaX = (float)(VoxelDims.x / R.direction.x * stepX); } if (R.direction.y < 0) { OutY = -1; stepY = -1; tMaxY = (float)((Voxels[X, Y, Z].Min_PT.y - R.origin.y) / R.direction.y); tDeltaY = (float)(VoxelDims.y / R.direction.y * stepY); } else { OutY = VoxelCtY; stepY = 1; tMaxY = (float)((Voxels[X, Y, Z].Max_PT.y - R.origin.y) / R.direction.y); tDeltaY = (float)(VoxelDims.y / R.direction.y * stepY); } if (R.direction.z < 0) { OutZ = -1; stepZ = -1; tMaxZ = (float)((Voxels[X, Y, Z].Min_PT.z - R.origin.z) / R.direction.z); tDeltaZ = (float)(VoxelDims.z / R.direction.z * stepZ); } else { OutZ = VoxelCtZ; stepZ = 1; tMaxZ = (float)((Voxels[X, Y, Z].Max_PT.z - R.origin.z) / R.direction.z); tDeltaZ = (float)(VoxelDims.z / R.direction.z * stepZ); } List<double> t_list = new List<double>(); List<int> Codes = new List<int>(); List<Point> Path_pts = new List<Point>(); List<int> voxelCodes = new List<int>(); List<Point> X_LIST = new List<Point>(); List<double> ulist = new List<double>(); List<double> vlist = new List<double>(); List<double> tlist = new List<double>(); List<int> pidlist = new List<int>(); while (true) { //Check all polygons in the current voxel... foreach (int i in Voxel_Inv[X, Y, Z, top_index]) { if (Poly_Ray_ID[R.ThreadID, top_index][i] != R.Ray_ID) { Poly_Ray_ID[R.ThreadID, top_index][i] = R.Ray_ID; Point Pt; double u=0, v=0, t=0; if (Model[top_index].intersect(i, R, out Pt, out u, out v, out t) && t > 0.0000000001) X_LIST.Add(Pt); ulist.Add(u); vlist.Add(v); tlist.Add(t); pidlist.Add(i); } } for (int c = 0; c < X_LIST.Count; c++) { if (this.Voxels[X, Y, Z].IsPointInBox(X_LIST[c])) { int choice = c; //Ret_Event = X_LIST[c]; for (int s = c; s < X_LIST.Count; s++) { if (tlist[s] < tlist[choice]) { choice = s; //Ret_Event = X_LIST[s]; } } Path_pts.Add(X_LIST[choice]); t_list.Add(tlist[choice]); Ret_Event = new X_Event_NH(Path_pts, ulist[choice], vlist[choice], t_list, pidlist[choice], Codes); //Ret_Event.t += t_start; return true; } } ///////////////////////////////////////// VPrev = Velocities[X, Y, Z]; ///////////////////////////////////////// //Find the Next Voxel... ///////////////////////////////////////////////// if (tMaxX < tMaxY) { if (tMaxX < tMaxZ) { X += stepX; if (X < 0 || X >= VoxelCtX) { Ret_Event = new X_Event(); return false; /* outside grid */ } tMaxX += tDeltaX; if (VPrev != Velocities[X, Y, Z]) { R.direction = XRefraction(R.direction, VPrev, Velocities[X, Y, Z]); if (R.direction.x < 0) { stepX = -1; } else { stepX = 1; } if (R.direction.y < 0) { stepY = -1; } else { stepY = 1; } if (R.direction.z < 0) { stepZ = -1; } else { stepZ = 1; } tDeltaX = (float)(VoxelDims.x / R.direction.x * stepX); tDeltaY = (float)(VoxelDims.y / R.direction.y * stepY); tDeltaZ = (float)(VoxelDims.z / R.direction.z * stepZ); t_list.Add(tDeltaX); Codes.Add(VoxelCode(X,Y,Z)); R.origin += R.direction * tDeltaX; Path_pts.Add(R.origin); X_LIST.Clear(); } } else { Z += stepZ; if (Z < 0 || Z >= VoxelCtZ) { Ret_Event = new X_Event(); return false; /* outside grid */ } tMaxZ += tDeltaZ; if (VPrev != Velocities[X, Y, Z]) { R.direction = ZRefraction(R.direction, VPrev, Velocities[X, Y, Z]); if (R.direction.x < 0) { stepX = -1; } else { stepX = 1; } if (R.direction.y < 0) { stepY = -1; } else { stepY = 1; } if (R.direction.z < 0) { stepZ = -1; } else { stepZ = 1; } tDeltaX = (float)(VoxelDims.x / R.direction.x * stepX); tDeltaY = (float)(VoxelDims.y / R.direction.y * stepY); tDeltaZ = (float)(VoxelDims.z / R.direction.z * stepZ); t_list.Add(tDeltaZ); R.origin += R.direction * tDeltaZ; Path_pts.Add(R.origin); X_LIST.Clear(); } } } else { if (tMaxY < tMaxZ) { Y += stepY; if (Y < 0 || Y >= VoxelCtY) { Ret_Event = new X_Event(); return false; /* outside grid */ } tMaxY += tDeltaY; if (VPrev != Velocities[X, Y, Z]) { R.direction = YRefraction(R.direction, VPrev, Velocities[X, Y, Z]); if (R.direction.x < 0) { stepX = -1; } else { stepX = 1; } if (R.direction.y < 0) { stepY = -1; } else { stepY = 1; } if (R.direction.z < 0) { stepZ = -1; } else { stepZ = 1; } tDeltaX = (float)(VoxelDims.x / R.direction.x * stepX); tDeltaY = (float)(VoxelDims.y / R.direction.y * stepY); tDeltaZ = (float)(VoxelDims.z / R.direction.z * stepZ); t_list.Add(tDeltaY); R.origin += R.direction * tDeltaY; Path_pts.Add(R.origin); X_LIST.Clear(); } } else { Z += stepZ; if (Z < 0 || Z >= VoxelCtZ) { Ret_Event = new X_Event(); return false; /* outside grid */ } tMaxZ += tDeltaZ; if (VPrev != Velocities[X, Y, Z]) { R.direction = ZRefraction(R.direction, VPrev, Velocities[X, Y, Z]); if (R.direction.x < 0) { stepX = -1; } else { stepX = 1; } if (R.direction.y < 0) { stepY = -1; } else { stepY = 1; } if (R.direction.z < 0) { stepZ = -1; } else { stepZ = 1; } tDeltaX = (float)(VoxelDims.x / R.direction.x * stepX); tDeltaY = (float)(VoxelDims.y / R.direction.y * stepY); tDeltaZ = (float)(VoxelDims.z / R.direction.z * stepZ); t_list.Add(tDeltaZ); R.origin += R.direction * tDeltaZ; Path_pts.Add(R.origin); X_LIST.Clear(); } } } } }