public async Task EnumerateParallel(MyVector2 areaSizing, Action <MyColor[][], int, int, int> action, CancellationToken ct) { await Task.Run(() => Parallel.For(0, _sprites.Length, (index, loopState) => { if (ct.IsCancellationRequested) { loopState.Break(); } EnumerateThroughSprite(areaSizing, index, action); })); }
private MyVector2 Compute2D(MyVector3 point) { if (this.glProjector == null) { this.ObtainGLProjector(); } MyVector2 pt2 = this.glProjector.Project(point).ToMyVector2(); pt2.y = this.view.Height - pt2.y; return(pt2); }
public bool isExist(MyVector2 position, List <MyVector2> collections) { foreach (MyVector2 data in collections) { if (data.x == position.x && data.y == position.y) { return(true); } } return(false); }
//Help method to calculate the average normal of two line segments private static MyVector2 GetAverageNormal(MyVector2 a, MyVector2 b, MyVector2 c) { MyVector2 normal_1 = GetNormal(a, b); MyVector2 normal_2 = GetNormal(b, c); MyVector2 averageNormal = (normal_1 + normal_2) * 0.5f; averageNormal = MyVector2.Normalize(averageNormal); return(averageNormal); }
private MyVector2 GetCurvePointTagent(int i, double t) { MyVector2 b0 = inputPoints[i]; MyVector2 b1 = 2 * B[i] / 3.0 + B[i + 1] / 3.0; MyVector2 b2 = B[i] / 3.0 + 2 * B[i + 1] / 3.0;; MyVector2 b3 = inputPoints[i + 1]; double dt = 1.0 - t; double t0 = -dt * dt * 3, t1 = 3 * (-2 * dt * t + dt * dt), t2 = 3 * (-t * t + 2 * t * dt), t3 = 3 * t * t; return(t0 * b0 + t1 * b1 + t2 * b2 + t3 * b3); }
private void CenterOfCircle(MyVector2 a, MyVector2 b, MyVector2 c) { MyVector2 center = _Geometry.CalculateCircleCenter(a, b, c); //MyVector2 center = _Geometry.CalculateCircleCenter_Alternative2(a, b, c); //Debug.Log(center.x + " " + center.y); float radius = Vector3.Magnitude(a.ToVector3() - center.ToVector3()); Gizmos.DrawWireSphere(center.ToVector3(), radius); }
private MyVector2 GetCurvePoint(int i, double t) { MyVector2 b0 = inputPoints[i]; MyVector2 b1 = 2 * B[i] / 3.0 + B[i + 1] / 3.0; MyVector2 b2 = B[i] / 3.0 + 2 * B[i + 1] / 3.0; MyVector2 b3 = inputPoints[i + 1]; double dt = 1.0 - t; double t0 = dt * dt * dt, t1 = 3 * dt * dt * t, t2 = 3 * dt * t * t, t3 = t * t * t; return(t0 * b0 + t1 * b1 + t2 * b2 + t3 * b3); }
//Is a point intersecting with a circle? private void PointCircle() { MyVector2 testPoint = pointTrans.position.ToMyVector2(); MyVector2 circlePointA = t1_p1_trans.position.ToMyVector2(); MyVector2 circlePointB = t1_p2_trans.position.ToMyVector2(); MyVector2 circlePointC = t1_p3_trans.position.ToMyVector2(); //Is a point in a circle determines by three other points IntersectionCases intersectionCases = _Intersections.PointCircle(circlePointA, circlePointB, circlePointC, testPoint); //print(isPointInCircle); //Display the circle //if (intersectionCases == IntersectionCases.NoIntersection) //{ // Gizmos.color = Color.white; //} //if (intersectionCases == IntersectionCases.IsInside) //{ // Gizmos.color = Color.red; //} //if (intersectionCases == IntersectionCases.IsOnEdge) //{ // Gizmos.color = Color.blue; //} MyVector2 centerOfCicle = _Geometry.CalculateCircleCenter(circlePointA, circlePointB, circlePointC); float radius = MyVector2.Distance(centerOfCicle, circlePointA); //Gizmos.DrawWireSphere(centerOfCicle.ToVector3(), radius); ////Display the points //float pointRadius = 0.2f; //Gizmos.DrawWireSphere(pointTrans.position, pointRadius); //Gizmos.DrawWireSphere(t1_p1_trans.position, pointRadius); //Gizmos.DrawWireSphere(t1_p2_trans.position, pointRadius); //Gizmos.DrawWireSphere(t1_p3_trans.position, pointRadius); //With mesh //Big circle TestAlgorithmsHelpMethods.DisplayCircleMesh(centerOfCicle, radius, 60, Color.white); //Small circle Color circleColor = (intersectionCases == IntersectionCases.IsInside) ? Color.red : Color.white; TestAlgorithmsHelpMethods.DisplayCircleMesh(testPoint, 1f, 20, circleColor); }
/*** calculate the distance from a given point to the line ***/ public double GetDistance(MyVector2 point) { double x0 = point.x; double y0 = point.y; double d = Math.Abs(a * x0 + b * y0 + c); d = d / (Math.Sqrt(a * a + b * b)); return(d); }
/********************************************************** * Get point location, using windows coordinate system: * y-axes points down. * Return Value: * -1:point at the left of the line (or above the line if the line is horizontal) * 0: point in the line segment or in the line segment 's extension * 1: point at right of the line (or below the line if the line is horizontal) ***********************************************************/ public int GetPointLocation(MyVector2 point) { double Ax, Ay, Bx, By, Cx, Cy; Bx = m_endPoint.x; By = m_endPoint.y; Ax = m_startPoint.x; Ay = m_startPoint.y; Cx = point.x; Cy = point.y; if (this.HorizontalLine()) { if (Math.Abs(Ay - Cy) < CPolygon.thresh) //equal { return(0); } else if (Ay > Cy) { return(-1); //y Axis points down, point is above the line } else //Ay<Cy { return(1); //y Axis points down, point is below the line } } else //Not a horizontal line { //make the line direction bottom->up if (m_endPoint.y > m_startPoint.y) { this.ChangeLineDirection(); } double L = this.GetLineSegmentLength(); double s = ((Ay - Cy) * (Bx - Ax) - (Ax - Cx) * (By - Ay)) / (L * L); //Note: the y axis is pointing down: if (Math.Abs(s - 0) < CPolygon.thresh) //s=0 { return(0); //point is in the line or line extension } else if (s > 0) { return(-1); //point is left of line or above the horizontal line } else //s<0 { return(1); } } }
/// <summary> /// Creates a matrix that is scaling from a specified center. /// </summary> /// <param name="x">Scaling factor that is applied along the x-axis.</param> /// <param name="y">Scaling factor that is applied along the y-axis.</param> /// <param name="center">The center of the scaling.</param> /// <param name="result">The created scaling matrix.</param> public static void Scaling(float x, float y, ref MyVector2 center, out MyMatrix3x2 result) { MyMatrix3x2 localResult; localResult.M11 = x; localResult.M12 = 0.0f; localResult.M21 = 0.0f; localResult.M22 = y; localResult.M31 = center.X - (x * center.X); localResult.M32 = center.Y - (y * center.Y); result = localResult; }
/// <summary> /// Creates a matrix that is scaling from a specified center. /// </summary> /// <param name="x">Scaling factor that is applied along the x-axis.</param> /// <param name="y">Scaling factor that is applied along the y-axis.</param> /// <param name="center">The center of the scaling.</param> /// <returns>The created scaling matrix.</returns> public static MyMatrix3x2 Scaling(float x, float y, MyVector2 center) { MyMatrix3x2 result; result.M11 = x; result.M12 = 0.0f; result.M21 = 0.0f; result.M22 = y; result.M31 = center.X - (x * center.X); result.M32 = center.Y - (y * center.Y); return(result); }
public static void DrawCross2D(MyVector2 p, float size, Color c) { GL.Color3(c.R, c.G, c.B); GL.LineWidth(2.0f); GL.Begin(PrimitiveType.Lines); GL.Vertex2(p.x - size, p.y - size); GL.Vertex2(p.x + size, p.y + size); GL.Vertex2(p.x + size, p.y - size); GL.Vertex2(p.x - size, p.y + size); GL.End(); GL.LineWidth(1.0f); }
/********************************************* * To check whether a given point is a CPolygon Vertex **********************************************/ public bool PolygonVertex(MyVector2 point) { bool bVertex = false; int nIndex = VertexIndex(point); if ((nIndex >= 0) && (nIndex <= m_aVertices.Length - 1)) { bVertex = true; } return(bVertex); }
public void EnumerateCopy(MyVector2 areaDimensions, Action <MyColor[][], int, int, int> action) { var copy = CopyArrayOf(_sprites); for (int i = 0; i < copy.Length; i++) { enumerateThroughSprite(areaDimensions, copy[i], i, action); } //for (int x = 0; x < copy[i].Length; x++) // for (int y = 0; y < copy[i][x].Length; y++) // action(copy[i], x, y); }
//Calculate the angle between Vector a and b both originating from c private void AngeBetweenVectors(MyVector2 a, MyVector2 b, MyVector2 c) { Gizmos.DrawLine(pointCTrans.position, pointATrans.position); Gizmos.DrawLine(pointCTrans.position, pointBTrans.position); MyVector2 from = a - c; MyVector2 to = b - c; float angle = MathUtility.AngleFromToCCW(from, to); Debug.Log(angle * Mathf.Rad2Deg); }
public void ViewingMouseWheel(MyVector2 mousepos, System.Windows.Forms.MouseEventArgs e) { this.arcBall.Click(mousepos / scaleRatio, Trackball.MotionType.Scale); mousepos += mousepos * 0.6 * e.Delta; this.arcBall.Drag(mousepos / scaleRatio); MyMatrix4d ms = this.arcBall.GetMatrix(); this.modelTransformation = ms * this.modelTransformation; this.arcBall.End(); this.ObtainGLProjector(); this.Update2D(); }
//Generate circle meshes for delaunay based in 3 points in a triangle, where d is the opposite vertex public void GenerateDelaunayCircleMeshes(MyVector2 a, MyVector2 b, MyVector2 c, MyVector2 d) { //Remove all old meshes ClearBlackMeshes(); //Unnormalize the points a = HelpMethods.UnNormalize(a, normalizingBox, dMax); b = HelpMethods.UnNormalize(b, normalizingBox, dMax); c = HelpMethods.UnNormalize(c, normalizingBox, dMax); d = HelpMethods.UnNormalize(d, normalizingBox, dMax); //Generate the triangles //Big circle MyVector2 center = Geometry.CalculateCircleCenter(a, b, c); float radius = MyVector2.Distance(center, a); HashSet <Triangle2> allTriangles = GenerateMesh.CircleHollow(center, radius, 100, 0.1f); //Circles showing the 4 points float circleMeshRadius = 0.3f; HashSet <Triangle2> circle_a = GenerateMesh.Circle(a, circleMeshRadius, 10); HashSet <Triangle2> circle_b = GenerateMesh.Circle(b, circleMeshRadius, 10); HashSet <Triangle2> circle_c = GenerateMesh.Circle(c, circleMeshRadius, 10); HashSet <Triangle2> circle_d = GenerateMesh.Circle(d, circleMeshRadius, 10); //Similar to List's add range allTriangles.UnionWith(circle_a); allTriangles.UnionWith(circle_b); allTriangles.UnionWith(circle_c); allTriangles.UnionWith(circle_d); //Active edge is a-c HashSet <Triangle2> activeEdgeMesh = GenerateMesh.LineSegment(a, c, 0.2f); allTriangles.UnionWith(activeEdgeMesh); //Generate meshes foreach (Triangle2 t in allTriangles) { Mesh triangleMesh = Triangle2ToMesh(t, 0.1f); blackMeshes.Add(triangleMesh); } }
public void SamplePoints(double dis_thres) { // get sample points w.r.t. the distance threshold // a ||s_i-s_i+1|| < dis_thres is required this.sampledPoints_ = new List <MyVector2>(); this.sampledPointsTangents_ = new List <MyVector2>(); for (int i = 0; i < this.numOfPoints - 1; ++i) { double len = (this.inputPoints[i + 1] - this.inputPoints[i]).Length(); int npointsPerSegment = (int)(len / dis_thres); bool stop = false; while (!stop) { stop = true; List <MyVector2> points = new List <MyVector2>(); List <MyVector2> pointsTagent = new List <MyVector2>(); for (int j = 0; j < npointsPerSegment; ++j) { double t1 = (double)j / npointsPerSegment; double t2 = (double)(j + 1) / npointsPerSegment; MyVector2 p1 = this.GetCurvePoint(i, t1); MyVector2 p2 = this.GetCurvePoint(i, t2); if ((p2 - p1).Length() > dis_thres) { stop = false; npointsPerSegment++; break; } MyVector2 pt1 = this.GetCurvePointTagent(i, t1); points.Add(p1); pointsTagent.Add(pt1); } if (stop == true) { this.sampledPoints_.AddRange(points); this.sampledPointsTangents_.AddRange(pointsTagent); } } } // end point this.sampledPoints_.Add(this.GetCurvePoint(this.numOfPoints - 2, 1)); this.sampledPointsTangents_.Add(this.GetCurvePointTagent(this.numOfPoints - 2, 1)); // get normals this.GetSamplePointsNormals(); }
// // Arrow // public static HashSet <Triangle2> Arrow(MyVector2 p1, MyVector2 p2, float lineWidth, float arrowSize) { HashSet <Triangle2> arrowTriangles = new HashSet <Triangle2>(); //An arrow consists of two parts: the pointy part and the rectangular part //First we have to see if we can fit the parts MyVector2 lineDir = p2 - p1; float lineLength = MyVector2.Magnitude(lineDir); if (lineLength < arrowSize) { Debug.Log("Cant make arrow because line is too short"); return(null); } //Make the arrow tip MyVector2 lineDirNormalized = MyVector2.Normalize(lineDir); MyVector2 arrowBottom = p2 - lineDirNormalized * arrowSize; MyVector2 lineNormal = MyVector2.Normalize(new MyVector2(lineDirNormalized.y, -lineDirNormalized.x)); MyVector2 arrowBottom_R = arrowBottom + lineNormal * arrowSize * 0.5f; MyVector2 arrowBottom_L = arrowBottom - lineNormal * arrowSize * 0.5f; Triangle2 arrowTipTriangle = new Triangle2(p2, arrowBottom_R, arrowBottom_L); arrowTriangles.Add(arrowTipTriangle); //Make the arrow rectangle float halfWidth = lineWidth * 0.5f; MyVector2 p1_T = p1 + lineNormal * halfWidth; MyVector2 p1_B = p1 - lineNormal * halfWidth; MyVector2 p2_T = arrowBottom + lineNormal * halfWidth; MyVector2 p2_B = arrowBottom - lineNormal * halfWidth; HashSet <Triangle2> rectangle = LineSegment(p1_T, p1_B, p2_T, p2_B); foreach (Triangle2 t in rectangle) { arrowTriangles.Add(t); } return(arrowTriangles); }
//Is a plane intersecting with a plane private void PlanePlane() { Vector3 planeNormal_1 = planeTrans.forward; Vector3 planePos_1 = planeTrans.position; Vector3 planeNormal_2 = rayTrans.forward; Vector3 planePos_2 = rayTrans.position; //3d to 2d MyVector2 normal_1 = planeNormal_1.ToMyVector2(); MyVector2 normal_2 = planeNormal_2.ToMyVector2(); MyVector2 pos1 = planePos_1.ToMyVector2(); MyVector2 pos2 = planePos_2.ToMyVector2(); Plane2 plane_1 = new Plane2(pos1, normal_1); Plane2 plane_2 = new Plane2(pos2, normal_2); //Intersections bool isIntersecting = _Intersections.PlanePlane(plane_1, plane_2); Debug.Log("Are planes intersecting: " + isIntersecting); //Display //if (isIntersecting) //{ // MyVector2 intersectionPoint = Intersections.GetPlanePlaneIntersectionPoint(pos1, normal_1, pos2, normal_2); // Gizmos.DrawWireSphere(intersectionPoint.ToVector3(), 0.2f); //} //Color planeColor = isIntersecting ? Color.red : Color.white; //TestAlgorithmsHelpMethods.DrawPlane(pos1, normal_1, planeColor); //TestAlgorithmsHelpMethods.DrawPlane(pos2, normal_2, planeColor); //Display with mesh TestAlgorithmsHelpMethods.DisplayPlaneMesh(pos1, normal_1, 0.5f, Color.blue); TestAlgorithmsHelpMethods.DisplayPlaneMesh(pos2, normal_2, 0.5f, Color.blue); if (isIntersecting) { MyVector2 intersectionPoint = _Intersections.GetPlanePlaneIntersectionPoint(plane_1, plane_2); TestAlgorithmsHelpMethods.DisplayCircleMesh(intersectionPoint, 1f, 20, Color.red); } }
MyVector2 Get_B(MyVector2[] p, int n, float t) { if (n == 1) { return(p[0]); } MyVector2[] backup = new MyVector2[n - 1]; for (int i = 0; i < n - 1; i++) { backup[i] = (1 - t) * p[i] + t * p[i + 1]; } return(Get_B(backup, n - 1, t)); }
//Generate two triangles if we know the corners of the rectangle public static HashSet <Triangle2> LineSegment(MyVector2 p1_T, MyVector2 p1_B, MyVector2 p2_T, MyVector2 p2_B) { HashSet <Triangle2> lineTriangles = new HashSet <Triangle2>(); //Create the triangles Triangle2 t1 = new Triangle2(p1_T, p1_B, p2_T); Triangle2 t2 = new Triangle2(p1_B, p2_B, p2_T); lineTriangles.Add(t1); lineTriangles.Add(t2); return(lineTriangles); }
private MyVector2 GetMarkCenter2dPixel(List <MyVector2> bPoints, double CircleDistance) { offset = 1.0 / (Compute2D(new MyVector3(1, 0, CircleDistance)) - Compute2D(new MyVector3(0, 0, CircleDistance))).x; MyVector2 pic_c = Compute2D(new MyVector3(0, 0, CircleDistance)); MyVector2 c = new MyVector2(0, 0); for (int i = 0; i < bPoints.Count; i++) { c += bPoints[i]; } c = c / bPoints.Count; return(c); }
//Help method to calculate the intersection point between two planes offset in normal direction by a width private static MyVector2 GetIntersectionPoint(MyVector2 a, MyVector2 b, MyVector2 c, float halfWidth, bool isTopPoint) { //Direction of the lines going to and from point b MyVector2 beforeDir = MyVector2.Normalize(b - a); MyVector2 afterDir = MyVector2.Normalize(c - b); MyVector2 beforeNormal = GetNormal(a, b); MyVector2 afterNormal = GetNormal(b, c); //Compare the normals! //normalDirFactor is used to determine if we want to top point (same direction as normal) float normalDirFactor = isTopPoint ? 1f : -1f; //If they are the same it means we have a straight line and thus we cant do plane-plane intersection //if (beforeNormal.Equals(afterNormal)) //When comparing the normals, we cant use the regular small value because then //the line width goes to infinity when doing plane-plane intersection float dot = MyVector2.Dot(beforeNormal, afterNormal); //Dot is 1 if the point in the same dir and -1 if the point in the opposite dir float one = 1f - 0.01f; if (dot > one || dot < -one) { MyVector2 averageNormal = MyVector2.Normalize((afterNormal + beforeNormal) * 0.5f); MyVector2 intersectionPoint = b + averageNormal * halfWidth * normalDirFactor; return(intersectionPoint); } else { //Now we can calculate where the plane starts MyVector2 beforePlanePos = b + beforeNormal * halfWidth * normalDirFactor; MyVector2 afterPlanePos = b + afterNormal * halfWidth * normalDirFactor; Plane2 planeBefore = new Plane2(beforePlanePos, beforeNormal); Plane2 planeAfter = new Plane2(afterPlanePos, afterNormal); //Calculate the intersection point //We know they are intersecting, so we don't need to test that MyVector2 intersectionPoint = _Intersections.GetPlanePlaneIntersectionPoint(planeBefore, planeAfter); return(intersectionPoint); } }
//Generate list of meshes from the Triangle2 data structure public List <Mesh> GenerateTriangulationMesh(HashSet <Triangle2> triangleData, bool shouldUnNormalize) { //Unnormalize HashSet <Triangle2> triangles_2d = new HashSet <Triangle2>(); if (shouldUnNormalize) { foreach (Triangle2 t in triangleData) { //Each face has in this case three edges MyVector2 p1 = t.p1; MyVector2 p2 = t.p2; MyVector2 p3 = t.p3; //Unnormalize the point p1 = normalizer.UnNormalize(p1); p2 = normalizer.UnNormalize(p2); p3 = normalizer.UnNormalize(p3); Triangle2 t_unnormalized = new Triangle2(p1, p2, p3); triangles_2d.Add(t_unnormalized); } } else { triangles_2d = triangleData; } //Make sure the triangles have the correct orientation //triangles_2d = HelpMethods.OrientTrianglesClockwise(triangles_2d); //From 2d to mesh in one step if we want one single mesh //Mesh displayMesh = _TransformBetweenDataStructures.Triangles2ToMesh(triangles_2d, useCompressedMesh: false); //Generate the meshes from triangles List <Mesh> meshes = new List <Mesh>(); foreach (Triangle2 t in triangles_2d) { Mesh triangleMesh = Triangle2ToMesh(t); meshes.Add(triangleMesh); } return(meshes); }
//Find all triangles opposite of vertex p //But we will find all edges opposite to p, and from these edges we can find the triangles private static void AddTrianglesOppositePToStack(MyVector2 p, Stack <HalfEdge2> trianglesOppositeP, HalfEdgeData2 triangulationData) { //Find a vertex at position p and then rotate around it, triangle-by-triangle, to find all opposite edges HalfEdgeVertex2 rotateAroundThis = null; foreach (HalfEdgeVertex2 v in triangulationData.vertices) { if (v.position.Equals(p)) { rotateAroundThis = v; } } //Which triangle is this vertex a part of, so we know when we have rotated all the way around HalfEdgeFace2 tStart = rotateAroundThis.edge.face; HalfEdgeFace2 tCurrent = null; int safety = 0; while (tCurrent != tStart) { safety += 1; if (safety > 10000) { Debug.Log("Stuck in endless loop when finding opposite edges in Delaunay Sloan"); break; } //The edge opposite to p HalfEdge2 edgeOppositeRotateVertex = rotateAroundThis.edge.nextEdge.oppositeEdge; //Try to add the edge to the list iof triangles we are interested in //Null might happen if we are at the border //A stack might include duplicates so we have to check for that as well if (edgeOppositeRotateVertex != null && !trianglesOppositeP.Contains(edgeOppositeRotateVertex)) { trianglesOppositeP.Push(edgeOppositeRotateVertex); } //Rotate left - this assumes we can always rotate left so no holes are allowed //and neither can we investigate one of the vertices thats a part of the supertriangle //which we dont need to worry about because p is never a part of the supertriangle rotateAroundThis = rotateAroundThis.edge.oppositeEdge.v; //In which triangle are we now? tCurrent = rotateAroundThis.edge.face; } }
public static void DrawRectFill(MyVector2 start, MyVector2 end, Color c) { GL.PushMatrix(); GL.LoadIdentity(); GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Fill); GL.Color3(c.R, c.G, c.B); GL.Rect(start.x, start.y, end.x, end.y); GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Fill); GL.PopMatrix(); }
public static void DrawCross2DPlus(MyVector2 p, float size, Color c, float linewidth = 2.0f) { GL.Color3(c.R, c.G, c.B); GL.LineWidth(linewidth); GL.Begin(PrimitiveType.Lines); GL.Vertex2(p.x - size, p.y); GL.Vertex2(p.x + size, p.y); GL.Vertex2(p.x, p.y - size); GL.Vertex2(p.x, p.y + size); GL.End(); GL.LineWidth(1.0f); DrawRect(p - new MyVector2(size, size), p + new MyVector2(size, size), Color.Gray); }
//Triangle public static void DisplayTriangleMesh(MyVector2 a, MyVector2 b, MyVector2 c, Color color) { Triangle2 t = new Triangle2(a, b, c); HashSet <Triangle2> triangles = new HashSet <Triangle2>(); triangles.Add(t); triangles = HelpMethods.OrientTrianglesClockwise(triangles); Mesh mesh = _TransformBetweenDataStructures.Triangles2ToMesh(triangles, false); TestAlgorithmsHelpMethods.DisplayMesh(mesh, color); }
public void setPathSquare(int row, int column, int adjustX, int adjustY, Direction a) { sequence = new MyVector2(row, column); nextSequence = new MyVector2(row + adjustX, column + adjustY); direction = a; }