/// <summary> /// </summary> /// <param name="walls"></param> /// <param name="y"></param> /// <returns></returns> public static List <Vector3> GetDistinctPositions3D(List <Wall> walls, float y = 0) { var positions = GetDistinctPositions(walls); var positions3D = new List <Vector3>(); foreach (var pos in positions) { positions3D.Add(VectorFunctions.Switch2D3D(pos, y)); } return(positions3D); }
/// <summary> /// Draw a wall w with extremities start and end /// </summary> /// <param name="start"></param> /// <param name="end"></param> /// <param name="w"></param> /// <returns></returns> public static List <Vector3> MakeGraphicalWall(Vector3 start, Vector3 end, Wall w) { // min 10 cm wall length if (Vector3.Distance(start, end) < 0.1f) { return(new List <Vector3>()); } var isCommonP1 = false; var isCommonP2 = false; var center = (start + end) / 2; var wdir = (end - start).normalized; var perp = new Vector3(wdir.y, -wdir.x); // rectangle a b d c var a = start - perp * w.Thickness / 2; var c = start + perp * w.Thickness / 2; var b = end - perp * w.Thickness / 2; var d = end + perp * w.Thickness / 2; Vector3[] v1 = null; Vector3[] v2 = null; // TRAPEZES if (start == w.P1 && w.linkedP1.Count == 1) { var common = GetCommonPosition(w, w.linkedP1[0]); var angle0 = GetAngleBetweenWalls(w, w.linkedP1[0]); isCommonP1 = common == w.P1; if (common != Vector3.positiveInfinity && angle0 != 0 && angle0 < 179 && angle0 > -179) { //Debug.Log("V1 ANGLE " + angle0); v1 = GetVerticesToStickWalls(w, w.linkedP1[0]); } // retour => new Vector3[] { f, g, b, d }; } if (end == w.P2 && w.linkedP2.Count == 1) { var common = GetCommonPosition(w, w.linkedP2[0]); var angle0 = GetAngleBetweenWalls(w, w.linkedP2[0]); isCommonP2 = common == w.P2; if (common != Vector3.positiveInfinity && angle0 != 0 && angle0 < 179 && angle0 > -179) { //Debug.Log("V2 ANGLE " + angle0); v2 = GetVerticesToStickWalls(w, w.linkedP2[0]); } // retour => new Vector3[] { a, c, f, g }; } ////////// ADD THICKNESS IF SEVERAL LINKED ////////if(start == w.P1 && w.linkedP1.Count > 1) ////////{ //////// Vector3 common = WallFunctions.GetCommonPosition(w, w.linkedP1[0]); //////// float angle0 = WallFunctions.GetAngleBetweenWalls(w, w.linkedP1[0]); //////// isCommonP1 = common == w.P1; //////// if(common != Vector3.zero && angle0 != 0 && angle0 != 180 && angle0 != -180) //////// { //////// var decal = w.Direction * w.linkedP1[0].Thickness / 2f; //////// v1 = new Vector3[] {a+decal,c+decal,b,d}; //////// } ////////} ////////if (end == w.P2 && w.linkedP2.Count > 1) ////////{ //////// Vector3 common = WallFunctions.GetCommonPosition(w, w.linkedP2[0]); //////// float angle0 = WallFunctions.GetAngleBetweenWalls(w, w.linkedP2[0]); //////// isCommonP2 = common == w.P2; //////// if (common != Vector3.zero && angle0 != 0 && angle0 != 180 && angle0 != -180) //////// { //////// var decal = w.Direction * w.linkedP2[0].Thickness / 2f; //////// v2 = new Vector3[] { a, c , b + decal, d + decal }; //////// } ////////} if (v1 != null) { a = v1[0]; c = v1[1]; //Debug.Log("f = " + a); } if (v2 != null) { b = v2[2]; d = v2[3]; //Debug.Log("f = " + b); } // relative a -= center; b -= center; c -= center; d -= center; // rotation Quaternion rotation; Quaternion rotation3D; if (wdir == Vector3.left) { rotation = Quaternion.identity; rotation3D = Quaternion.identity; } else { rotation = Quaternion.FromToRotation(Vector3.right, wdir); rotation3D = Quaternion.FromToRotation(Vector3.up, wdir); } var invRot = Quaternion.Inverse(rotation); var invRot3D = Quaternion.Inverse(rotation3D); var a2 = invRot * a; var b2 = invRot * b; var c2 = invRot * c; var d2 = invRot * d; // =========== 2D PART =========== // 4 vertices to adjust, according to thickness and position var new2DVertices = new List <Vector3> { a2, b2, c2, d2 }; var custTriangles2D = new List <Vector3> { a2, b2, d2, a2, d2, c2 }; var poly = new Polygon2D(new GameObject("Wall2D"), custTriangles2D, w.Color).Build(); w.walls2D.Add(poly); poly.gameObject.transform.parent = w.associated2DObject.transform; poly.gameObject.layer = (int)ErgoLayers.Top; poly.gameObject.tag = "Wall"; var polcol = poly.gameObject.GetComponent <PolygonCollider2D>(); Vector2[] points = { a2, b2, d2, c2, a2 }; polcol.SetPath(0, points); var outline2D = poly.gameObject.AddComponent <Outline>(); //outline2D.OutlineMode = Outline.Mode.OutlineAll; //outline2D.OutlineColor = Color.green; //outline2D.OutlineWidth = 10f; outline2D.enabled = false; // transform poly.gameObject.transform.position = new Vector3(center.x, center.y, -0.001f); // rotation poly.gameObject.transform.rotation = rotation; //w.wall2D.transform.localScale = Vector3.one * w.Length; // =========== 3D PART =========== var center3D = VectorFunctions.Switch2D3D(center); var a3 = invRot3D * VectorFunctions.Switch2D3D(a); var b3 = invRot3D * VectorFunctions.Switch2D3D(b); var c3 = invRot3D * VectorFunctions.Switch2D3D(c); var d3 = invRot3D * VectorFunctions.Switch2D3D(d); var a3h = invRot3D * (VectorFunctions.Switch2D3D(a) + Vector3.up * w.Height); var b3h = invRot3D * (VectorFunctions.Switch2D3D(b) + Vector3.up * w.Height); var c3h = invRot3D * (VectorFunctions.Switch2D3D(c) + Vector3.up * w.Height); var d3h = invRot3D * (VectorFunctions.Switch2D3D(d) + Vector3.up * w.Height); var new3DVertices = new List <Vector3> { // Bottom a3, b3, c3, d3, // Top a3h, b3h, c3h, d3h }; var custTriangles3D = new List <Vector3> { // up a3, b3, d3, a3, d3, c3, // down a3h, b3h, d3h, a3h, d3h, c3h, // face c3h, d3h, c3, d3h, d3, c3, // back a3h, b3h, a3, b3h, b3, a3, // right b3h, d3h, d3, b3h, d3, b3, // left a3h, c3h, c3, a3h, c3, a3 }; var poly3 = new Polygon3D(new GameObject("Wall3D"), custTriangles3D, w.Color).Build(); w.walls3D.Add(poly3); poly3.gameObject.transform.parent = w.associated3DObject.transform; poly3.gameObject.layer = (int)ErgoLayers.ThreeD; poly3.gameObject.tag = "Wall"; var outline = poly3.gameObject.AddComponent <Outline>(); //outline.OutlineMode = Outline.Mode.OutlineAll; //outline.OutlineColor = Color.green; //outline.OutlineWidth = 5f; outline.enabled = false; // transform poly3.gameObject.transform.position = center3D; // rot poly3.gameObject.transform.rotation = rotation3D; return(new List <Vector3> { a + center, b + center, c + center, d + center }); }
/// <summary> /// Check if the lines are interesecting in 2d space /// </summary> /// <param name="intersection"></param> /// <param name="w1"></param> /// <param name="w2"></param> /// <returns></returns> public static bool IsIntersecting(out Vector3 intersection, Wall w1, Wall w2) { Vector2 l1_start = w1.P1; Vector2 l1_end = w1.P2; Vector2 l2_start = w2.P1; Vector2 l2_end = w2.P2; //Direction of the lines var l1_dir = (l1_end - l1_start).normalized; var l2_dir = (l2_end - l2_start).normalized; //If we know the direction we can get the normal vector to each line var l1_normal = new Vector2(-l1_dir.y, l1_dir.x); var l2_normal = new Vector2(-l2_dir.y, l2_dir.x); //Step 1: Rewrite the lines to a general form: Ax + By = k1 and Cx + Dy = k2 //The normal vector is the A, B var A = l1_normal.x; var B = l1_normal.y; var C = l2_normal.x; var D = l2_normal.y; //To get k we just use one point on the line var k1 = A * l1_start.x + B * l1_start.y; var k2 = C * l2_start.x + D * l2_start.y; //Step 2: are the lines parallel? -> no solutions if (VectorFunctions.IsParallel(l1_normal, l2_normal)) { Debug.Log("The lines are parallel so no solutions!"); intersection = Vector3.zero; return(false); } //Step 3: are the lines the same line? -> infinite amount of solutions //Pick one point on each line and test if the vector between the points is orthogonal to one of the normals if (VectorFunctions.IsOrthogonal(l1_start - l2_start, l1_normal)) { Debug.Log("Same line so infinite amount of solutions!"); //Return false anyway intersection = Vector3.zero; return(false); } //Step 4: calculate the intersection point -> one solution var x_intersect = (D * k1 - B * k2) / (A * D - B * C); var y_intersect = (-C * k1 + A * k2) / (A * D - B * C); var intersectPoint = new Vector2(x_intersect, y_intersect); //Step 5: but we have line segments so we have to check if the intersection point is within the segment if (VectorFunctions.IsBetween(l1_start, l1_end, intersectPoint) && VectorFunctions.IsBetween(l2_start, l2_end, intersectPoint)) { Debug.Log("We have an intersection point!"); intersection = intersectPoint; return(true); } intersection = Vector3.zero; return(false); }