public override void SetEdges() { edges = new Edge[4]; for (int i = 0; i < 4; i++) { edges[i] = new Edge(verts[i], verts[(i + 1) % 4]); edges[i].IsRightUp = !LinAl.isPointUpperThanLine(pos, edges[i].V1, edges[i].V2); } }
public override void SetEdges() { edges = new Edge[4]; for (int i = 0; i < 4; i++) { edges[i] = new Edge(verts[i], verts[(i + 1) % 4]); if (edges[i].rotation == Edge.Rotation.Vertical) { edges[i].IsRightUp = this.pos.x < edges[i].V1.x; } else { edges[i].IsRightUp = !LinAl.isPointUpperThanLine(this.pos, edges[i].V1, edges[i].V2); } } }
public Edge(Vector2 v1, Vector2 v2) { if (v1.x == v2.x) { rotation = Rotation.Vertical; } else if (v1.y == v2.y) { rotation = Rotation.Horizontal; } else { rotation = Rotation.Diagonal; } V1 = v1; V2 = v2; Line = LinAl.GetLine(v1, v2); }
Vector2 Reflect(Vector2 touch, Edge wall, Vector2 velocity) { float speed = velocity.magnitude; float[] normal = LinAl.GetPerpendicularLine(touch, wall.Line); float angleWall = Mathf.Atan(-wall.Line[0] / wall.Line[1]) * Mathf.Rad2Deg; float angleVelocity = Mathf.Rad2Deg * Mathf.Atan2(velocity.y, velocity.x); if ((wall.IsRightUp && LinAl.isPointUpperThanLine(ball.transform.position, wall.V1, wall.V2)) || (!wall.IsRightUp && !LinAl.isPointUpperThanLine(ball.transform.position, wall.V1, wall.V2))) { float newAngleVelocity = 2 * angleWall - angleVelocity; newAngleVelocity *= Mathf.Deg2Rad; return(new Vector2(Mathf.Cos(newAngleVelocity), Mathf.Sin(newAngleVelocity)).normalized *speed); } else { return(Vector2.zero); } }
bool CheckForCollision(Vector2 pos, float r, Edge edge) { if (pos.x + r < Mathf.Min(edge.V2.x, edge.V1.x) || pos.x - r > Mathf.Max(edge.V2.x, edge.V1.x) || pos.y + r < Mathf.Min(edge.V2.y, edge.V1.y) || pos.y - r > Mathf.Max(edge.V2.y, edge.V1.y)) { return(false); } if ((edge.rotation != Edge.Rotation.Vertical) && (edge.IsRightUp && !LinAl.isPointUpperThanLine(pos, edge.V1, edge.V2)) || (!edge.IsRightUp && LinAl.isPointUpperThanLine(pos, edge.V1, edge.V2))) { return(false); } if (edge.rotation == Edge.Rotation.Vertical) { if (pos.x < edge.V1.x && edge.IsRightUp || (pos.x > edge.V1.x && !edge.IsRightUp)) { return(false); } } float a = edge.Line[0]; float b = edge.Line[1]; float c = edge.Line[2]; float p = pos.x; float q = pos.y; //float A = 1 + (a / b) * (a / b); //float B = 2 * a * c / (b * b) - 2 * p + a * q / b; //float C = p * p + (c / b) * (c / b) + 2 * q * c / b + q * q - r * r; //float D = B * B - 4 * A * C; // Discriminant float A = 1 + Mathf.Pow(b / a, 2); float B = 2 * b * c / Mathf.Pow(a, 2) + 2 * b * p / a - 2 * q; float C = Mathf.Pow(c / a, 2) + 2 * p * c / a + Mathf.Pow(p, 2) + Mathf.Pow(q, 2) - Mathf.Pow(r, 2); float D = B * B - 4 * A * C; if (D < 0) { return(false); } else { if (edge.rotation == Edge.Rotation.Horizontal) { ball.SetVelocity(new Vector2(ball.Velocity.x, -ball.Velocity.y)); ball.transform.position = (ball.transform.position.y > edge.V2.y) ? new Vector3(ball.transform.position.x, edge.V2.y + r + 0.0001f, ball.transform.position.z) : new Vector3(ball.transform.position.x, edge.V2.y - r - 0.0001f, ball.transform.position.z); return(true); } else if (edge.rotation == Edge.Rotation.Vertical) { ball.SetVelocity(new Vector2(-ball.Velocity.x, ball.Velocity.y)); ball.transform.position = (ball.transform.position.x > edge.V2.x) ? new Vector3(edge.V2.x + r + 0.0001f, ball.transform.position.y, ball.transform.position.z): new Vector3(edge.V2.x - r - 0.0001f, ball.transform.position.y, ball.transform.position.z); return(true); } else { float y1 = -(B + Mathf.Sqrt(D)) / (2 * A); float x1 = (y1 * b + c) / -a; float y2 = -(B - Mathf.Sqrt(D)) / (2 * A); float x2 = (y2 * b + c) / -a; float y = y1 + (y2 - y1) / 2; float x = x1 + (x2 - x1) / 2; if ((edge.IsRightUp && !LinAl.isPointUpperThanLine(pos, edge.V1, edge.V2)) || (!edge.IsRightUp && LinAl.isPointUpperThanLine(pos, edge.V1, edge.V2))) { return(false); } ball.SetVelocity(Reflect(new Vector2(x, y), edge, ball.Velocity)); ball.transform.position = new Vector2(x, y) + LinAl.GetNormalToEdge(edge) * (r + 0.001f); return(true); } } }