/// <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); }
/// <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); }
/// <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); }
/// <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); }
/// <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); } }
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); }
// 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)); }
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); }
/// <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()); }
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); }
/// <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; }
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); }
public SpriteInfo(string spriteName, QuadVertex quad) { SpriteName = spriteName; Quad = quad; }
/// <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; }
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; }
/// <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; }
// 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); }
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(); }
/// <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(); }