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);
                }
            }
Exemplo n.º 2
0
            /// <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);
            }
Exemplo n.º 3
0
            /// <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);
            }
Exemplo n.º 4
0
            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);
            }
Exemplo n.º 5
0
            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);
            }
Exemplo n.º 6
0
        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);
        }
Exemplo n.º 7
0
            public Quadrilateral(ref List <Point> Vertices, int index, int id)
                : base(ref Vertices, index, id)
            {
                if (VertexCount != 4)
                {
                    throw new ApplicationException("Faulty Quadrilateral");
                }

                area_Fraction[0] = 0.5 * Hare_math.Cross((Points[1] - Points[0]), (Points[2] - Points[0])).Length();
                area_Fraction[1] = 0.5 * Hare_math.Cross((Points[2] - Points[3]), (Points[1] - Points[3])).Length();
                double Area = area_Fraction[0] + area_Fraction[1];

                area_Fraction[0] /= Area;
                area_Fraction[1] /= Area;
            }
Exemplo n.º 8
0
            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));
            }
Exemplo n.º 9
0
            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();
            }
Exemplo n.º 10
0
            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]);
            }
Exemplo n.º 11
0
 /// <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);
 }
Exemplo n.º 12
0
            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;
                }
            }
Exemplo n.º 13
0
 /// <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);
 }
Exemplo n.º 14
0
        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;
            }
        }
Exemplo n.º 15
0
            /// <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));
            }
Exemplo n.º 16
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;
            }
        }
Exemplo n.º 17
0
            public bool PolyBoxOverlap(Point[] P)
            {
                Point[][] triangles = new Point[P.Length - 2][];

                for (int q = 0, j = 1, k = 2; k < P.Length; q++, j++, k++)
                {
                    triangles[q] = new Point[] { P[0], P[j], P[k] };
                }

                foreach (Point[] triverts in triangles)
                {
                    /*    use separating axis theorem to test overlap between triangle and box */
                    /*    need to test for overlap in these directions: */
                    /*    1) the {x,y,z}-directions (actually, since we use the AABB of the triangle */
                    /*       we do not even need to test these) */
                    /*    2) normal of the triangle */
                    /*    3) crossproduct(edge from tri, {x,y,z}-directin) */
                    /*       this gives 3x3=9 more tests */

                    v0 = new Vector(0, 0, 0);
                    v1 = new Vector(0, 0, 0);
                    v2 = new Vector(0, 0, 0);

                    //   float axis[3];
                    double fex, fey, fez;               // -NJMP- "d" local variable removed
                    Vector normal, e0, e1, e2;

                    /* This is the fastest branch on Sun */
                    /* move everything so that the boxcenter is in (0,0,0) */
                    v0 = triverts[0] - Center;
                    v1 = triverts[1] - Center;
                    v2 = triverts[2] - Center;

                    /* compute triangle edges */
                    e0 = v1 - v0;     /* tri edge 0 */
                    e1 = v2 - v1;     /* tri edge 1 */
                    e2 = v0 - v2;     /* tri edge 2 */

                    /* Bullet 3:  */
                    /*  test the 9 tests first (this was faster) */
                    fex = Math.Abs(e0.x);
                    fey = Math.Abs(e0.y);
                    fez = Math.Abs(e0.z);
                    if (!AXISTEST_X01(e0.z, e0.y, fez, fey))
                    {
                        continue;
                    }
                    if (!AXISTEST_Y02(e0.z, e0.x, fez, fex))
                    {
                        continue;
                    }
                    if (!AXISTEST_Z12(e0.y, e0.x, fey, fex))
                    {
                        continue;
                    }

                    fex = Math.Abs(e1.x);
                    fey = Math.Abs(e1.y);
                    fez = Math.Abs(e1.z);
                    if (!AXISTEST_X01(e1.z, e1.y, fez, fey))
                    {
                        continue;
                    }
                    if (!AXISTEST_Y02(e1.z, e1.x, fez, fex))
                    {
                        continue;
                    }
                    if (!AXISTEST_Z0(e1.y, e1.x, fey, fex))
                    {
                        continue;
                    }

                    fex = Math.Abs(e2.x);
                    fey = Math.Abs(e2.y);
                    fez = Math.Abs(e2.z);
                    if (!AXISTEST_X2(e2.z, e2.y, fez, fey))
                    {
                        continue;
                    }
                    if (!AXISTEST_Y1(e2.z, e2.x, fez, fex))
                    {
                        continue;
                    }
                    if (!AXISTEST_Z12(e2.y, e2.x, fey, fex))
                    {
                        continue;
                    }

                    /* Bullet 1: */
                    /*  first test overlap in the {x,y,z}-directions */
                    /*  find min, max of the triangle each direction, and test for overlap in */
                    /*  that direction -- this is equivalent to testing a minimal AABB around */
                    /*  the triangle against the AABB */

                    /* test in X-direction */
                    FINDMINMAX(v0.x, v1.x, v2.x, ref min, ref max);
                    if (min > halfwidth.x || max < -halfwidth.x)
                    {
                        continue;
                    }

                    /* test in Y-direction */
                    FINDMINMAX(v0.y, v1.y, v2.y, ref min, ref max);
                    if (min > halfwidth.y || max < -halfwidth.y)
                    {
                        continue;
                    }

                    /* test in Z-direction */
                    FINDMINMAX(v0.z, v1.z, v2.z, ref min, ref max);
                    if (min > halfwidth.z || max < -halfwidth.z)
                    {
                        continue;
                    }

                    /* Bullet 2: */
                    /*  test if the box intersects the plane of the triangle */
                    /*  compute plane equation of triangle: normal*x+d=0 */

                    normal = Hare_math.Cross(e0, e1);
                    if (!planeBoxOverlap(normal, v0, halfwidth))
                    {
                        continue;   // -NJMP-
                    }
                    return(true);   /* box and triangle overlaps */
                }
                return(false);
            }
        /// <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;
        }
Exemplo n.º 19
0
            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));
            }
Exemplo n.º 20
0
            public bool Poly_Overlap_Area(Polygon Pts, out double Area)
            {
                System.Collections.Generic.List <Point> XPts = new System.Collections.Generic.List <Point>();
                int ct = 0;

                for (int i = 0; i < Pts.VertextCT; i++)
                {
                    if (this.IsPointInBox(Pts.Points[i]))
                    {
                        ct++;
                        XPts.Add(Pts.Points[i]);
                    }
                }

                if (ct == Pts.VertextCT)
                {
                    if (ct == 3)
                    {
                        Area = Hare_math.Cross(Pts.Points[1] - Pts.Points[0], Pts.Points[2] - Pts.Points[0]).Length() / 2;
                    }
                    else
                    {
                        Area = Hare_math.Cross((Pts.Points[2] - Pts.Points[0]), (Pts.Points[3] - Pts.Points[1])).Length() / 2;
                    }
                    return(true);
                }

                for (int i = 0; i < Pts.VertextCT; i++)
                {
                    int    j    = (i + 1) % Pts.VertextCT;
                    double tmin = 0;
                    Point  X    = new Point();
                    this.Intersect(new Ray(Pts.Points[i], Pts.Points[j] - Pts.Points[i], 0, 0), ref tmin, ref X);
                    if (tmin < 1)
                    {
                        XPts.Add(X);
                    }
                }

                Point  I;
                double u; double v; double t; int id;

                for (int i = 0; i < 12; i++)
                {
                    if (Pts.Intersect(Edge(i), Pts.Points, out I, out u, out v, out t, out id))
                    {
                        XPts.Add(I);
                    }
                }

                if (XPts.Count == 0)
                {
                    Area = 0;
                    return(false);
                }

                //Sort XPts by polar angle.

                Point Center = new Point();

                foreach (Point Pt in XPts)
                {
                    Center += Pt;
                }
                Center /= XPts.Count;

                System.Collections.SortedList PtSort = new System.Collections.SortedList();
                if (Pts.Normal.x == 1)
                {
                    foreach (Point Pt in XPts)
                    {
                        PtSort.Add(System.Math.Atan2(Pt.y - Center.y, Pt.z - Center.z), Pt);
                    }
                }
                else if (Pts.Normal.y == 1)
                {
                    foreach (Point Pt in XPts)
                    {
                        PtSort.Add(System.Math.Atan2(Pt.x - Center.x, Pt.z - Center.z), Pt);
                    }
                }
                else
                {
                    foreach (Point Pt in XPts)
                    {
                        PtSort.Add(System.Math.Atan2(Pt.x - Center.x, Pt.y - Center.y), Pt);
                    }
                }

                Area = 0;

                for (int i = 0; i < PtSort.Count - 2; i++)
                {
                    Area += Hare_math.Cross((Point)PtSort[i + 1] - (Point)PtSort[i], (Point)PtSort[i + 2] - (Point)PtSort[i]).Length() / 2;
                }

                return(true);
            }
            /// <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;
            }
Exemplo n.º 22
0
            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))));
            }
Exemplo n.º 23
0
            /// <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
            }