Пример #1
0
        private static Vector3D PerformDrag3DRight(DragData dragData, Vector3D lookFrom)
        {
            // The view vector magnitude.
            double   abs         = lookFrom.Abs();
            Vector3D newLookFrom = lookFrom;

            // Increment it.
            abs += 5 * abs * dragData.YPercent;
            newLookFrom.Normalize();
            newLookFrom *= abs;

            double smallestRadius = .02;

            if (newLookFrom.Abs() < smallestRadius)
            {
                newLookFrom.Normalize();
                newLookFrom *= smallestRadius;
            }

            double largestRadius = 100.0;

            if (newLookFrom.Abs() > largestRadius)
            {
                newLookFrom.Normalize();
                newLookFrom *= largestRadius;
            }

            return(newLookFrom);
        }
Пример #2
0
        public double ProjectedArea(Vector3D viewDir)
        {
            Vector3D vectord = this.Max - this.Min;
            Vector3D v       = new Vector3D(vectord.Y, vectord.Z, vectord.X) * new Vector3D(vectord.Z, vectord.X, vectord.Y);

            return(Vector3D.Abs(viewDir).Dot(v));
        }
Пример #3
0
        public static Vector3D EdgeToPlane(Geometry g, H3.Cell.Edge edge)
        {
            if (g != Geometry.Hyperbolic)
            {
                throw new System.NotImplementedException();
            }

            Vector3D b1, b2;

            H3Models.Ball.GeodesicIdealEndpoints(edge.Start, edge.End, out b1, out b2);
            if (((b2 + b1) / 2).IsOrigin)
            {
                Vector3D lineNormal = b2 - b1;
                lineNormal.RotateXY(Math.PI / 2);
                lineNormal.Normalize();
                return(new Vector3D(lineNormal.X, lineNormal.Y, lineNormal.Z, 0));
            }

            Vector3D center, normal;
            double   radius, angleTot;

            H3Models.Ball.Geodesic(edge.Start, edge.End, out center, out radius, out normal, out angleTot);

            Vector3D closest = H3Models.Ball.ClosestToOrigin(new Circle3D()
            {
                Center = center, Radius = radius, Normal = normal
            });
            Vector3D closestKlein = HyperbolicModels.PoincareToKlein(closest);

            center.Normalize();
            return(new Vector3D(center.X, center.Y, center.Z, closestKlein.Abs()));
        }
Пример #4
0
        /// <summary>
        /// Builds a segment going through the box (if we cross it).
        /// </summary>
        private static Segment BuildSegment(CircleNE c)
        {
            Vector3D[] iPoints = Box.GetIntersectionPoints(c);
            if (2 != iPoints.Length)
            {
                return(null);
            }

            if (c.IsLine)
            {
                return(Segment.Line(iPoints[0], iPoints[1]));
            }

            // Find the midpoint.  Probably a better way.
            Vector3D t1 = iPoints[0] - c.Center;
            Vector3D t2 = iPoints[1] - c.Center;
            double   angle1 = Euclidean2D.AngleToCounterClock(t1, t2);
            double   angle2 = Euclidean2D.AngleToClock(t1, t2);
            Vector3D mid1 = t1, mid2 = t1;

            mid1.RotateXY(angle1 / 2);
            mid2.RotateXY(-angle2 / 2);
            mid1 += c.Center;
            mid2 += c.Center;
            Vector3D mid = mid1;

            if (mid2.Abs() < mid1.Abs())
            {
                mid = mid2;
            }
            return(Segment.Arc(iPoints[0], mid, iPoints[1]));
        }
Пример #5
0
 internal static Sphere SphereFuncBall(Geometry g, Vector3D v, bool simple = true)
 {
     //bool simple = true;
     if (simple)
     {
         double size     = 125;
         double thickCen = 2.0 / size;
         //double thickEdge = .7 / size;
         double thickEdge = 1.0 / size;
         double thick     = thickCen - v.Abs() * (thickCen - thickEdge);
         return(new Sphere()
         {
             Center = v, Radius = thick
         });
     }
     else
     {
         double thick = .1;
         //double minRad = 0.8 / 100;
         double   minRad = 1.0 / 125;
         Vector3D c;
         double   r;
         H3Models.Ball.DupinCyclideSphere(v, thick / 2, g, out c, out r);
         return(new Sphere()
         {
             Center = c, Radius = Math.Max(r, minRad)
         });
     }
 }
Пример #6
0
        public double ProjectedArea(Vector3D viewDir)
        {
            Vector3D span = Max - Min;
            Vector3D size = new Vector3D(span.Y, span.Z, span.X) * new Vector3D(span.Z, span.X, span.Y);

            return(Vector3D.Abs(viewDir).Dot(size));
        }
Пример #7
0
        /// <summary> Рисует гирлянду из сфер. </summary>
        private void DrawSpheres()
        {
            Glu.GLUquadric quad = Glu.gluNewQuadric();

            for (int i = 0; i < 50; i++)
            {
                Vector3D position =
                    new Vector3D((float)((2.0 + 3.0 * i / 50.0) * Math.Sin(i)),
                                 (float)((2.0 + 3.0 * i / 50.0) * Math.Cos(i)),
                                 (float)(-4.0 + 9.0 * i / 50.0));

                Gl.glPushMatrix();

                Gl.glTranslatef(position.X * (float)(Math.Sin(time / 100.0)),
                                position.Y * (float)(Math.Cos(time / 100.0)),
                                position.Z * (float)(0.5 + 0.5 * Math.Sin(time / 100.0)));

                Gl.glColor3fv(Vector3D.Abs(position / 5.0f).ToArray());

                Glu.gluSphere(quad, 0.3f, 20, 20);

                Gl.glPopMatrix();
            }

            Glu.gluDeleteQuadric(quad);
        }
Пример #8
0
        /// <summary>
        /// Returns a stereographically sphere representing us.
        /// </summary>
        public Sphere ToSphere()
        {
            // Equatorial sphere?
            if (Pole == new Vector3D(0, 0, 0, 1))
            {
                return(new Sphere());
            }

            // A plane?
            Vector3D poleR3 = Sterographic.S3toR3(Pole);

            if (Tolerance.Equal(poleR3.Abs(), 1))
            {
                return(Sphere.Plane(poleR3));
            }

            // Get 4 points on the sphere.
            Vector3D e1 = new Vector3D(1, 0, 0, 0);
            Vector3D e2 = new Vector3D(0, 1, 0, 0);
            Vector3D e3 = new Vector3D(0, 0, 1, 0);
            Vector3D e4 = new Vector3D(0, 0, 0, 1);

            System.Func <Vector3D, Vector3D> one = v =>
            {
                v = Euclidean3D.ProjectOntoPlane(Pole, new Vector3D(), v);
                v.Normalize();
                return(Sterographic.S3toR3(v));
            };

            return(Sphere.From4Points(one(e1), one(e2), one(e3), one(e4)));
        }
Пример #9
0
            public bool Equals(SurfaceVertex v1, SurfaceVertex v2)
            {
                double threshold = 0.001;

                if (v1.Vertex.Compare(v2.Vertex, threshold))
                {
                    return(true);
                }

                foreach (Puzzle.Translation trans in m_translations)
                {
                    Vector3D offset = trans.m_translation;
                    if (Tolerance.Zero(offset.Abs(), threshold))
                    {
                        continue;
                    }

                    Vector3D test = v1.Vertex + offset;
                    if (test.Compare(v2.Vertex, threshold))
                    {
                        return(true);
                    }
                }

                return(false);
            }
Пример #10
0
 /// <summary>
 /// Offsets a vector by a hyperbolic distance.
 /// </summary>
 public static Vector3D Offset( Vector3D v, double hDist )
 {
     double mag = v.Abs();
     mag = DonHatch.h2eNorm( DonHatch.e2hNorm( mag ) + hDist );
     v.Normalize();
     v *= mag;
     return v;
 }
Пример #11
0
        public static double DistancePointPlane( Vector3D normalVector, Vector3D planePoint, Vector3D point )
        {
            // Check to make sure that plane is not degenerate.
            if( Tolerance.Zero( normalVector.MagSquared() ) )
                return double.NaN;

            // Here is the distance (signed depending on which side of the plane we are on).
            return ( point - planePoint ).Dot( normalVector ) / normalVector.Abs();
        }
Пример #12
0
        public static double DistancePointLine( Vector3D n1, Vector3D p1, Vector3D point )
        {
            // Check to make sure that n1 is not degenerate.
            if( Tolerance.Zero( n1.MagSquared() ) )
                return double.NaN;

            // ZZZ - Can we make this a signed distance?
            return ( ( point - p1 ).Cross( n1 ) ).Abs() / n1.Abs();
        }
Пример #13
0
 public static bool IsInfinite( Vector3D input )
 {
     // XXX - ugly hack I'd like to improve.
     return
         IsInfinite( input.X ) ||
         IsInfinite( input.Y ) ||
         IsInfinite( input.Z ) ||
         IsInfinite( input.W ) ||
         input.Abs() > InfiniteScale;
 }
Пример #14
0
        /// <summary>
        /// A simple thickening. This is not accurate, but meant to save cost by minimizing wall thickness everywhere.
        /// The input vector should live on normal.
        /// </summary>
        private static System.Tuple <Vector3D, Vector3D> ThickenSimple(Vector3D v, Sphere normal)
        {
            double size     = 125;
            double thickCen = 2.0 / size;
            //double thickEdge = .7 / size;
            double   thickEdge = 1.0 / size;
            double   thick     = thickCen - v.Abs() * (thickCen - thickEdge);
            Vector3D direction = v - normal.Center;

            return(ThickenSimple(v, direction, thick));
        }
Пример #15
0
        /// <summary>
        /// For a point outside the unit ball, get the ideal circle associate to the dual plane.
        /// </summary>
        public static Circle3D GetCircle(Vector3D p)
        {
            Sphere ball = new Sphere();

            // Our point defines an orthogonal cone to the unit ball.
            double d      = p.Abs();
            double radius = Math.Sqrt(d * d - 1);
            Sphere s      = new Sphere(p, radius);

            return(ball.Intersection(s));
        }
Пример #16
0
        /// <summary>
        /// Evaluates the configured flux function (see
        /// <see cref="BoundaryConditionSourceFromINonlinearFlux.BoundaryConditionSourceFromINonlinearFlux(CNSControl, ISpeciesMap, BoundaryCondition, INonlinearFlux)"/>
        /// using the present flow state <paramref name="U"/> and the boundary
        /// value provided by the configured boundary condition.
        /// </summary>
        /// <param name="time"></param>
        /// <param name="x"></param>
        /// <param name="U"></param>
        /// <param name="IndexOffset"></param>
        /// <param name="FirstCellInd"></param>
        /// <param name="Lenght"></param>
        /// <param name="Output"></param>
        public void Source(double time, MultidimensionalArray x, MultidimensionalArray[] U, int IndexOffset, int FirstCellInd, int Lenght, MultidimensionalArray Output)
        {
            int D             = CNSEnvironment.NumberOfDimensions;
            int noOfNodes     = x.GetLength(1);
            int noOfVariables = D + 2;

            MultidimensionalArray normal = MultidimensionalArray.Create(Lenght, noOfNodes, D);

            MultidimensionalArray[] Uout = new MultidimensionalArray[noOfVariables];
            for (int i = 0; i < noOfVariables; i++)
            {
                Uout[i] = MultidimensionalArray.Create(Lenght, noOfNodes);
            }

            double[] xLocal   = new double[D];
            Material material = speciesMap.GetMaterial(double.NaN);

            for (int i = 0; i < Lenght; i++)
            {
                for (int j = 0; j < noOfNodes; j++)
                {
                    StateVector stateIn = new StateVector(material, U, i, j);

                    Vector3D levelSetNormal = new Vector3D();
                    int      offset         = CNSEnvironment.NumberOfDimensions + 2;
                    for (int d = 0; d < CNSEnvironment.NumberOfDimensions; d++)
                    {
                        levelSetNormal[d] = U[offset + d][i + IndexOffset, j];
                    }
                    levelSetNormal.Normalize();
                    Debug.Assert(Math.Abs(levelSetNormal.Abs() - 1.0) < 1e-13, "Abnormal normal vector");

                    for (int d = 0; d < D; d++)
                    {
                        xLocal[d]       = x[i + IndexOffset, j, d];
                        normal[i, j, d] = levelSetNormal[d];
                    }

                    StateVector stateOut = boundaryCondition.GetBoundaryState(time, xLocal, levelSetNormal, stateIn);
                    Debug.Assert(stateOut.IsValid, "Invalid boundary state");

                    Uout[0][i, j] = stateOut.Density;
                    for (int d = 0; d < D; d++)
                    {
                        Uout[d + 1][i, j] = stateOut.Momentum[d];
                    }
                    Uout[D + 1][i, j] = stateOut.Energy;
                }
            }

            fluxFunction.InnerEdgeFlux(time, -1, x, normal, U, Uout, IndexOffset, Lenght, Output);
        }
Пример #17
0
        public override float GetVolume(ref Vector3D voxelPosition)
        {
            if (base.m_inverseIsDirty)
            {
                base.m_inverse        = MatrixD.Invert(base.m_transformation);
                base.m_inverseIsDirty = false;
            }
            voxelPosition = Vector3D.Transform(voxelPosition, base.m_inverse);
            Vector3D vectord = Vector3D.Abs(voxelPosition) - this.Boundaries.HalfExtents;
            double   num     = Vector3D.Dot(voxelPosition, this.RampNormal) + this.RampNormalW;

            return(base.SignedDistanceToDensity((float)Math.Max(vectord.Max(), -num)));
        }
Пример #18
0
        public void Vector3AbsTest()
        {
            Vector3D v1 = new Vector3D(-2.5f, 2.0f, 0.5f);
            Vector3D v3 = Vector3D.Abs(new Vector3D(0.0f, double.NegativeInfinity, double.NaN));
            Vector3D v  = Vector3D.Abs(v1);

            Assert.AreEqual(2.5f, v.X);
            Assert.AreEqual(2.0f, v.Y);
            Assert.AreEqual(0.5f, v.Z);
            Assert.AreEqual(0.0f, v3.X);
            Assert.AreEqual(double.PositiveInfinity, v3.Y);
            Assert.AreEqual(double.NaN, v3.Z);
        }
Пример #19
0
        public override float GetVolume(ref Vector3D voxelPosition)
        {
            if (base.m_inverseIsDirty)
            {
                base.m_inverse        = MatrixD.Invert(base.m_transformation);
                base.m_inverseIsDirty = false;
            }
            voxelPosition = Vector3D.Transform(voxelPosition, base.m_inverse);
            Vector3D center   = this.Boundaries.Center;
            Vector3D vectord2 = Vector3D.Abs(voxelPosition - center) - (center - this.Boundaries.Min);

            return(base.SignedDistanceToDensity((float)vectord2.Max()));
        }
Пример #20
0
        public void Vector3AbsTest()
        {
            Vector3D <float> v1 = new Vector3D <float>(-2.5f, 2.0f, 0.5f);
            Vector3D <float> v3 = Vector3D.Abs(new Vector3D <float>(0.0f, float.NegativeInfinity, float.NaN));
            Vector3D <float> v  = Vector3D.Abs(v1);

            Assert.Equal(2.5f, v.X);
            Assert.Equal(2.0f, v.Y);
            Assert.Equal(0.5f, v.Z);
            Assert.Equal(0.0f, v3.X);
            Assert.Equal(float.PositiveInfinity, v3.Y);
            Assert.Equal(float.NaN, v3.Z);
        }
Пример #21
0
        /**
         * Find the appropriate face for the projection of a point.
         */
        public static int FindCubeFace(ref Vector3D localPos)
        {
            Vector3D abs;

            Vector3D.Abs(ref localPos, out abs);

            if (abs.X > abs.Y)
            {
                if (abs.X > abs.Z)
                {
                    if (localPos.X > 0.0f)
                    {
                        return((int)Direction.Right);
                    }
                    else
                    {
                        return((int)Direction.Left);
                    }
                }
                else
                if (localPos.Z > 0.0f)
                {
                    return((int)Direction.Backward);
                }
                else
                {
                    return((int)Direction.Forward);
                }
            }
            else
            if (abs.Y > abs.Z)
            {
                if (localPos.Y > 0.0f)
                {
                    return((int)Direction.Up);
                }
                else
                {
                    return((int)Direction.Down);
                }
            }
            else
            if (localPos.Z > 0.0f)
            {
                return((int)Direction.Backward);
            }
            else
            {
                return((int)Direction.Forward);
            }
        }
Пример #22
0
        private static string FormatSphereNoMaterialOffset(Sphere sphere, bool invert, bool includeClosingBracket = true)
        {
            bool   microOffset = true;
            double microOff    = 0.00001;

            //microOff = 0.000001;
            // Don't offset unless drawn!!!
            //microOff = -0.00005;
            if (invert)
            {
                microOff *= -1;
            }

            if (sphere.IsPlane)
            {
                Vector3D offsetOnNormal = Euclidean2D.ProjectOntoLine(sphere.Offset, new Vector3D(), sphere.Normal);
                double   offset         = offsetOnNormal.Abs();
                if (offsetOnNormal.Dot(sphere.Normal) < 0)
                {
                    offset *= -1;
                }

                if (microOffset)
                {
                    offset -= microOff;
                }

                return(string.Format("plane {{ {0}, {1:G6}{2} {3}",
                                     FormatVec(sphere.Normal), offset, invert ? " inverse" : string.Empty,
                                     includeClosingBracket ? "}" : string.Empty));
            }
            else
            {
                double radius = sphere.Radius;
                if (microOffset)
                {
                    if (radius < 20)
                    {
                        radius -= microOff;
                    }
                    else
                    {
                        radius *= (1 - microOff);
                    }
                }

                return(string.Format("sphere {{ {0}, {1:G6}{2} {3}",
                                     FormatVec(sphere.Center), radius, invert ? " inverse" : string.Empty,
                                     includeClosingBracket ? "}" : string.Empty));
            }
        }
Пример #23
0
        /**
         * Project the position to local space for a provided face.
         */
        public static void ProjectForFace(ref Vector3D localPos, int face, out Vector2D normalCoord)
        {
            Vector3D abs;

            Vector3D.Abs(ref localPos, out abs);

            switch ((Direction)face)
            {
            case Direction.Forward:
                localPos     /= abs.Z;
                normalCoord.X = -localPos.X;
                normalCoord.Y = localPos.Y;
                break;

            case Direction.Backward:
                localPos     /= abs.Z;
                normalCoord.X = localPos.X;
                normalCoord.Y = localPos.Y;
                break;

            case Direction.Left:
                localPos     /= abs.X;
                normalCoord.X = localPos.Z;
                normalCoord.Y = localPos.Y;
                break;

            case Direction.Right:
                localPos     /= abs.X;
                normalCoord.X = -localPos.Z;
                normalCoord.Y = localPos.Y;
                break;

            case Direction.Up:
                localPos     /= abs.Y;
                normalCoord.X = localPos.Z;
                normalCoord.Y = localPos.X;
                break;

            case Direction.Down:
                localPos     /= abs.Y;
                normalCoord.X = -localPos.Z;
                normalCoord.Y = localPos.X;
                break;

            default:
                Debug.Fail("Bad face number!!!!!");
                normalCoord = Vector2D.Zero;
                break;
            }
        }
Пример #24
0
 private static string H3Facet(Sphere sphere)
 {
     if (sphere.IsPlane)
     {
         Vector3D offsetOnNormal = Euclidean2D.ProjectOntoLine(sphere.Offset, new Vector3D(), sphere.Normal);
         return(string.Format("plane {{ {0}, {1:G6} material {{ sphereMat }} clipped_by {{ ball }} }}",
                              FormatVec(sphere.Normal), offsetOnNormal.Abs()));
     }
     else
     {
         return(string.Format("sphere {{ {0}, {1:G6} material {{ sphereMat }} clipped_by {{ ball }} }}",
                              FormatVec(sphere.Center), sphere.Radius));
     }
 }
Пример #25
0
 private static string FormatSphereNoMaterial(Sphere sphere, bool invert, bool includeClosingBracket = true)
 {
     if (sphere.IsPlane)
     {
         Vector3D offsetOnNormal = Euclidean2D.ProjectOntoLine(sphere.Offset, new Vector3D(), sphere.Normal);
         return(string.Format("plane {{ {0}, {1:G6}{2} {3}",
                              FormatVec(sphere.Normal), offsetOnNormal.Abs(), invert ? " inverse" : string.Empty,
                              includeClosingBracket ? "}" : string.Empty));
     }
     else
     {
         return(string.Format("sphere {{ {0}, {1:G6}{2} {3}",
                              FormatVec(sphere.Center), sphere.Radius, invert ? " inverse" : string.Empty,
                              includeClosingBracket ? "}" : string.Empty));
     }
 }
Пример #26
0
        public Ray ExecuteTransform(Ray r)
        {
            Point3D  o = ExecuteTransform(r.Origin, out Vector3D oError);
            Vector3D d = ExecuteTransform(r.Direction);
            // Offset ray origin to edge of error bounds and compute _tMax_
            double lengthSquared = d.LengthSquared();
            double tMax          = r.TMax;

            if (lengthSquared > 0)
            {
                double dt = d.Abs().Dot(oError) / lengthSquared;
                o    += d.ToPoint3D() * dt;
                tMax -= dt;
            }
            return(new Ray(o, d, tMax, r.Time, r.Medium));
        }
Пример #27
0
        public Vector3D GetPow(Vector3D ThrVec, bool max = false)
        {
            var res = new Vector3D
            {
                X = ThrVec.X > 0 ? myThr.RightThrusters.EffectivePow : -myThr.LeftThrusters.EffectivePow,
                Y = ThrVec.Y > 0 ? myThr.UpThrusters.EffectivePow : -myThr.DownThrusters.EffectivePow,
                Z = ThrVec.Z > 0 ? myThr.BackwardThrusters.EffectivePow : -myThr.ForwardThrusters.EffectivePow
            };

            if (!max)
            {
                var c = ThrVec / Vector3D.Abs(ThrVec).Sum;
                c   /= c.AbsMax();
                res *= c;
            }
            return(res);
        }
Пример #28
0
        public H3.Cell.Edge[] Helicoid()
        {
            List <H3.Cell.Edge> fiberList = new List <H3.Cell.Edge>();

            // These two params affect each other (changing numFibers will affect rotation rate).
            double rotationRate = Math.PI / 78.5;
            int    numFibers    = 1000;

            // Note: we need to increment a constant hyperbolic distance each step.
            int    count  = 0;
            double max    = DonHatch.e2hNorm(0.998);
            double offset = max * 2 / (numFibers - 1);

            for (double z_h = -max; z_h <= max; z_h += offset)
            {
                double z = DonHatch.h2eNorm(z_h);

                Sphere   s = H3Models.Ball.OrthogonalSphereInterior(new Vector3D(0, 0, z));
                Circle3D c = H3Models.Ball.IdealCircle(s);

                // Two endpoints of our fiber.
                Vector3D v1 = new Vector3D(c.Radius, 0, c.Center.Z);
                Vector3D v2 = new Vector3D(-c.Radius, 0, c.Center.Z);

                v1.RotateXY(rotationRate * count);
                v2.RotateXY(rotationRate * count);

                v1 = Transform(v1);
                v2 = Transform(v2);

                Vector3D t      = Transform(new Vector3D(0, 0, z));
                double   cutoff = 0.995;
                if (t.Abs() > cutoff)
                {
                    continue;
                }

                fiberList.Add(new H3.Cell.Edge(v1, v2, order: false));
                count++;
            }

            return(fiberList.ToArray());
        }
Пример #29
0
        public static Circle3D GeodesicFrom2Points(Vector3D a, Vector3D b)
        {
            if (a == b || a == -b)
            {
                throw new System.Exception("Geodesic not unique");
            }

            System.Func <Vector3D, Circle3D> lineFunc = p =>
            {
                Circle3D circ = new Circle3D();
                circ.Radius = double.PositiveInfinity;
                p.Normalize();
                circ.Normal = p;                    // Hacky representation of a line.
                return(circ);
            };

            if (a.IsOrigin || b.IsOrigin)
            {
                Vector3D p = a.IsOrigin ? b : a;
                return(lineFunc(p));
            }

            double mag1 = a.Abs(), mag2 = b.Abs();

            if (Tolerance.Equal(mag1, 1) && Tolerance.Equal(mag2, 1))
            {
                return(new Circle3D(a, b, a * -1));
            }

            // The antipode in S^3 of a or b will give us a 3rd point.
            Vector3D antipode = Sterographic.S3toR3(Sterographic.R3toS3(a) * -1);

            // If the antipode is also an an antipode in R3, the points are colinear
            // (or they are on the equatorial 2-sphere, but that is checked above).
            if (a == antipode * -1)
            {
                return(lineFunc(a));
            }

            return(new Circle3D(a, b, antipode));
        }
Пример #30
0
        public static Circle3D GetCircleForBallPoint(Vector3D p)
        {
            Sphere ball = new Sphere();

            p = SphericalModels.GnomonicToStereo(p);

            if (Tolerance.GreaterThanOrEqual(p.Abs(), 1))
            {
                return(null);
            }

            Sphere t = H3Models.Ball.OrthogonalSphereInterior(p);

            //return H3Models.Ball.IdealCircle( t );

            // Get the corresponding point on the exterior (our inversion).
            p = HyperbolicModels.PoincareToKlein(p);
            p = HyperbolicModels.PoincareToKlein(p);
            p = ball.ReflectPoint(p);

            return(GetCircle(p));
        }
Пример #31
0
	// grid coordinates, not world coordinates
	public void calculateMaxThrust() {
		pos_maxThrustWorld = Vector3D.Zero;
		neg_maxThrustWorld = Vector3D.Zero;
		pos_maxThrust = Vector3D.Zero;
		neg_maxThrust = Vector3D.Zero;

		foreach(IMyThrust thruster in thrusters) {
			Vector3D engineDir = thruster.Orientation.Forward.GetVector();

			Vector3D engineForce = engineDir * thruster.MaxEffectiveThrust;
			Vector3D engineForceWorld = engineForce.TransformNormal(grid.WorldMatrix);

			// split into positive and negative
			Vector3D positive = (engineForce + engineForce.Abs())/2;
			pos_maxThrust += positive;
			neg_maxThrust += engineForce - positive;

			// and for world space too
			positive = (engineForceWorld + engineForceWorld.Abs())/2;
			pos_maxThrustWorld += positive;
			neg_maxThrustWorld += engineForceWorld - positive;
		}
	}
Пример #32
0
        private void PerformDrag3D(DragData dragData)
        {
            switch (dragData.Button)
            {
            case MouseButtons.Left:
            {
                // The spherical coordinate radius.
                double radius = m_viewLookFrom3D.Abs();
                if (!Tolerance.Zero(radius))
                {
                    Vector3D newLookFrom = m_viewLookFrom3D;
                    Vector3D newUp       = m_up3D;

                    Vector3D rotationAxis = newUp.Cross(newLookFrom);
                    rotationAxis.Normalize();

                    double angle = System.Math.Atan2(dragData.XDiff, dragData.YDiff);
                    rotationAxis.RotateAboutAxis(newLookFrom, angle);

                    double magnitude = -System.Math.Sqrt(dragData.XDiff * dragData.XDiff + dragData.YDiff * dragData.YDiff) / 100;
                    newLookFrom.RotateAboutAxis(rotationAxis, magnitude);
                    newUp.RotateAboutAxis(rotationAxis, magnitude);

                    m_viewLookFrom3D = newLookFrom;
                    m_up3D           = newUp;
                }

                break;
            }

            case MouseButtons.Right:
            {
                m_viewLookFrom3D = PerformDrag3DRight(dragData, m_viewLookFrom3D);
                break;
            }
            }
        }
Пример #33
0
        private void DrawCylinders()
        {
            Glu.GLUquadric quad = Glu.gluNewQuadric();

            for (int i = 1; i < 12; i++)
            {
                Vector3D position =
                    new Vector3D((float)(6.5 * Math.Sin(i * time / 50.0)),
                                 (float)(6.5 * Math.Cos(i * time / 50.0)),
                                 -5.0f);

                Gl.glPushMatrix();

                Gl.glTranslatef(position.X, position.Y, position.Z);

                Gl.glColor3fv(Vector3D.Abs(Vector3D.Sin(time * position / 100.0f)).ToArray());

                Glu.gluCylinder(quad, 0.5f, 0.0f, 1.5f, 20, 20);

                Gl.glPopMatrix();
            }

            Glu.gluDeleteQuadric(quad);
        }
Пример #34
0
            /// <summary>
            /// LOD
            /// </summary>
            public static void LOD_Finite( Vector3D e1, Vector3D e2, out int div1, out int div2, H3.Settings settings )
            {
                //if( settings.Halfspace )
                //	throw new System.NotImplementedException();

                int maxHit = 15;
                int hit = (int)( Math.Max( e1.Abs(), e2.Abs() ) * maxHit );
                div1 = 11;
                div2 = 30 - hit;

                /* lasercrystal
                int maxHit = 8;
                int hit = (int)( Math.Max( e1.Abs(), e2.Abs() ) * maxHit );
                div1 = 6;
                div2 = 20 - hit;*/
            }
Пример #35
0
 private static Vector3D HalfTo( Vector3D v )
 {
     double distHyperbolic = DonHatch.e2hNorm( v.Abs() );
     double halfDistEuclidean = DonHatch.h2eNorm( distHyperbolic / 3 );
     Vector3D result = v;
     result.Normalize( halfDistEuclidean );
     return result;
 }
Пример #36
0
            /// <summary>
            /// Given two points (in the UHS model), find the endpoints 
            /// of the associated geodesic that lie on the z=0 plane.
            /// </summary>
            public static void GeodesicIdealEndpoints( Vector3D v1, Vector3D v2, out Vector3D z1, out Vector3D z2 )
            {
                // We have to special case when geodesic is vertical (parallel to z axis).
                Vector3D diff = v2 - v1;
                Vector3D diffFlat = new Vector3D( diff.X, diff.Y );
                if( Tolerance.Zero( diffFlat.Abs() ) )	// Vertical
                {
                    Vector3D basePoint = new Vector3D( v1.X, v1.Y );
                    z1 = diff.Z > 0 ? basePoint : Infinity.InfinityVector;
                    z2 = diff.Z < 0 ? basePoint : Infinity.InfinityVector;
                }
                else
                {
                    if( Tolerance.Zero( v1.Z ) && Tolerance.Zero( v2.Z ) )
                    {
                        z1 = v1;
                        z2 = v2;
                        return;
                    }

                    // If one point is ideal, we need to not reflect that one!
                    bool swapped = false;
                    if( Tolerance.Zero( v1.Z ) )
                    {
                        Utils.SwapPoints( ref v1, ref v2 );
                        swapped = true;
                    }

                    Vector3D v1_reflected = v1;
                    v1_reflected.Z *= -1;
                    Circle3D c = new Circle3D( v1_reflected, v1, v2 );
                    Vector3D radial = v1 - c.Center;
                    radial.Z = 0;
                    if( !radial.Normalize() )
                    {
                        radial = v2 - c.Center;
                        radial.Z = 0;
                        if( !radial.Normalize() )
                            System.Diagnostics.Debugger.Break();
                    }

                    radial *= c.Radius;
                    z1 = c.Center + radial;
                    z2 = c.Center - radial;

                    // Make sure the order will be right.
                    // (z1 closest to v1 along arc).
                    if( v1.Dist( z1 ) > v2.Dist( z1 ) )
                        Utils.SwapPoints( ref z1, ref z2 );
                    if( swapped )
                        Utils.SwapPoints( ref z1, ref z2 );
                }
            }
Пример #37
0
        // x,y,z -> r,theta,phi
        public static Vector3D CartesianToSpherical( Vector3D v )
        {
            double r = v.Abs();
            if( Tolerance.Zero( r ) )
                return new Vector3D();

            return new Vector3D(
                r,
                Math.Acos( v.Z / r ),
                Math.Atan2( v.Y, v.X ) );
        }
Пример #38
0
        // r,theta,phi -> x,y,z
        public static Vector3D SphericalToCartesian( Vector3D v )
        {
            if( Tolerance.Zero( v.Abs() ) )
                return new Vector3D();

            return new Vector3D(
                v.X * Math.Sin( v.Y ) * Math.Cos( v.Z ),
                v.X * Math.Sin( v.Y ) * Math.Sin( v.Z ),
                v.X * Math.Cos( v.Y ) );
        }
Пример #39
0
            /// <summary>
            /// Helper that works in all geometries.
            /// center: http://www.wolframalpha.com/input/?i=%28+%28+%28+r+%2B+p+%29+%2F+%28+1+-+r*p+%29+%29+%2B+%28+%28+-r+%2B+p+%29+%2F+%28+1+%2B+r*p+%29+%29++%29+%2F+2
            /// radius: http://www.wolframalpha.com/input/?i=%28+%28+%28+r+%2B+p+%29+%2F+%28+1+-+r*p+%29+%29+-+%28+%28+-r+%2B+p+%29+%2F+%28+1+%2B+r*p+%29+%29++%29+%2F+2
            /// </summary>
            public static void DupinCyclideSphere( Vector3D vNonEuclidean, double radiusEuclideanOrigin, Geometry g,
				out Vector3D centerEuclidean, out double radiusEuclidean )
            {
                if( g == Geometry.Euclidean )
                {
                    centerEuclidean = vNonEuclidean;
                    radiusEuclidean = radiusEuclideanOrigin;
                    return;
                }

                double p = vNonEuclidean.Abs();
                if( !vNonEuclidean.Normalize() )
                {
                    // We are at the origin.
                    centerEuclidean = vNonEuclidean;
                    radiusEuclidean = radiusEuclideanOrigin;
                    return;
                }

                double r = radiusEuclideanOrigin;
                double numeratorCenter = g == Geometry.Hyperbolic ? ( 1 - r * r ) : ( 1 + r * r );
                double numeratorRadius = g == Geometry.Hyperbolic ? ( 1 - p * p ) : ( 1 + p * p );

                double center = p * numeratorCenter / ( 1 - p * p * r * r );
                radiusEuclidean = r * numeratorRadius / ( 1 - p * p * r * r );
                centerEuclidean = vNonEuclidean * center;

                /*
                // Alternate impl, in this case for spherical.
                Mobius m = new Mobius();
                m.Isometry( Geometry.Spherical, 0, p1 );
                Vector3D t1 = m.Apply( new Vector3D( mag, 0, 0 ) );
                Vector3D t2 = m.Apply( new Vector3D( -mag, 0, 0 ) );
                center = ( t1 + t2 ) / 2;
                radius = t1.Dist( t2 ) / 2; */
            }
Пример #40
0
            /// <summary>
            /// Calculate points along a geodesic segment from v1 to v2.
            /// </summary>
            public static Vector3D[] GeodesicPoints( Vector3D v1, Vector3D v2, int div )
            {
                Vector3D center, normal;
                double radius, angleTot;
                Geodesic( v1, v2, out center, out radius, out normal, out angleTot );

                if( Infinity.IsInfinite( radius ) ||
                    Tolerance.Zero( v1.Abs() ) || Tolerance.Zero( v2.Abs() ) )	// HACK! radius should be infinite, something wrong with geodesic func
                {
                    Segment seg = Segment.Line( v1, v2 );
                    return seg.Subdivide( div );
                    //return new Vector3D[] { v1, v2 };
                }
                else
                    return Shapeways.CalcArcPoints( center, radius, v1, normal, angleTot, div );
            }
Пример #41
0
            /// <summary>
            /// Find an orthogonal sphere defined by a single interior point.
            /// This point is the unique point on the sphere that is furthest from the ball boundary.
            /// (equivalently, closest to the origin)
            /// </summary>
            public static Sphere OrthogonalSphereInterior( Vector3D v )
            {
                // r = radius of sphere
                // c = distance from origin to passed in point
                // http://www.wolframalpha.com/input/?i=%28c%2Br%29%5E2+%3D+1+%2B+r%5E2%2C+solve+for+r
                double c = v.Abs();
                double r = -(c * c - 1) / (2 * c);

                v.Normalize();
                return new Sphere()
                {
                    Center = v * ( c + r ),
                    Radius = r
                };
            }
Пример #42
0
 /// <summary>
 /// Calculate the cosine of the angle between two vectors.
 /// </summary>
 private static double CosAngle( Vector3D p1, Vector3D p2 )
 {
     double cosA = p1.Dot( p2 ) / (p1.Abs() * p2.Abs());
     return Clamp( cosA );
 }
Пример #43
0
            /// <summary>
            /// Given 2 points in the interior of the ball, calculate the center and radius of the orthogonal circle.
            /// One point may optionally be on the boundary, but one shoudl be in the interior.
            /// If both points are on the boundary, we'll fall back on our other method.
            /// </summary>
            public static void OrthogonalCircleInterior( Vector3D v1, Vector3D v2, out Circle3D circle )
            {
                if( Tolerance.Equal( v1.Abs(), 1 ) &&
                    Tolerance.Equal( v2.Abs(), 1 ) )
                {
                    circle = OrthogonalCircle( v1, v2 );
                    return;
                }

                // http://www.math.washington.edu/~king/coursedir/m445w06/ortho/01-07-ortho-to3.html
                // http://www.youtube.com/watch?v=Bkvo09KE1zo

                Vector3D interior = Tolerance.Equal( v1.Abs(), 1 ) ? v2 : v1;

                Sphere ball = new Sphere();
                Vector3D reflected = ball.ReflectPoint( interior );
                circle = new Circle3D( reflected, v1, v2 );
            }
Пример #44
0
 /// <summary>
 /// Calculate the sine of the angle between two vectors.
 /// </summary>
 private static double SinAngle( Vector3D p1, Vector3D p2 )
 {
     double sinA = (p1.Cross( p2 )).Abs() / (p1.Abs() * p2.Abs());
     return Clamp( sinA );
 }
Пример #45
0
        public static PerspectiveCamera CreateFromBounds(AxisAlignedBox3D bounds, Viewport3D viewport,
                                                         float fieldOfView, float yaw = 0.0f, float pitch = 0.0f, float zoom = 1.0f)
        {
            // Calculate initial guess at camera settings.
            Matrix3D          transform       = Matrix3D.CreateFromYawPitchRoll(yaw, pitch, 0);
            Vector3D          cameraDirection = Vector3D.Normalize(transform.Transform(Vector3D.Forward));
            PerspectiveCamera initialGuess    = new PerspectiveCamera
            {
                FieldOfView       = fieldOfView,
                NearPlaneDistance = 1.0f,
                FarPlaneDistance  = bounds.Size.Length() * 10,
                Position          = bounds.Center - cameraDirection * bounds.Size.Length() * 2,
                LookDirection     = cameraDirection,
                UpDirection       = Vector3D.Up
            };

            Matrix3D projection = initialGuess.GetProjectionMatrix(viewport.AspectRatio);
            Matrix3D view       = initialGuess.GetViewMatrix();

            // Project bounding box corners onto screen, and calculate screen bounds.
            float closestZ     = float.MaxValue;
            Box2D?screenBounds = null;

            Point3D[] corners = bounds.GetCorners();
            foreach (Point3D corner in corners)
            {
                Point3D screenPoint = viewport.Project(corner,
                                                       projection, view, Matrix3D.Identity);

                if (screenPoint.Z < closestZ)
                {
                    closestZ = screenPoint.Z;
                }

                IntPoint2D intScreenPoint = new IntPoint2D((int)screenPoint.X, (int)screenPoint.Y);
                if (screenBounds == null)
                {
                    screenBounds = new Box2D(intScreenPoint, intScreenPoint);
                }
                else
                {
                    Box2D value = screenBounds.Value;
                    value.Expand(intScreenPoint);
                    screenBounds = value;
                }
            }

            // Now project back from screen bounds into scene, setting Z to the minimum bounding box Z value.
            IntPoint2D minScreen = screenBounds.Value.Min;
            IntPoint2D maxScreen = screenBounds.Value.Max;
            Point3D    min       = viewport.Unproject(new Point3D(minScreen.X, minScreen.Y, closestZ),
                                                      projection, view, Matrix3D.Identity);
            Point3D max = viewport.Unproject(new Point3D(maxScreen.X, maxScreen.Y, closestZ),
                                             projection, view, Matrix3D.Identity);

            // Use these new values to calculate the distance the camera should be from the AABB centre.
            Vector3D size   = Vector3D.Abs(max - min);
            float    radius = size.Length();
            float    dist   = radius / (2 * MathUtility.Tan(fieldOfView * viewport.AspectRatio / 2));

            Point3D closestBoundsCenter = (min + (max - min) / 2);
            Point3D position            = closestBoundsCenter - cameraDirection * dist * (1 / zoom);

            return(new PerspectiveCamera
            {
                FieldOfView = fieldOfView,
                NearPlaneDistance = 1.0f,
                FarPlaneDistance = dist * 10,
                Position = position,
                LookDirection = cameraDirection,
                UpDirection = Vector3D.Up
            });
        }