-2

I have two lines intersecting each other, How can I put a box upon lines to get 4 corner coordinates.

The image explains the question very well. The red dotted lines(box) are just illusionary, Purpose is to get 4(????) corners of the box.

Lines can be drawn in and direction or shape.

I have got the intersection points of the lines and the middle point of both lines.

enter image description here

indrajit
  • 303
  • 1
  • 14
  • 1
    Just compute the various combinations of min and max (min(x),min(y),min(z) min(x),min(y),max(z) min(x),max(y),min(z) min(x),max(y),max(z) and so on) – Paulw11 Nov 02 '21 at 04:52

1 Answers1

2

So from what I understand is you want a world-XY aligned bounding rectangle. Otherwise there wouldn't be 4 but 8 corners ;)

Actually it doesn't really matter for this if the lines are intersecting or not.

Simply

  • get the four given start and end points of the lines
  • from these calculate min and max for X and Y axis
  • from these min and max permutations you get the four corners

Something like e.g.

// The given line points
Vector2 startA;
Vector2 endA;
Vector2 startB;
Vector2 endB;

// calculate min/max for each axis
var minX = Mathf.Min(startA.x, endA.x, startB.x, endB.x);
var maxX = Mathf.Max(startA.x, endA.x, startB.x, endB.x);
var minY = Mathf.Min(startA.y, endA.y, startB.y, endB.y);
var maxY = Mathf.Max(startA.y, endA.y, startB.y, endB.y);

// permutations of these give you the corners
var topRight = new Vector2(maxX, maxY);
var bottomRight = new Vector2(maxX, minY);
var bottomLeft = new Vector2 (minX, minY);
var topLeft = new Vector2 (minX, maxY);

If you also need the Z axis (in order to actually get a box) it is just four permutations more for minZ and maxZ accordingly.

// The given line points
Vector3 startA;
Vector3 endA;
Vector3 startB;
Vector3 endB;

// calculate min/max for each axis
var minX = Mathf.Min(startA.x, endA.x, startB.x, endB.x);
var maxX = Mathf.Max(startA.x, endA.x, startB.x, endB.x);
var minY = Mathf.Min(startA.y, endA.y, startB.y, endB.y);
var maxY = Mathf.Max(startA.y, endA.y, startB.y, endB.y);
var minZ = Mathf.Min(startA.z, endA.z, startB.z, endB.z);
var maxZ = Mathf.Max(startA.z, endA.z, startB.z, endB.z);

// permutations of these give you the corners
var topRightFront = new Vector3(maxX, maxY, minZ);
var bottomRightFront = new Vector3(maxX, minY, minZ);
var bottomLeftFront = new Vector3 (minX, minY, minZ);
var topLeftFront = new Vector3 (minX, maxY, minZ);
var topRightBack = new Vector3(maxX, maxY, maxZ);
var bottomRightBack = new Vector3(maxX, minY, maxZ);
var bottomLeftBack = new Vector3 (minX, minY, maxZ);
var topLeftBack = new Vector3 (minX, maxY, maxZ);

So the before mentioned code was assuming you want the rect/box to be world axis aligned.

In case that is not the case you could use the following way

  • Have an empty GameObject as the reference for the rotated world (e.g. aligned via QR code tracking etc) - let's call it "WorldAnchor"
  • convert the line points into local space of that WorldAnchor
  • Do the same min/max calculation for all axis now in local space
  • Do the same permutation to obtain the corners
  • Finally convert the corners back to world space

Something like

// The given line points in WORLD Space
Vector3 startA;
Vector3 endA;
Vector3 startB;
Vector3 endB;

// The given oriented world anchor
Transform anchor;

// The line points converted to LOCAL space
var localStartA = anchor.InverseTransformPoint(startA);
var localEndA = anchor.InverseTransformPoint(endA);
var localStartB = anchor.InverseTransformPoint(startB);
var localEndB = anchor.InverseTransformPoint(endB);

// calculate min/max for each axis
var localMinX = Mathf.Min(localStartA.x, localEndA.x, localStartB.x, localEndB.x);
var localMaxX = Mathf.Max(localStartA.x, localEndA.x, localStartB.x, localEndB.x);
var localMinY = Mathf.Min(localStartA.y, localEndA.y, localStartB.y, localEndB.y);
var localMaxY = Mathf.Max(localStartA.y, localEndA.y, localStartB.y, localEndB.y);
var localMinZ = Mathf.Min(localStartA.z, localEndA.z, localStartB.z, localEndB.z);
var localMaxZ = Mathf.Max(localStartA.z, localEndA.z, localStartB.z, localEndB.z);

// permutations of these give you the corners
var localTopRightFront = new Vector3(localMaxX, localMaxY, localMinZ);
var localBottomRightFront = new Vector3(localMaxX, localMinY, localMinZ);
var localBottomLeftFront = new Vector3 (localMinX, localMinY, localMinZ);
var localTopLeftFront = new Vector3 (localMinX, localMaxY, localMinZ);
var localTopRightBack = new Vector3(localMaxX, localMaxY, localMaxZ);
var localBottomRightBack = new Vector3(localMaxX, localMinY, localMaxZ);
var localBottomLeftBack = new Vector3 (localMinX, localMinY, localMaxZ);
var localTopLeftBack = new Vector3 (localMinX, localMaxY, localMaxZ);

Now either simply place your corner visualizers at these positions but as children of the WorldAnchor object.

Or convert them back to global world space using

var topRightFront = anchor.TransformPoint(localTopRightFront);
var bottomRightFront = anchor.TransformPoint(localBottomRightFront);
var bottomLeftFront = anchor.TransformPoint(localBottomLeftFront);
var topLeftFront = anchor.TransformPoint(localTopLeftFront);
var topRightBack = anchor.TransformPoint(localTopRightBack);
var bottomRightBack = anchor.TransformPoint(localBottomRightBack);
var bottomLeftBack = anchor.TransformPoint(localBottomLeftBack);
var topLeftBack = anchor.TransformPoint(localTopLeftBack);
derHugo
  • 83,094
  • 9
  • 75
  • 115
  • Thank you for the answer @derHugo How would I accommodate Z in corner ? let minX = min(startA.x, endA.x, startB.x, endB.x) let minY = min(startA.y, endA.y, startB.y, endB.y) let minZ = min(startA.z, endA.z, startB.z, endB.z) let maxX = max(startA.x, endA.x, startB.x, endB.x) let maxY = max(startA.y, endA.y, startB.y, endB.y) let maxZ = max(startA.z, endA.z, startB.z, endB.z) let topRight: Position = .init(x: maxX, y: maxY, z: minZ) – indrajit Nov 02 '21 at 06:40
  • @indrajit this is `c#` so forget about `let` to begin with ;) Updated and added the Z axis permutations at the bottom – derHugo Nov 02 '21 at 06:51
  • Lol, Right @detHugo, It is let in c# :). I have followed your guide but corners identifies at a different place, I want them exactly on corner(See yellow mark in image) https://ibb.co/j80Rrhd Idea ? – indrajit Nov 02 '21 at 08:05
  • let topRight: Position = .init(x: maxX, y: maxY, z: minZ) let topLeft: Position = .init(x: minX, y: maxY, z: minZ) let bottomRight: Position = .init(x: maxX, y: minY, z: maxZ) let bottomLeft: Position = .init(x: minX, y: minY, z: maxZ) – indrajit Nov 02 '21 at 08:06
  • 1
    @indrajit idea: Apparently you do **not** want the box to be unity **world axis aligned** as I asked and assumed since you didn't answer ;) The question is now: How should your app know how to align the box? It is not aware o the pattern on your floor .... – derHugo Nov 02 '21 at 08:12
  • 1
    So the solution for this is quite more complex! You need a way to define your rotated world axis .. e.g. via QR scan or whatever ... then you would convert the given line points into the **local space** of an accordingly oriented object => same calculation to obtain the corners in that **local space** => convert them back into **global space**, done ;) – derHugo Nov 02 '21 at 08:21