예제 #1
0
        /// <summary>
        /// Determines which side of a line a horizontal line segment lies on.
        /// Used in point in polygon.
        /// </summary>
        /// <param name="hr">The horizontal line segment</param>
        /// <returns>Code indicating the position of the horizontal segment with respect to this line.
        /// Side.Left if the horizontal segment is to the left of this line; Side.Right if to the
        /// right of this line; Side.Unknown if the side cannot be determined (this line is
        /// horizontal).
        /// </returns>
        internal override Side GetSide(HorizontalRay hr)
        {
            // Express the end of the horizontal in a local system with
            // the same origin as the circle this arc lies on.
            IPosition  center = m_Circle.Center;
            QuadVertex pos    = new QuadVertex(center, hr.End);
            Quadrant   quad   = pos.Quadrant;

            // Assign the side code, assuming the arc is clockwise.
            Side result = (quad == Quadrant.NE || quad == Quadrant.SE ? Side.Right : Side.Left);

            // If the horizontal is apparently to the right of the curve,
            // but the location in question coincides with the extreme
            // north point of the circle, reverse the side (it's OK in
            // the extreme south).

            if (result == Side.Right)
            {
                double maxnorth = center.Y + Circle.Radius;
                if (Math.Abs(maxnorth - hr.Y) < Constants.TINY)
                {
                    result = Side.Left;
                }
            }

            // If the arc actually goes anti-clockwise, reverse the side.
            if (!m_IsClockwise)
            {
                result = (result == Side.Left ? Side.Right : Side.Left);
            }

            return(result);
        }
예제 #2
0
        /// <summary>
        /// Creates the VertexBuffer for the quad
        /// </summary>
        /// <param name="graphicsDevice">The GraphicsDevice to use</param>
        private void CreateFullScreenQuad(GraphicsDevice graphicsDevice)
        {
            // Create a vertex buffer for the quad, and fill it in
            vertexBuffer = new VertexBuffer(graphicsDevice, typeof(QuadVertex), vertexDeclaration.GetVertexStrideSize(0) * 4, BufferUsage.None);
            QuadVertex[] vbData = new QuadVertex[4];

            // Upper right
            vbData[0].position = new Vector3(1, 1, 1);
            vbData[0].texCoordAndCornerIndex = new Vector3(1, 0, 1);

            // Lower right
            vbData[1].position = new Vector3(1, -1, 1);
            vbData[1].texCoordAndCornerIndex = new Vector3(1, 1, 2);

            // Upper left
            vbData[2].position = new Vector3(-1, 1, 1);
            vbData[2].texCoordAndCornerIndex = new Vector3(0, 0, 0);

            // Lower left
            vbData[3].position = new Vector3(-1, -1, 1);
            vbData[3].texCoordAndCornerIndex = new Vector3(0, 1, 3);


            vertexBuffer.SetData(vbData);
        }
예제 #3
0
        /// <summary>
        /// Creates a full-screen Quad VB
        /// </summary>
        /// <param name="vertexDeclaration">The VertexDeclaration to use</param>
        /// <returns>The VB for the quad</returns>
        protected VertexBuffer CreateFullScreenQuad(VertexDeclaration vertexDeclaration)
        {
            // Create a vertex buffer for the quad, and fill it in
            var vertexBuffer = new VertexBuffer(
                _graphicsDevice, typeof(QuadVertex), vertexDeclaration.GetVertexStrideSize(0) * 4, BufferUsage.None);
            var vbData = new QuadVertex[4];

            // Upper right
            vbData[0].Position = new Vector3(1, 1, 1);
            vbData[0].TexCoord = new Vector2(1, 0);

            // Lower right
            vbData[1].Position = new Vector3(1, -1, 1);
            vbData[1].TexCoord = new Vector2(1, 1);

            // Upper left
            vbData[2].Position = new Vector3(-1, 1, 1);
            vbData[2].TexCoord = new Vector2(0, 0);

            // Lower left
            vbData[3].Position = new Vector3(-1, -1, 1);
            vbData[3].TexCoord = new Vector2(0, 1);

            vertexBuffer.SetData(vbData);
            return(vertexBuffer);
        }
예제 #4
0
        /// <summary>
        /// Checks an array of positions that purportedly correspond to a circular arc, to see
        /// whether the data is directed clockwise or not. No checks are made to confirm that
        /// the data really does correspond to a circular arc.
        /// </summary>
        /// <param name="pts">The positions defining an arc</param>
        /// <param name="center">The position of the centre of the circle that the arc lies on.</param>
        /// <returns>True if the data is ordered clockwise.</returns>
        public static bool IsClockwise(IPointGeometry[] pts, IPointGeometry center)
        {
            // To determine the direction, we must locate two successive
            // vertices that lie in the same quadrant (with respect to the
            // circle center).

            QuadVertex start = new QuadVertex(center, pts[0]);
            QuadVertex end   = null;

            for (int i = 1; i < pts.Length; i++, start = end)
            {
                // Pick up the position at the end of the line segment.
                end = new QuadVertex(center, pts[i]);

                // If both ends of the segment are in the same quadrant,
                // see which one comes first. The result tells us whether
                // the curve is clockwise or not.

                if (start.Quadrant == end.Quadrant)
                {
                    return(start.GetTanAngle() < end.GetTanAngle());
                }
            }

            // Something has gone wrong if we got here!
            Debug.Assert(1 == 2);
            return(true);
        }
예제 #5
0
        /// <summary>
        /// Creates the VertexBuffer for the quad
        /// </summary>
        private void createFullScreenQuad()
        {
            var vbData = new QuadVertex[4];

            // Upper right
            vbData[0].Position = new Vector3(1, 1, 1);
            vbData[0].TexCoordAndCornerIndex = new Vector3(1, 0, 1);

            // Lower right
            vbData[1].Position = new Vector3(1, -1, 1);
            vbData[1].TexCoordAndCornerIndex = new Vector3(1, 1, 2);

            // Upper left
            vbData[2].Position = new Vector3(-1, 1, 1);
            vbData[2].TexCoordAndCornerIndex = new Vector3(0, 0, 0);

            // Lower left
            vbData[3].Position = new Vector3(-1, -1, 1);
            vbData[3].TexCoordAndCornerIndex = new Vector3(0, 1, 3);


            using (var strm = new DataStream(vbData, true, false))
            {
                vertexBuffer = new Buffer(device, strm, 4 * QuadVertex.SizeInBytes, ResourceUsage.Immutable, BindFlags.VertexBuffer,
                                          CpuAccessFlags.None, ResourceOptionFlags.None, 0);
            }
        }
예제 #6
0
        public virtual void LoadContent(bool reload)
        {
            if (this.vertexBuffer != null && !this.vertexBuffer.IsDisposed)
            {
                this.vertexBuffer.Dispose();
            }

            // Create a vertex buffer for the quad, and fill it in
            this.vertexBuffer = new VertexBuffer(this.main.GraphicsDevice, typeof(QuadVertex), FullscreenQuad.VertexDeclaration.VertexStride * 4, BufferUsage.None);
            QuadVertex[] vbData = new QuadVertex[4];

            // Upper right
            vbData[0].Position = new Vector3(1, 1, 1);
            vbData[0].TexCoordAndCornerIndex = new Vector3(1, 0, 1);

            // Lower right
            vbData[1].Position = new Vector3(1, -1, 1);
            vbData[1].TexCoordAndCornerIndex = new Vector3(1, 1, 2);

            // Upper left
            vbData[2].Position = new Vector3(-1, 1, 1);
            vbData[2].TexCoordAndCornerIndex = new Vector3(0, 0, 0);

            // Lower left
            vbData[3].Position = new Vector3(-1, -1, 1);
            vbData[3].TexCoordAndCornerIndex = new Vector3(0, 1, 3);

            this.vertexBuffer.SetData(vbData);
        }
        Mesh GetQuadMesh()
        {
            if (quad != null)
            {
                return(quad);
            }

            var layout = new[]
            {
                new VertexAttributeDescriptor(VertexAttribute.Position, VertexAttributeFormat.Float32, 4),
                new VertexAttributeDescriptor(VertexAttribute.TexCoord0, VertexAttributeFormat.Float32, 2),
            };

            quad = new Mesh();
            quad.SetVertexBufferParams(4, layout);

            var quadVerts = new NativeArray <QuadVertex>(4, Allocator.Temp);

            var margin = 1.0f;

            quadVerts[0] = new QuadVertex()
            {
                pos = new float4(-margin, -margin, 1, 1), uv = new float2(0, 0)
            };
            quadVerts[1] = new QuadVertex()
            {
                pos = new float4(margin, -margin, 1, 1), uv = new float2(1, 0)
            };
            quadVerts[2] = new QuadVertex()
            {
                pos = new float4(margin, margin, 1, 1), uv = new float2(1, 1)
            };
            quadVerts[3] = new QuadVertex()
            {
                pos = new float4(-margin, margin, 1, 1), uv = new float2(0, 1)
            };

            quad.SetVertexBufferData(quadVerts, 0, 0, 4);
            quadVerts.Dispose();

            var quadTris = new int[6] {
                0, 1, 2, 0, 2, 3
            };

            quad.SetIndices(quadTris, MeshTopology.Triangles, 0);
            quad.bounds = new Bounds(Vector3.zero, new Vector3(10000, 10000, 1000));

            return(quad);
        }
예제 #8
0
        // If the specified position isn't actually on the arc, the length is to the
        // position when it's projected onto the arc (i.e. the perpendicular position)
        public static ILength GetLength(ICircularArcGeometry g, IPosition asFarAs)
        {
            ICircleGeometry circle = g.Circle;
            double          radius = circle.Radius;

            if (asFarAs == null)
            {
                // If the BC coincides with the EC, it's possible the arc has zero
                // length. As a matter of convention, counter-clockwise arcs will
                // be regarded as having a length of zero in that case. Meanwhile,
                // clockwise arcs will have a length that corresponds to the complete
                // circumference of the circle.

                if (g.BC.IsCoincident(g.EC))
                {
                    if (g.IsClockwise)
                    {
                        return(CircleGeometry.GetLength(circle));
                    }
                    else
                    {
                        return(Backsight.Length.Zero);
                    }
                }

                return(new Length(radius * g.SweepAngleInRadians));
            }

            // Express the position of the BC in a local coordinate system.
            IPosition  c  = circle.Center;
            QuadVertex bc = new QuadVertex(c, g.BC, radius);

            // Calculate the clockwise angle to the desired point.
            QuadVertex to  = new QuadVertex(c, asFarAs, radius);
            double     ang = to.BearingInRadians - bc.BearingInRadians;

            if (ang < 0.0)
            {
                ang += MathConstants.PIMUL2;
            }

            // If the curve is actually anti-clockwise, take the complement.
            if (!g.IsClockwise)
            {
                ang = MathConstants.PIMUL2 - ang;
            }

            return(new Length(radius * ang));
        }
예제 #9
0
        public override void LoadContent(bool reload)
        {
            // Create a vertex buffer for the quad, and fill it in
            this.vertexBuffer = new VertexBuffer(this.main.GraphicsDevice, typeof(QuadVertex), FullscreenQuad.VertexDeclaration.VertexStride * 4, BufferUsage.None);
            QuadVertex[] vbData = new QuadVertex[4];

            // Upper right
            vbData[0].Position = new Vector3(1, 1, 1);
            vbData[0].TexCoordAndCornerIndex = new Vector3(1, 0, 1);

            // Lower right
            vbData[1].Position = new Vector3(1, -1, 1);
            vbData[1].TexCoordAndCornerIndex = new Vector3(1, 1, 2);

            // Upper left
            vbData[2].Position = new Vector3(-1, 1, 1);
            vbData[2].TexCoordAndCornerIndex = new Vector3(0, 0, 0);

            // Lower left
            vbData[3].Position = new Vector3(-1, -1, 1);
            vbData[3].TexCoordAndCornerIndex = new Vector3(0, 1, 3);

            this.vertexBuffer.SetData(vbData);
        }
예제 #10
0
        /// <summary>
        /// Gets the most easterly position for this arc.
        /// </summary>
        /// <returns>The most easterly position</returns>
        internal override IPosition GetEastPoint()
        {
            // If the arc is a complete circle, just work it out the easy way.
            if (IsCircle)
            {
                return(m_Circle.GetEastPoint());
            }

            // Determine where the east point is. It could be either the
            // BC, the EC, or the most easterly point of the circle.

            IPosition start  = First;
            IPosition end    = Second;
            char      choice = (start.X > end.X ? 'S' : choice = 'E');

            // But hold on. If the arc passes from the northeast to southeast
            // quadrant, we want the east point of the circle.

            IPosition  c  = m_Circle.Center;
            QuadVertex vs = new QuadVertex(c, start);
            QuadVertex ve = new QuadVertex(c, end);

            Quadrant qs = vs.Quadrant;
            Quadrant qe = ve.Quadrant;

            // If the BC & EC are in the same quadrant, the only way the
            // circle point can apply is if it goes all the way round.
            if (!(qs == qe && vs.GetTanAngle() < ve.GetTanAngle()))
            {
                // Determine whether the circle point applies.
                switch (qs)
                {
                case Quadrant.NE:
                {
                    choice = 'C';
                    break;
                }

                case Quadrant.SE:
                    break;

                case Quadrant.SW:
                {
                    if (qe == Quadrant.SE)
                    {
                        choice = 'C';
                    }

                    break;
                }

                case Quadrant.NW:
                {
                    if (qe != Quadrant.NE)
                    {
                        choice = 'C';
                    }

                    break;
                }
                }
            }

            if (choice == 'S')
            {
                return(start);
            }
            else if (choice == 'E')
            {
                return(end);
            }

            Debug.Assert(choice == 'C');
            return(m_Circle.GetEastPoint());
        }
예제 #11
0
파일: Water.cs 프로젝트: schmittens/Lemma
        private void loadEffectAndVertexBuffers()
        {
            this.effect = this.main.Content.Load <Effect>("Effects\\Water").Clone();
            this.effect.Parameters["NormalMap" + Model.SamplerPostfix].SetValue(this.main.Content.Load <Texture2D>("Textures\\water-normal"));

            this.Color.Reset();
            this.Fresnel.Reset();
            this.Speed.Reset();
            this.RippleDensity.Reset();
            this.Distortion.Reset();
            this.Brightness.Reset();
            this.Refraction.Reset();
            this.UnderwaterColor.Reset();

            // Surface
            this.surfaceVertexBuffer = new VertexBuffer(this.main.GraphicsDevice, typeof(QuadVertex), Water.VertexDeclaration.VertexStride * 4, BufferUsage.None);
            QuadVertex[] surfaceData = new QuadVertex[4];

            // Upper right
            const float scale = 0.5f;

            surfaceData[0].Position = new Vector3(scale, 0, scale);
            surfaceData[0].TexCoord = new Vector2(1, 0);

            // Upper left
            surfaceData[1].Position = new Vector3(-scale, 0, scale);
            surfaceData[1].TexCoord = new Vector2(0, 0);

            // Lower right
            surfaceData[2].Position = new Vector3(scale, 0, -scale);
            surfaceData[2].TexCoord = new Vector2(1, 1);

            // Lower left
            surfaceData[3].Position = new Vector3(-scale, 0, -scale);
            surfaceData[3].TexCoord = new Vector2(0, 1);

            surfaceData[0].Normal = surfaceData[1].Normal = surfaceData[2].Normal = surfaceData[3].Normal = new Vector3(0, 1, 0);

            this.surfaceVertexBuffer.SetData(surfaceData);

            // Underwater
            this.underwaterVertexBuffer = new VertexBuffer(this.main.GraphicsDevice, typeof(QuadVertex), Water.VertexDeclaration.VertexStride * 4, BufferUsage.None);

            QuadVertex[] underwaterData = new QuadVertex[4];

            // Upper right
            underwaterData[0].Position = new Vector3(1, 1, 1);
            underwaterData[0].TexCoord = new Vector2(1, 0);

            // Lower right
            underwaterData[1].Position = new Vector3(1, -1, 1);
            underwaterData[1].TexCoord = new Vector2(1, 1);

            // Upper left
            underwaterData[2].Position = new Vector3(-1, 1, 1);
            underwaterData[2].TexCoord = new Vector2(0, 0);

            // Lower left
            underwaterData[3].Position = new Vector3(-1, -1, 1);
            underwaterData[3].TexCoord = new Vector2(0, 1);

            underwaterData[0].Normal = underwaterData[1].Normal = underwaterData[2].Normal = underwaterData[3].Normal = new Vector3(0, 0, -1);

            this.underwaterVertexBuffer.SetData(underwaterData);
        }
예제 #12
0
        /// <summary>
        /// Determines which side of a line a horizontal line segment lies on.
        /// Used in point in polygon.
        /// </summary>
        /// <param name="hr">The horizontal line segment</param>
        /// <returns>Code indicating the position of the horizontal segment with respect to this line.
        /// Side.Left if the horizontal segment is to the left of this line; Side.Right if to the
        /// right of this line; Side.Unknown if the side cannot be determined (this line is
        /// horizontal).
        /// </returns>
        internal override Side GetSide(HorizontalRay hr)
        {
            // Express the end of the horizontal in a local system with
            // the same origin as the circle this arc lies on.
            IPosition center = m_Circle.Center;
            QuadVertex pos = new QuadVertex(center, hr.End);
            Quadrant quad = pos.Quadrant;

            // Assign the side code, assuming the arc is clockwise.
            Side result = (quad==Quadrant.NE || quad==Quadrant.SE ? Side.Right : Side.Left);

            // If the horizontal is apparently to the right of the curve,
            // but the location in question coincides with the extreme
            // north point of the circle, reverse the side (it's OK in
            // the extreme south).

            if (result==Side.Right)
            {
                double maxnorth = center.Y + Circle.Radius;
                if (Math.Abs(maxnorth - hr.Y) < Constants.TINY)
                    result = Side.Left;
            }

            // If the arc actually goes anti-clockwise, reverse the side.
            if (!m_IsClockwise)
                result = (result==Side.Left ? Side.Right : Side.Left);

            return result;
        }
예제 #13
0
        public static IWindow GetExtent(ICircularArcGeometry g)
        {
            // If the curve is a complete circle, just define it the easy way.
            if (g.BC.IsCoincident(g.EC))
            {
                return(CircleGeometry.GetExtent(g.Circle));
            }

            IPosition bcp    = g.BC;
            IPosition ecp    = g.EC;
            IPosition centre = g.Circle.Center;

            // Initialize the window with the start location.
            Window win = new Window(bcp);

            // Expand using the end location
            win.Union(ecp);

            // If the curve is completely within one quadrant, we're done.
            QuadVertex bc = new QuadVertex(centre, bcp);
            QuadVertex ec = new QuadVertex(centre, ecp);

            Quadrant qbc = bc.Quadrant;
            Quadrant qec = ec.Quadrant;

            if (qbc == qec)
            {
                if (g.IsClockwise)
                {
                    if (bc.GetTanAngle() < ec.GetTanAngle())
                    {
                        return(win);
                    }
                }
                else
                {
                    if (ec.GetTanAngle() < bc.GetTanAngle())
                    {
                        return(win);
                    }
                }
            }

            // Get the window of the circle
            IWindow circle = CircleGeometry.GetExtent(g.Circle);

            // If the curve is anticlockwise, switch the quadrants for BC & EC
            if (!g.IsClockwise)
            {
                Quadrant temp = qbc;
                qbc = qec;
                qec = temp;
            }

            // Expand the window, depending on which quadrants the start &
            // end points fall in. The lack of breaks in the inner switches
            // is intentional (e.g. if start & end both fall in Quadrant.NorthEast,
            // the window we want is the complete circle, having checked above
            // for the case where the arc is JUST in Quadrant.NorthEast).

            // Define do-nothing values for the Union's below
            double wx = win.Min.X;
            double wy = win.Min.Y;

            if (qbc == Quadrant.NE)
            {
                switch (qec)
                {
                case Quadrant.NE:
                    win.Union(wx, circle.Max.Y);
                    goto case Quadrant.NW;

                case Quadrant.NW:
                    win.Union(circle.Min.X, wy);
                    goto case Quadrant.SW;

                case Quadrant.SW:
                    win.Union(wx, circle.Min.Y);
                    goto case Quadrant.SE;

                case Quadrant.SE:
                    win.Union(circle.Max.X, wy);
                    break;
                }
            }
            else if (qbc == Quadrant.SE)
            {
                switch (qec)
                {
                case Quadrant.SE:
                    win.Union(circle.Max.X, wy);
                    goto case Quadrant.NE;

                case Quadrant.NE:
                    win.Union(wx, circle.Max.Y);
                    goto case Quadrant.NW;

                case Quadrant.NW:
                    win.Union(circle.Min.X, wy);
                    goto case Quadrant.SW;

                case Quadrant.SW:
                    win.Union(wx, circle.Min.Y);
                    break;
                }
            }
            else if (qbc == Quadrant.SW)
            {
                switch (qec)
                {
                case Quadrant.SW:
                    win.Union(wx, circle.Min.Y);
                    goto case Quadrant.SE;

                case Quadrant.SE:
                    win.Union(circle.Max.X, wy);
                    goto case Quadrant.NE;

                case Quadrant.NE:
                    win.Union(wx, circle.Max.Y);
                    goto case Quadrant.NW;

                case Quadrant.NW:
                    win.Union(circle.Min.X, wy);
                    break;
                }
            }
            else if (qbc == Quadrant.NW)
            {
                switch (qec)
                {
                case Quadrant.NW:
                    win.Union(circle.Min.X, wy);
                    goto case Quadrant.SW;

                case Quadrant.SW:
                    win.Union(wx, circle.Min.Y);
                    goto case Quadrant.SE;

                case Quadrant.SE:
                    win.Union(circle.Max.X, wy);
                    goto case Quadrant.NE;

                case Quadrant.NE:
                    win.Union(wx, circle.Max.Y);
                    break;
                }
            }

            return(win);
        }
예제 #14
0
 public SpriteInfo(string spriteName, QuadVertex quad)
 {
     SpriteName = spriteName;
     Quad       = quad;
 }
예제 #15
0
        /// <summary>
        /// Intersect two circles. If there are two intersections,
        /// they are arranged so that the one with the lowest bearing comes first.
        /// </summary>
        /// <param name="a">The 1st circle</param>
        /// <param name="b">The 2nd circle</param>
        /// <param name="x1">The 1st intersection (if any).</param>
        /// <param name="x2">The 2nd intersection (if any).</param>
        /// <returns>The number of intersections found.</returns>
        internal static uint Intersect(ICircleGeometry a, ICircleGeometry b, out IPosition x1, out IPosition x2)
        {
            // Get the intersections (if any).
            uint nx = Geom.IntersectCircles(a.Center, a.Radius, b.Center, b.Radius, out x1, out x2);

            // Return if 0 or 1 intersection.
            if (nx<2)
                return nx;

            // Arrange the intersections so that the one with the lowest bearing comes first.
            QuadVertex q1x1 = new QuadVertex(a.Center, x1);
            QuadVertex q1x2 = new QuadVertex(a.Center, x2);
            QuadVertex q2x1 = new QuadVertex(b.Center, x1);
            QuadVertex q2x2 = new QuadVertex(b.Center, x2);

            double b1x1 = q1x1.BearingInRadians;
            double b1x2 = q1x2.BearingInRadians;
            double b2x1 = q2x1.BearingInRadians;
            double b2x2 = q2x2.BearingInRadians;

            // Switch if the min bearing to the 2nd intersection is actually
            // less than the min bearing to the 1st intersection.

            if (Math.Min(b1x2, b2x2) < Math.Min(b1x1, b2x1))
            {
                IPosition temp = x1;
                x1 = x2;
                x2 = temp;
            }

            return 2;
        }
예제 #16
0
        public static IWindow GetExtent(ICircularArcGeometry g)
        {
            // If the curve is a complete circle, just define it the easy way.
            if (g.BC.IsCoincident(g.EC))
                return CircleGeometry.GetExtent(g.Circle);

            IPosition bcp = g.BC;
            IPosition ecp = g.EC;
            IPosition centre = g.Circle.Center;

            // Initialize the window with the start location.
            Window win = new Window(bcp);

            // Expand using the end location
            win.Union(ecp);

            // If the curve is completely within one quadrant, we're done.
            QuadVertex bc = new QuadVertex(centre, bcp);
            QuadVertex ec = new QuadVertex(centre, ecp);

            Quadrant qbc = bc.Quadrant;
            Quadrant qec = ec.Quadrant;

            if (qbc == qec)
            {
                if (g.IsClockwise)
                {
                    if (bc.GetTanAngle() < ec.GetTanAngle())
                        return win;
                }
                else
                {
                    if (ec.GetTanAngle() < bc.GetTanAngle())
                        return win;
                }
            }

            // Get the window of the circle
            IWindow circle = CircleGeometry.GetExtent(g.Circle);

            // If the curve is anticlockwise, switch the quadrants for BC & EC
            if (!g.IsClockwise)
            {
                Quadrant temp = qbc;
                qbc = qec;
                qec = temp;
            }

            // Expand the window, depending on which quadrants the start &
            // end points fall in. The lack of breaks in the inner switches
            // is intentional (e.g. if start & end both fall in Quadrant.NorthEast,
            // the window we want is the complete circle, having checked above
            // for the case where the arc is JUST in Quadrant.NorthEast).

            // Define do-nothing values for the Union's below
            double wx = win.Min.X;
            double wy = win.Min.Y;

            if (qbc==Quadrant.NE)
            {
                switch (qec)
                {
                    case Quadrant.NE:
                        win.Union(wx, circle.Max.Y);
                        goto case Quadrant.NW;
                    case Quadrant.NW:
                        win.Union(circle.Min.X, wy);
                        goto case Quadrant.SW;
                    case Quadrant.SW:
                        win.Union(wx, circle.Min.Y);
                        goto case Quadrant.SE;
                    case Quadrant.SE:
                        win.Union(circle.Max.X, wy);
                        break;
                }
            }
            else if (qbc==Quadrant.SE)
            {
                switch (qec)
                {
                    case Quadrant.SE:
                        win.Union(circle.Max.X, wy);
                        goto case Quadrant.NE;
                    case Quadrant.NE:
                        win.Union(wx, circle.Max.Y);
                        goto case Quadrant.NW;
                    case Quadrant.NW:
                        win.Union(circle.Min.X, wy);
                        goto case Quadrant.SW;
                    case Quadrant.SW:
                        win.Union(wx, circle.Min.Y);
                        break;
                }
            }
            else if (qbc==Quadrant.SW)
            {
                switch (qec)
                {
                    case Quadrant.SW:
                        win.Union(wx, circle.Min.Y);
                        goto case Quadrant.SE;
                    case Quadrant.SE:
                        win.Union(circle.Max.X, wy);
                        goto case Quadrant.NE;
                    case Quadrant.NE:
                        win.Union(wx, circle.Max.Y);
                        goto case Quadrant.NW;
                    case Quadrant.NW:
                        win.Union(circle.Min.X, wy);
                        break;
                }
            }
            else if (qbc==Quadrant.NW)
            {
                switch (qec)
                {
                    case Quadrant.NW:
                        win.Union(circle.Min.X, wy);
                        goto case Quadrant.SW;
                    case Quadrant.SW:
                        win.Union(wx, circle.Min.Y);
                        goto case Quadrant.SE;
                    case Quadrant.SE:
                        win.Union(circle.Max.X, wy);
                        goto case Quadrant.NE;
                    case Quadrant.NE:
                        win.Union(wx, circle.Max.Y);
                        break;
                }
            }

            return win;
        }
예제 #17
0
        /// <summary>
        /// Checks an array of positions that purportedly correspond to a circular arc, to see
        /// whether the data is directed clockwise or not. No checks are made to confirm that
        /// the data really does correspond to a circular curve.
        /// </summary>
        /// <param name="pts">Positions on circular arc</param>
        /// <param name="center">The position of the centre of the circle that the curve lies on</param>
        /// <returns>True if the data is ordered clockwise.</returns>
        public static bool IsClockwise(IPosition[] pts, IPosition center)
        {
            if (pts.Length<2)
                return false;

            // To determine the direction, we must locate two successive
            // vertices that lie in the same quadrant (with respect to the
            // circle centre).

            QuadVertex start = new QuadVertex(center, pts[0]);
            QuadVertex end;

            for (int i=1; i<pts.Length; i++, start=end)
            {
                // Pick up the position at the end of the line segment
                end = new QuadVertex(center, pts[i]);

                // If both ends of the segment are in the same quadrant,
                // see which one comes first. The result tells us whether
                // the curve is clockwise or not.

                if (start.Quadrant == end.Quadrant)
                    return (start.GetTanAngle() < end.GetTanAngle() ? true : false);
            }

            // Something has gone wrong if we got here!
            Debug.Assert(1==2);
            return true;
        }
예제 #18
0
        // If the specified position isn't actually on the arc, the length is to the
        // position when it's projected onto the arc (i.e. the perpendicular position)
        public static ILength GetLength(ICircularArcGeometry g, IPosition asFarAs)
        {
            ICircleGeometry circle = g.Circle;
            double radius = circle.Radius;

            if (asFarAs == null)
            {
                // If the BC coincides with the EC, it's possible the arc has zero
                // length. As a matter of convention, counter-clockwise arcs will
                // be regarded as having a length of zero in that case. Meanwhile,
                // clockwise arcs will have a length that corresponds to the complete
                // circumference of the circle.

                if (g.BC.IsCoincident(g.EC))
                {
                    if (g.IsClockwise)
                        return CircleGeometry.GetLength(circle);
                    else
                        return Backsight.Length.Zero;
                }

                return new Length(radius * g.SweepAngleInRadians);
            }

            // Express the position of the BC in a local coordinate system.
            IPosition c = circle.Center;
            QuadVertex bc = new QuadVertex(c, g.BC, radius);

            // Calculate the clockwise angle to the desired point.
            QuadVertex to = new QuadVertex(c, asFarAs, radius);
            double ang = to.BearingInRadians - bc.BearingInRadians;
            if (ang<0.0)
                ang += MathConstants.PIMUL2;

            // If the curve is actually anti-clockwise, take the complement.
            if (!g.IsClockwise)
                ang = MathConstants.PIMUL2 - ang;

            return new Length(radius * ang);
        }
예제 #19
0
파일: Water.cs 프로젝트: kernelbitch/Lemma
        public override void LoadContent(bool reload)
        {
            this.effect = this.main.Content.Load<Effect>("Effects\\Water").Clone();
            this.effect.Parameters["NormalMap" + Model.SamplerPostfix].SetValue(this.main.Content.Load<Texture2D>("Images\\water-normal"));

            this.Color.Reset();
            this.Fresnel.Reset();
            this.Speed.Reset();
            this.RippleDensity.Reset();
            this.Distortion.Reset();
            this.Brightness.Reset();
            this.Clearness.Reset();
            this.UnderwaterColor.Reset();

            // Surface
            this.surfaceVertexBuffer = new VertexBuffer(this.main.GraphicsDevice, typeof(QuadVertex), Water.VertexDeclaration.VertexStride * 4, BufferUsage.None);
            QuadVertex[] surfaceData = new QuadVertex[4];

            // Upper right
            const float scale = 2000.0f;
            surfaceData[0].Position = new Vector3(scale, 0, scale);
            surfaceData[0].TexCoord = new Vector2(1, 0);

            // Upper left
            surfaceData[1].Position = new Vector3(-scale, 0, scale);
            surfaceData[1].TexCoord = new Vector2(0, 0);

            // Lower right
            surfaceData[2].Position = new Vector3(scale, 0, -scale);
            surfaceData[2].TexCoord = new Vector2(1, 1);

            // Lower left
            surfaceData[3].Position = new Vector3(-scale, 0, -scale);
            surfaceData[3].TexCoord = new Vector2(0, 1);

            surfaceData[0].Normal = surfaceData[1].Normal = surfaceData[2].Normal = surfaceData[3].Normal = new Vector3(0, 1, 0);

            this.surfaceVertexBuffer.SetData(surfaceData);

            // Underwater
            this.underwaterVertexBuffer = new VertexBuffer(this.main.GraphicsDevice, typeof(QuadVertex), Water.VertexDeclaration.VertexStride * 4, BufferUsage.None);

            QuadVertex[] underwaterData = new QuadVertex[4];

            // Upper right
            underwaterData[0].Position = new Vector3(1, 1, 1);
            underwaterData[0].TexCoord = new Vector2(1, 0);

            // Lower right
            underwaterData[1].Position = new Vector3(1, -1, 1);
            underwaterData[1].TexCoord = new Vector2(1, 1);

            // Upper left
            underwaterData[2].Position = new Vector3(-1, 1, 1);
            underwaterData[2].TexCoord = new Vector2(0, 0);

            // Lower left
            underwaterData[3].Position = new Vector3(-1, -1, 1);
            underwaterData[3].TexCoord = new Vector2(0, 1);

            underwaterData[0].Normal = underwaterData[1].Normal = underwaterData[2].Normal = underwaterData[3].Normal = new Vector3(0, 0, -1);

            this.underwaterVertexBuffer.SetData(underwaterData);

            this.resize();
        }
예제 #20
0
        /// <summary>
        /// Gets the most easterly position for this arc.
        /// </summary>
        /// <returns>The most easterly position</returns>
        internal override IPosition GetEastPoint()
        {
            // If the arc is a complete circle, just work it out the easy way.
            if (IsCircle)
                return m_Circle.GetEastPoint();

            // Determine where the east point is. It could be either the
            // BC, the EC, or the most easterly point of the circle.

            IPosition start = First;
            IPosition end = Second;
            char choice = (start.X > end.X ? 'S' : choice = 'E');

            // But hold on. If the arc passes from the northeast to southeast
            // quadrant, we want the east point of the circle.

            IPosition c = m_Circle.Center;
            QuadVertex vs = new QuadVertex(c, start);
            QuadVertex ve = new QuadVertex(c, end);

            Quadrant qs = vs.Quadrant;
            Quadrant qe = ve.Quadrant;

            // If the BC & EC are in the same quadrant, the only way the
            // circle point can apply is if it goes all the way round.
            if (!(qs==qe && vs.GetTanAngle()<ve.GetTanAngle()))
            {
                // Determine whether the circle point applies.
                switch (qs)
                {
                    case Quadrant.NE:
                    {
                        choice='C';
                        break;
                    }

                    case Quadrant.SE:
                        break;

                    case Quadrant.SW:
                    {
                        if (qe==Quadrant.SE)
                            choice = 'C';

                        break;
                    }

                    case Quadrant.NW:
                    {
                        if (qe!=Quadrant.NE)
                            choice = 'C';

                        break;
                    }
                }
            }

            if (choice=='S')
                return start;
            else if (choice=='E')
                return end;

            Debug.Assert(choice=='C');
            return m_Circle.GetEastPoint();
        }