public override void EdgeFrame_Tangents(Hare.Geometry.Point Origin, Vector Normal, int[] PlaneIDs, ref List <double> dist2, List <Vector> Dir, List <int> EdgeIDs) { double d = Hare_math.Dot(Normal, Origin); //for (int i = 0; i < PlaneCount; i++) foreach (int i in EdgeIDs) { Hare.Geometry.Point[] Pts = new Hare.Geometry.Point[2]; double d_min = double.MaxValue; double d_max = double.MinValue; foreach (int j in Topo[0].Plane_Members[i]) { //Do the polygon/plane intersection for each member 'j' of i. Hare.Geometry.Point[] vtx = Topo[0].Polygon_Vertices(j); Hare.Geometry.Point[] temp = new Hare.Geometry.Point[1]; uint tmpcount = 0; for (int k = 0, h = 1; k < vtx.Length; k++, h++) { Vector ab = vtx[h % vtx.Length] - vtx[k]; double t = (d - Hare_math.Dot(Normal, vtx[k])) / Hare_math.Dot(Normal, ab); // If t in [0..1] compute and return intersection point if (t >= 0.0f && t <= 1.0f) { temp[tmpcount] = vtx[k] + t * ab; tmpcount++; } if (h == 0 && tmpcount == 0) { break; } if (tmpcount > 1) { break; } } foreach (Hare.Geometry.Point p in temp) { Hare.Geometry.Point v = Origin - p; double tmp = v.x * v.x + v.y * v.y + v.z * v.z; if (tmp > d_max) { Pts[1] = p; d_max = tmp; } if (tmp < d_min) { Pts[0] = p; d_min = tmp; } } } dist2.Add(d_min); EdgeIDs.Add(i); Vector direction = (Pts[1] - Pts[0]); direction.Normalize(); Dir.Add(direction); } }
/// <summary> /// Ray-Triangle intersection algorithm, based on the algorithm published by Tomas Akenine-Möller, May 2000 /// </summary> /// <param name="orig">Ray origin point</param> /// <param name="dir">Ray direction vector</param> /// <param name="vert0">First triangle vertex</param> /// <param name="vert1">Second triangle vertex</param> /// <param name="vert2">Third triangle vertex</param> /// <param name="t">t-value along ray where an intersection point has been found (if any).</param> /// <param name="u">u-value on triangle where an intersection point has been found (if any).</param> /// <param name="v">v-value on triangle where an intersection point has been found (if any).</param> /// <returns>True if an intersection was found, false if not.</returns> protected bool RayXtri(Point orig, Vector dir, Point vert0, Point vert1, Point vert2, ref double t, ref double u, ref double v) { /* find vectors for two edges sharing vert0 */ Vector edge1 = vert1 - vert0; Vector edge2 = vert2 - vert0; /* begin calculating determinant - also used to calculate U parameter */ Vector pvec = Hare_math.Cross(dir, edge2); /* if determinant is near zero, ray lies in plane of triangle */ double det = Hare_math.Dot(edge1, pvec); /* calculate distance from vert0 to ray origin */ Vector tvec = orig - vert0; double invdet = 1.0 / det; Vector qvec = Hare_math.Cross(tvec, edge1); if (det > 0.000001) { u = Hare_math.Dot(tvec, pvec); if (u < 0.0 || u > det) { return(false); } /* calculate V parameter and test bounds */ v = Hare_math.Dot(dir, qvec); if (v < 0.0 || u + v > det) { return(false); } } else if (det < -0.000001) { /* calculate U parameter and test bounds */ u = Hare_math.Dot(tvec, pvec); if (u > 0.0 || u < det) { return(false); } /* calculate V parameter and test bounds */ v = Hare_math.Dot(dir, qvec); if (v > 0.0 || u + v < det) { return(false); } } else { return(false); /* ray is parallell to the plane of the triangle */ } t = Hare_math.Dot(edge2, qvec) * invdet; u *= invdet; v *= invdet; return(true); }
/// <summary> /// Returns a boolean indicating which side of a polygon a ray is located on. /// </summary> /// <param name="Dir">A vector indicating the direction of the ray.</param> /// <returns>True if the ray is on the correct side of the polygon to indicate an intersection point.</returns> protected bool Ray_Side(Vector Dir) { double n = Hare_math.Dot(Dir, Normal); if (n < 0) { return(false); } return(true); }
public bool Cyl_Coord(Hare.Geometry.Point S, Hare.Geometry.Point R, ref double rs, ref double thetas, ref double zs, ref double rr, ref double thetar, ref double zr, out int Obtuse_Side)//, out double[] tm, out double[] tl) { //diffx = Tangent; //diffy = Normal; //diffz = Z_Norm; Vector S_D = S - Z_mid; Vector R_D = R - Z_mid; Vector S_Norm = new Vector(S_D.x, S_D.y, S_D.z) / S_D.Length(); // S - Z_mid; Vector R_Norm = new Vector(R_D.x, R_D.y, R_D.z) / R_D.Length(); //R - Z_mid; double S0 = Hare_math.Dot(S_Norm, Tangent[0]); double S1 = Hare_math.Dot(S_Norm, Tangent[1]); uint SDIR = 0; if (S0 > S1) { if (S1 > 0) { SDIR = 1; } } Obtuse_Side = (Hare_math.Dot(S_Norm, Normal[SDIR]) < 0 ? 1 : 0); zs = Hare_math.Dot(S_D, Z_Norm); //S_Coord.z; zr = Hare_math.Dot(R_D, Z_Norm); //R_Coord.z; Hare.Geometry.Point S_p = S - (Z_mid + zs * Z_Norm); Hare.Geometry.Point R_p = R - (Z_mid + zr * Z_Norm); rs = Math.Sqrt(S_p.x * S_p.x + S_p.y * S_p.y + S_p.z * S_p.z); //Math.Sqrt(S_Coord.x * S_Coord.x + S_Coord.y * S_Coord.y + S_Coord.z * S_Coord.z); rr = Math.Sqrt(R_p.x * R_p.x + R_p.y * R_p.y + R_p.z * R_p.z); //Math.Sqrt(R_Coord.x * R_Coord.x + R_Coord.y * R_Coord.y + R_Coord.z * R_Coord.z); thetas = Math.Acos(Hare_math.Dot(Tangent[SDIR], S_Norm)); //Math.Atan2(S_Coord.y, S_Coord.x); //double sdt = Hare_math.Dot(Tangent[SDIR], S_Norm); double rdt = Hare_math.Dot(Normal[SDIR] * (Obtuse_Side == 1 ? 1 : -1), R_Norm); if (rdt > 0) { thetar = Utilities.Numerics.PiX2 - Math.Acos(Hare_math.Dot(Tangent[SDIR], R_Norm));//Math.Atan2(R_Coord.y, R_Coord.x); } else { thetar = Math.Acos(Hare_math.Dot(Tangent[SDIR], R_Norm)); } //if (thetas < 0) thetas += Utilities.Numerics.PiX2; //if (thetar < 0) thetar += Utilities.Numerics.PiX2; return(true); }
private bool planeBoxOverlap(Vector normal, Point vert, Point maxbox) { Point vmin = new Point(0, 0, 0), vmax = new Point(0, 0, 0); double v; v = vert.x; if (normal.x > 0.0f) { vmin.x = -maxbox.x - v; vmax.x = maxbox.x - v; } else { vmin.x = maxbox.x - v; vmax.x = -maxbox.x - v; } v = vert.y; if (normal.y > 0.0f) { vmin.y = -maxbox.y - v; vmax.y = maxbox.y - v; } else { vmin.y = maxbox.y - v; vmax.y = -maxbox.y - v; } v = vert.z; if (normal.z > 0.0f) { vmin.z = -maxbox.z - v; vmax.z = maxbox.z - v; } else { vmin.z = maxbox.z - v; vmax.z = -maxbox.z - v; } if (Hare_math.Dot(normal, vmin) > 0.0f) { return(false); } if (Hare_math.Dot(normal, vmax) >= 0.0f) { return(true); } return(false); }
public Edge_Curved(ref IEnumerable <Hare.Geometry.Point> SPT, ref IEnumerable <Hare.Geometry.Point> RPT, bool issoft, double EdgeLength, Environment.Medium_Properties Att_Props, MathNet.Numerics.Interpolation.CubicSpline[] Edge_Crv, MathNet.Numerics.Interpolation.CubicSpline[] TangentA, MathNet.Numerics.Interpolation.CubicSpline[] TangentB) { //Find the secondary source spacing DeltaZ double fs = 176400; //Hz. double DeltaZ = 0; Point pt1 = new Point(Edge_Crv[0].Interpolate(0), Edge_Crv[1].Interpolate(0), Edge_Crv[2].Interpolate(0)); Vector Z_Dir = pt1 - new Point(Edge_Crv[0].Interpolate(0.001), Edge_Crv[1].Interpolate(0.001), Edge_Crv[2].Interpolate(0.001)); Z_Dir.Normalize(); List <Hare.Geometry.Point> Dpt = new List <Hare.Geometry.Point>(); //Find the secondary source spacing DeltaZ //Dpt.AddRange(RPT); //Dpt.AddRange(SPT); double i = 0; do { double MinAngle = double.NegativeInfinity; foreach (Point spt in SPT) { foreach (Point pt in RPT) { Vector D1 = (pt1 - pt); Vector D2 = (pt1 - spt); D1.Normalize(); D2.Normalize(); double angle = Math.Abs(Hare_math.Dot((D2 + D1) / 2, Z_Dir)); if (angle > MinAngle) { MinAngle = angle; } } } DeltaZ = Att_Props.Sound_Speed(pt1) / (fs * MinAngle); i += DeltaZ; if (i > EdgeLength) { break; } Hare.Geometry.Point pt2 = new Point(Edge_Crv[0].Interpolate(i), Edge_Crv[1].Interpolate(i), Edge_Crv[2].Interpolate(i)); Sources.Add(new EdgeSource(Edge.Rigid, pt1, pt2, new Vector[2] { new Vector(TangentA[0].Interpolate(i), TangentA[1].Interpolate(i), TangentA[2].Interpolate(i)), new Vector(TangentA[3].Interpolate(i), TangentA[4].Interpolate(i), TangentA[5].Interpolate(i)) })); pt1 = pt2; } while (true); }
public EdgeSource(int[] attr_in, Hare.Geometry.Point PtZ0, Hare.Geometry.Point _PtZ, Vector[] _Tangents) { attr = attr_in; Tangent = _Tangents; Z_Norm = _PtZ - PtZ0; Z_Range = Z_Norm.Length(); Z_dot = Z_Range * Z_Range;//Hare_math.Dot(Z_Norm, Z_Norm); Z_Norm /= Z_Range; Z_Range_2 = Z_Range / 2; Z_mid = (PtZ0 + _PtZ) / 2; Vector Bisector = (Tangent[0] + Tangent[1]) / 2; Bisector.Normalize(); double BisectAngle = Math.Acos(Hare_math.Dot(Tangent[0], Bisector)); if (BisectAngle == 0) { BisectAngle = 1E-12; } v = new double[2] { Math.PI / (2 * BisectAngle), Math.PI / (Utilities.Numerics.PiX2 - 2 * BisectAngle) }; v_4pi = new double[2] { v[0] / (4 * Math.PI), v[1] / (4 * Math.PI) }; v_2pi = new double[2] { v[0] / (2 * Math.PI), v[1] / (2 * Math.PI) }; Normal[0] = Hare_math.Cross(_Tangents[0], Z_Norm); Normal[1] = Hare_math.Cross(_Tangents[1], Z_Norm * -1); if (Hare_math.Dot(Normal[0], Bisector) > 0) { Normal[0] *= -1; Normal[1] *= -1; } //////////////////////////// //VisCheck// Rhino.Geometry.Point3d pt = new Rhino.Geometry.Point3d(Z_mid.x, Z_mid.y, Z_mid.z); Rhino.RhinoDoc.ActiveDoc.Objects.AddLine(pt, pt + new Rhino.Geometry.Point3d(Normal[0].x, Normal[0].y, Normal[0].z)); Rhino.RhinoDoc.ActiveDoc.Objects.AddLine(pt, pt + new Rhino.Geometry.Point3d(Normal[1].x, Normal[1].y, Normal[1].z)); //Rhino.RhinoDoc.ActiveDoc.Objects.AddLine(pt, pt + new Rhino.Geometry.Point3d(Tangent[0].x, Tangent[0].y, Tangent[0].z)); //Rhino.RhinoDoc.ActiveDoc.Objects.AddLine(pt, pt + new Rhino.Geometry.Point3d(Tangent[1].x, Tangent[1].y, Tangent[1].z)); //////Rhino.RhinoDoc.ActiveDoc.Objects.AddPoint(new Rhino.Geometry.Point3d(Z_mid.x, Z_mid.y, Z_mid.z)); }
public Polygon(ref List <Point> Vertices, int index, int id) { top_index = index; for (int j = 2; j < Vertices.Count; j++) { Normal = Hare_math.Cross(Vertices[1] - Vertices[0], Vertices[j] - Vertices[0]); if (!Normal.IsZeroVector()) { break; } } Points = new Point[Vertices.Count]; for (int p = 0; p < Vertices.Count; p++) { Points[p] = Vertices[p]; } Normal.Normalize(); diffz = new Vector(Normal.x, Normal.y, Normal.z); diffx = new Vector(0, 0, 1); double proj = Math.Abs(Hare_math.Dot(diffz, diffx)); if (0.99 < proj && 1.01 > proj) { diffx = new Vector(1, 0, 0); } diffy = new Vector(diffz.x, diffz.y, diffz.z); diffy = Hare_math.Cross(diffy, diffx); diffx = Hare_math.Cross(diffy, diffz); diffx.Normalize(); diffy.Normalize(); diffz.Normalize(); d = Hare_math.Dot(Normal, Points[0]); VertexCount = Points.Length; Inv_Dot_Normal = 1 / (Hare_math.Dot(Normal, Normal)); if (VertexCount < 3) { IsDegenerate = true; } Poly_index = id; IsConvex = Convexity(); }
public Hare.Geometry.Point ClosestPoint(Hare.Geometry.Point p, out int sel) { double min = double.PositiveInfinity; sel = -1; for (int i = 0; i < Samples.Length; i++) { Hare.Geometry.Vector v = p - Samples[i]; double lsq = Hare_math.Dot(v, v); if (lsq < min) { min = lsq; sel = i; } } return(Samples[sel]); }
/// <summary> /// Determines whether or not all triangular subdivisions of a convex polygon can be considered coplanar. /// </summary> /// <param name="P"></param> /// <returns></returns> public static bool IsCoPlanar(Point[] P) { if (P.Length > 3) { Vector First_Tri_CP = Hare_math.Cross(P[1] - P[0], P[2] - P[0]); First_Tri_CP.Normalize(); for (int j = 2, k = 3; k < P.Length; j++, k++) { Vector V = Hare_math.Cross(P[j] - P[0], P[k] - P[0]); double x = Hare_math.Dot(First_Tri_CP, V); if (x < 1) { return(false); } } } return(true); }
public EdgeSource(int[] attr_in, Hare.Geometry.Point Z_mid_in, double Delta_Z, Vector[] _Tangents) { attr = attr_in; Tangent = _Tangents; Z_Norm = Hare.Geometry.Hare_math.Cross(_Tangents[0], _Tangents[1]); Z_Range = Delta_Z; Z_dot = Z_Range * Z_Range;//Hare_math.Dot(Z_Norm, Z_Norm); Z_Range_2 = Z_Range / 2; Z_Norm.Normalize(); Z_mid = Z_mid_in; Vector Bisector = (Tangent[0] + Tangent[1]) / 2; Bisector.Normalize(); double BisectAngle = Math.Acos(Hare_math.Dot(Tangent[0], Bisector)); if (BisectAngle == 0) { BisectAngle = 1E-12; } v = new double[2] { Math.PI / (2 * BisectAngle), Math.PI / (Utilities.Numerics.PiX2 - 2 * BisectAngle) }; v_4pi = new double[2] { v[0] / (4 * Math.PI), v[1] / (4 * Math.PI) }; v_2pi = new double[2] { v[0] / (2 * Math.PI), v[1] / (2 * Math.PI) }; //BisectAngle = Math.Cos(BisectAngle); Normal[0] = Hare_math.Cross(_Tangents[0], Z_Norm); Normal[1] = Hare_math.Cross(_Tangents[1], Z_Norm * -1); if (Hare_math.Dot(Normal[0], Bisector) > 0) { Normal[0] *= -1; Normal[1] *= -1; } }
public Edge_Straight(ref IEnumerable <Hare.Geometry.Point> SPT, ref IEnumerable <Hare.Geometry.Point> RPT, Environment.Medium_Properties Att_Props, Rhino.Geometry.Brep[] Brep, int[] Brep_Index, Curve Be) : base(Brep, Be) { //Rhino.RhinoDoc.ActiveDoc.Objects.Add(Brep[0]); //Rhino.RhinoDoc.ActiveDoc.Objects.Add(Brep[1]); ParentBreps = Brep_Index; //Rhino.RhinoDoc.ActiveDoc.Objects.AddCurve(Be); //if (!Brep.Edges[edge_id].IsLinear()) throw new Exception("Straight_Edge object called for curved edge."); Rhino.Geometry.Point3d PA = Be.PointAtStart; Rhino.Geometry.Point3d PB = Be.PointAtEnd; PointA = Utilities.PachTools.RPttoHPt(PA); PointB = Utilities.PachTools.RPttoHPt(PB); //Get the open wedge angle. This needs the source location, and occlusion info... //Assuming tangent angles are always correctly oriented... Vector Z_Dir = PointA - PointB; double length = Z_Dir.Length(); Z_Dir.Normalize(); double MinAngle = double.PositiveInfinity; List <Hare.Geometry.Point> Dpt = new List <Hare.Geometry.Point>(); //Find the secondary source spacing DeltaZ Dpt.AddRange(RPT); Dpt.AddRange(SPT); for (int j = 0; j < Dpt.Count; j++) { double angle = Math.Abs(Hare_math.Dot(PointA - Dpt[j], Z_Dir)); if (angle < MinAngle) { MinAngle = angle; } angle = Math.Abs(Hare_math.Dot(PointB - Dpt[j], Z_Dir)); if (angle < MinAngle) { MinAngle = angle; } } double fs = 176400; //Hz. double DeltaZ = Att_Props.Sound_Speed(this.PointA) / (fs * MinAngle); //TODO: Adjust depending on distance from source to receiver... (nearest, farthest?) double El_Ct = Math.Ceiling(length / DeltaZ); DeltaZ = length / El_Ct; Random r = new Random(); Plane P; Curve[] Csects1; Curve[] Csects2; Point3d[] Psects; //for (;;) //{ double t = r.NextDouble() * (Be.Domain.Max - Be.Domain.Min) + Be.Domain.Min; Be.PerpendicularFrameAt(t, out P); Rhino.Geometry.Intersect.Intersection.BrepPlane(Brep[0], P, 0.1, out Csects1, out Psects); Rhino.Geometry.Intersect.Intersection.BrepPlane(Brep[1], P, 0.1, out Csects2, out Psects); //if (Csects1 != null && Csects2 != null && Csects1.Length > 0 && Csects2.Length > 0) break; //Rhino.RhinoDoc.ActiveDoc.Objects.Add(Csects1[0]); //Rhino.RhinoDoc.ActiveDoc.Objects.Add(Csects2[0]); //} Vector3d[] Tangents = new Vector3d[2]; ///Control Start Point of curve if ((Csects1[0].PointAtStart.X * P.Origin.X + Csects1[0].PointAtStart.Y * P.Origin.Y + Csects1[0].PointAtStart.Z * P.Origin.Z) < 0.00001) { Csects1[0].Reverse(); } if ((Csects2[0].PointAtStart.X * P.Origin.X + Csects2[0].PointAtStart.Y * P.Origin.Y + Csects2[0].PointAtStart.Z * P.Origin.Z) < 0.00001) { Csects2[0].Reverse(); } ///Get Tangent Vector Tangents[0] = (Csects1[0].PointAtNormalizedLength(0.05) - P.Origin); Tangents[0].Unitize(); Tangents[1] = (Csects2[0].PointAtNormalizedLength(0.05) - P.Origin); Tangents[1].Unitize(); Hare.Geometry.Vector[] HTangents = new Hare.Geometry.Vector[2] { new Hare.Geometry.Vector(Tangents[0].X, Tangents[0].Y, Tangents[0].Z), new Hare.Geometry.Vector(Tangents[1].X, Tangents[1].Y, Tangents[1].Z) }; ///Get Normal double up, vp; ComponentIndex CI; Point3d outPt; Vector3d[] Normals = new Vector3d[2]; Brep[0].ClosestPoint(P.Origin, out outPt, out CI, out up, out vp, 0.01, out Normals[0]); Brep[1].ClosestPoint(P.Origin, out outPt, out CI, out up, out vp, 0.01, out Normals[1]); Hare.Geometry.Vector[] HNormals = new Hare.Geometry.Vector[2] { new Hare.Geometry.Vector(Normals[0].X, Normals[0].Y, Normals[0].Z), new Hare.Geometry.Vector(Normals[1].X, Normals[1].Y, Normals[1].Z) }; Hare.Geometry.Point Pt1 = new Hare.Geometry.Point(PointA.x, PointA.y, PointA.z); //TODO - Modify DeltaZ per change in velocity. for (int i = 1; i < El_Ct; i++) { Hare.Geometry.Point Pt2 = PointA - i * Z_Dir * DeltaZ; Sources.Add(new EdgeSource(Edge.Rigid, Pt1, Pt2, HTangents)); //HTangents[1]*= -1; //Sources.Add(new EdgeSource(Edge.Rigid, Pt1, Pt2, HTangents)); Pt1 = Pt2; } }
private Vector XRefraction(Vector V_in, double VPrev, double V) { Vector V_out = new Vector(0, -V_in.z, V_in.y); double V_fract = VPrev / V; return(V_fract * new Vector(0, V_out.z, -V_out.y) - new Vector(Math.Sqrt(1 - V_fract * V_fract * Hare_math.Dot(V_out, V_out)), 0, 0)); }
public Edge_Straight(ref IEnumerable <Hare.Geometry.Point> SPT, ref IEnumerable <Hare.Geometry.Point> RPT, Environment.Medium_Properties Att_Props, bool isSoft, Hare.Geometry.Point[] PointS, MathNet.Numerics.Interpolation.CubicSpline[] TangentA, MathNet.Numerics.Interpolation.CubicSpline[] TangentB) { PointA = PointS[0]; PointB = PointS[PointS.Length - 1]; //Get the open wedge angle. This needs the source location, and occlusion info... //Assuming tangent angles are always correctly oriented... Vector Z_Dir = PointA - PointB; double length = Z_Dir.Length(); Z_Dir.Normalize(); //double MinAngle = double.PositiveInfinity; List <Hare.Geometry.Point> Dpt = new List <Hare.Geometry.Point>(); //Find the secondary source spacing DeltaZ Dpt.AddRange(RPT); Dpt.AddRange(SPT); //for (int j = 0; j < Dpt.Count; j++) //{ // double angle = Math.Abs(Hare_math.Dot(PointA - Dpt[j], Z_Dir)); // if (angle < MinAngle) MinAngle = angle; // angle = Math.Abs(Hare_math.Dot(PointB - Dpt[j], Z_Dir)); // if (angle < MinAngle) MinAngle = angle; //} double fs = 176400; //Hz. //double DeltaZ = Att_Props.Sound_Speed(this.PointA) / (fs * MinAngle);//TODO: Adjust depending on distance from source to receiver... (nearest, farthest?) //double El_Ct = Math.Ceiling(length / DeltaZ); //DeltaZ = length / El_Ct; Random r = new Random(); Hare.Geometry.Point Pt1 = new Hare.Geometry.Point(PointA.x, PointA.y, PointA.z); //TODO - Modify DeltaZ per change in velocity. //for (int i = 1; i < El_Ct; i++) //{ // Hare.Geometry.Point Pt2 = PointA - i * Z_Dir * DeltaZ; // Sources.Add(new EdgeSource(Edge.Rigid, Pt1, Pt2, HTangents)); // //HTangents[1]*= -1; // //Sources.Add(new EdgeSource(Edge.Rigid, Pt1, Pt2, HTangents)); // Pt1 = Pt2; //} Point pt1 = PointA; double DeltaZ = 0; //for (int i = 1; i < El_Ct; i++) for (double i = 0; i < length; i += DeltaZ) { double MinAngle = double.PositiveInfinity; foreach (Point pt in Dpt) { double angle = Math.Abs(Hare_math.Dot(PointA - pt, Z_Dir)); if (angle < MinAngle) { MinAngle = angle; } } DeltaZ = Att_Props.Sound_Speed(pt1) / (fs * MinAngle); Hare.Geometry.Point Pt2 = PointA - Z_Dir * i; Sources.Add(new EdgeSource(Edge.Rigid, Pt1, Pt2, new Vector[2] { new Vector(TangentA[0].Interpolate(i), TangentA[1].Interpolate(i), TangentA[2].Interpolate(i)), new Vector(TangentB[0].Interpolate(i), TangentB[1].Interpolate(i), TangentB[2].Interpolate(i)) })); Pt1 = Pt2; } }
/// <summary> /// Finds the closest point on the plane of a polygon from a specified point. /// </summary> /// <param name="q">The point to be compared.</param> /// <returns>The closest point on the plane.</returns> public Point ClosestPtPointPlane(Point q) { double t = Hare_math.Dot(Normal, q) - d; return(q - (t * Normal)); }
/// <summary> /// Finds the distance between a specified point and the closest point on the plane of a polygon. /// </summary> /// <param name="q">The point to compare to the plane of the polygon.</param> /// <returns>The distance between a point and the plane of the polygon.</returns> public double DistToPlane(Point q) { return((Hare_math.Dot(Normal, q) - d) * Inv_Dot_Normal); }
/// <summary> /// Calculates the direction of a specular reflection. /// </summary> /// <param name="RayDirect"></param> /// <param name="u"></param> /// <param name="v"></param> /// <param name="x"></param> protected virtual void ReflectRay(ref BroadRay RayDirect, ref double u, ref double v, ref int x) { Vector local_N = Room.Normal(x, u, v); RayDirect.direction -= local_N * Hare_math.Dot(RayDirect.direction, local_N) * 2; }
/// <summary> /// Calculates the direction of a specular reflection. /// </summary> /// <param name="RayDirect"></param> /// <param name="u"></param> /// <param name="v"></param> /// <param name="x"></param> public virtual void ReflectRay(ref OctaveRay RayDirect, ref double u, ref double v, ref int x) { Vector local_N = Normal(x, u, v); RayDirect.direction -= local_N * Hare_math.Dot(RayDirect.direction, local_N) * 2; }
private Vector ZRefraction(Vector V_in, double VPrev, double V) { Vector V_out = new Vector(V_in.y, V_in.x, 0); double V_fract = VPrev / V; return(V_fract * new Vector(-V_out.y, -V_out.x, 0) - new Vector(0, 0, Math.Sqrt(1 - V_fract * V_fract * Hare_math.Dot(V_out, V_out)))); }
/// <summary> /// The closest point on a triangle to a given point. /// </summary> /// <param name="p">The referenced point.</param> /// <param name="a">Vertex a</param> /// <param name="b">Vertex b</param> /// <param name="c">Vertex c</param> /// <returns>The closest point.</returns> protected Point TriangleClosestPt(Point p, Point a, Point b, Point c) { // Check if P in vertex region outside A Vector ab = b - a; Vector ac = c - a; Vector ap = p - a; double d1 = Hare_math.Dot(ab, ap); double d2 = Hare_math.Dot(ac, ap); if (d1 <= 0.0f && d2 <= 0.0f) { return(a); // barycentric coordinates (1,0,0) } // Check if P in vertex region outside B Vector bp = p - b; double d3 = Hare_math.Dot(ab, bp); double d4 = Hare_math.Dot(ac, bp); if (d3 >= 0.0f && d4 <= d3) { return(b); // barycentric coordinates (0,1,0) } // Check if P in edge region of AB, if so return projection of P onto AB double vc = d1 * d4 - d3 * d2; if (vc <= 0.0f && d1 >= 0.0f && d3 <= 0.0f) { double v = d1 / (d1 - d3); return(a + v * ab); // barycentric coordinates (1-v,v,0) } // Check if P in vertex region outside C Vector cp = p - c; double d5 = Hare_math.Dot(ab, cp); double d6 = Hare_math.Dot(ac, cp); if (d6 >= 0.0f && d5 <= d6) { return(c); // barycentric coordinates (0,0,1) } // Check if P in edge region of AC, if so return projection of P onto AC double vb = d5 * d2 - d1 * d6; if (vb <= 0.0f && d2 >= 0.0f && d6 <= 0.0f) { double w = d2 / (d2 - d6); return(a + w * ac); // barycentric coordinates (1-w,0,w) } // Check if P in edge region of BC, if so return projection of P onto BC double va = d3 * d6 - d5 * d4; if (va <= 0.0f && (d4 - d3) >= 0.0f && (d5 - d6) >= 0.0f) { double w = (d4 - d3) / ((d4 - d3) + (d5 - d6)); return(b + w * (c - b)); // barycentric coordinates (0,1-w,w) } // P inside face region. Compute Q through its barycentric coordinates (u,v,w) double denom = 1.0f / (va + vb + vc); double vl = vb * denom; double wl = vc * denom; return(a + ab * vl + ac * wl); // = u*a + v*b + w*c, u = va * denom = 1.0f - v - w }