private void SetVertices(Vector2D[] vertices) { #if DEBUG if (vertices == null) { throw new ArgumentNullException(nameof(vertices)); } if (vertices.Length < 3) { throw new ArgumentOutOfRangeException(nameof(vertices)); } // 验证定点是否顺时针方向 // 验证定点是否为凸包 #endif this.vertices = vertices; // 计算法线,并验证不存在长度为0的边 normals = new Vector2D[vertices.Length]; for (var i = 0; i < vertices.Length; ++i) { int inext = i + 1 < vertices.Length ? i + 1 : 0; var edge = vertices[inext] - vertices[i]; Debug.Assert(edge.LengthSquared() > float.Epsilon * float.Epsilon); var normal = Vector2D.Cross(edge, 1.0f); normal.Normalize(); normals[i] = normal; } }
private static void RefExtensionMethods() { var p = new Vector2D(1, 2); var q = new Vector2D(3, 4); Console.WriteLine(p.Dot(q)); Console.WriteLine(p.Cross(q)); }
public void CrossProduct() { Random Rand = new Random(); Vector2D TestVector2D1 = new Vector2D(Rand.NextDouble() * 1000, Rand.NextDouble() * 1000); Vector2D TestVector2D2 = new Vector2D(Rand.NextDouble() * 1000, Rand.NextDouble() * 1000); double Cross2D = TestVector2D1.Cross(TestVector2D2); Vector3D TestVector3D1 = new Vector3D(TestVector2D1.x, TestVector2D1.y, 0); Vector3D TestVector3D2 = new Vector3D(TestVector2D2.x, TestVector2D2.y, 0); Vector3D Cross3D = TestVector3D1.Cross(TestVector3D2); Assert.IsTrue(Cross3D.z == Cross2D); }
private List <Rectangle2D> GetRecrangle(List <Vector2D> points) { List <Rectangle2D> rectangles = new List <Rectangle2D>(); Vector2D floorLocalCoord = GetBasicDirection()[0]; Vector2D GlobalCoord = new Vector2D(1, 0); double xiTa = 0; if (floorLocalCoord.Dot(GlobalCoord) > 0 && GlobalCoord.Cross(floorLocalCoord) < 0) { xiTa = GlobalCoord.AngleWith(floorLocalCoord); } else if (floorLocalCoord.Dot(GlobalCoord) < 0 && GlobalCoord.Cross(-floorLocalCoord) < 0) { xiTa = GlobalCoord.AngleWith(floorLocalCoord); } else if (floorLocalCoord.Dot(GlobalCoord) > 0 && GlobalCoord.Cross(floorLocalCoord) > 0) { xiTa = Math.PI / 2 - GlobalCoord.AngleWith(floorLocalCoord); } else if (floorLocalCoord.Dot(GlobalCoord) < 0 && GlobalCoord.Cross(-floorLocalCoord) > 0) { xiTa = Math.PI / 2 - GlobalCoord.AngleWith(floorLocalCoord); } points.ForEach(x => x.X = Math.Floor(x.X * 1e9) / 1e9); points.ForEach(x => x.Y = Math.Floor(x.Y * 1e9) / 1e9); List <Vector2D> newCoord = new List <Vector2D>(); points.ForEach(x => newCoord.Add(CoordTransform(x, xiTa))); List <double> newXCoord = new List <double>(); List <double> newYCoord = new List <double>(); newCoord.ForEach(x => { newXCoord.Add(x.X); newYCoord.Add(x.Y); }); newXCoord = newXCoord.Distinct().OrderBy(x => x).ToList(); newYCoord = newYCoord.Distinct().OrderBy(y => y).ToList(); for (int i = 0; i < newXCoord.Count - 1; i++) { for (int j = 0; j < newYCoord.Count - 1; j++) { Vector2D p1 = new Vector2D(newXCoord[i], newYCoord[j]); Vector2D p2 = new Vector2D(newXCoord[i + 1], newYCoord[j]); Vector2D p3 = new Vector2D(newXCoord[i + 1], newYCoord[j + 1]); Vector2D p4 = new Vector2D(newXCoord[i], newYCoord[j + 1]); p1 = CoordTransform(p1, -xiTa); p2 = CoordTransform(p2, -xiTa); p3 = CoordTransform(p3, -xiTa); p4 = CoordTransform(p4, -xiTa); Rectangle2D rec = new Rectangle2D(p1, p2, p3, p4); rectangles.Add(rec); } } return(rectangles); }
private void multipleArcVertices(ArcPoint point, Vector2D facing, List <float> outputData) { var circle = point.Parent.Parent; var left = point.EdgeFacing * circle.Radius; var right = point.EdgeFacing * point.EdgeFacing.Dot(point.Point); var top = point.Parent.Parent.Radius * (point.RightEnd ? point.EdgeFacing.PerpendicularRight : point.EdgeFacing.PerpendicularLeft); var endShape = new LinkedList <Vector2D>(new[] { right + top, right, left, left + top, }); var facingNormal = point.RightEnd ? facing.PerpendicularRight : facing.PerpendicularLeft; for (var current = endShape.First; current != null; /* no step */) { var next = current.Next ?? endShape.First; var added = false; if ((current.Value.Dot(facingNormal) < DotLimit) != (next.Value.Dot(facingNormal) < DotLimit)) { var line = next.Value - current.Value; var height = current.Value.Dot(facingNormal); var speed = -height / line.Dot(facingNormal); endShape.AddAfter(current, current.Value + line * speed); added = true; } if (current.Value.Dot(facingNormal) < DotLimit) { var realNext = current.Next; endShape.Remove(current); current = realNext; } else { current = current.Next; } if (added) { current = current.Next; } } var triangles = new List <Vector2D[]>(); for (var current = endShape.First.Next.Next; current != null; current = current.Next) { triangles.Add(makeTriangle(endShape.First.Value, current.Previous.Value, current.Value)); } var facingSide = facing.Cross(point.EdgeFacing); if (point.RightEnd && facingSide < 0 || !point.RightEnd && facingSide > 0) { triangles.Add(makeTriangle(new Vector2D(0, 0), facing * circle.Radius * 1.5f, point.EdgeFacing * circle.Radius * 1.5f)); } outputData.AddRange(triangles.SelectMany(x => x).SelectMany(x => orbitVertex(x))); }
private static bool LeftTurn(Vector2D p1, Vector2D p2, Vector2D p3) { return(Vector2D.Cross(p2 - p1, p3 - p1) < 0); }