Location Parameters Document


location Parameter Documentation

Parameter Name

location

Data Type

Array[Array[float, float]]

  • The outer array must have a fixed length of 4 (must contain 4 vertices)
  • The inner array must have a fixed length of 2 (each vertex contains [x, y] coordinates)

Description

Represents the position and orientation of a shape on the canvas. The rectangle (including rotated rectangles) is defined by four vertex coordinates. The vertices must be listed in continuous clockwise order (recommended; all examples and code use clockwise order):

  1. Left Top (left_top)
  2. Right Top (right_top)
  3. Right Bottom (right_bottom)
  4. Left Bottom (left_bottom)

The coordinate system uses normalized coordinates for adaptive support across different canvas resolutions:

  • Origin (0, 0): Top-left corner of the canvas
  • Bottom-right (1, 1): Bottom-right corner of the canvas
  • Coordinate range: unrestricted (values outside [0, 1] indicate the shape is partially outside the canvas)
  • Normalization formula (actual coordinate → normalized coordinate):
    •   normalized_x = actual_x / canvas_width
        normalized_y = actual_y / canvas_height  
    • For example, actual coordinate (200, 100) on a 1000×500 canvas is normalized to (0.2, 0.2).

Vertex Order and Meaning

IndexVertex NameDescriptionExample [x, y]
0left_topTop-left vertex[0.2, 0.2]
1right_topTop-right vertex[0.6, 0.2]
2right_bottomBottom-right vertex[0.6, 0.6]
3left_bottomBottom-left vertex[0.2, 0.6]
📌

Key Rules:

  • Vertices must be listed in continuous clockwise or counterclockwise order to form a closed rectangle (if using counterclockwise, ensure the order is continuous and closed; otherwise, rotation and other operations may not work as expected)
  • Coordinate values may exceed [0, 1], indicating the shape is partially outside the canvas (as long as any part is inside, it is considered valid)

Example Values

The black box represents the valid canvas area; x and y are normalized values relative to the actual width and height.

  1. A rectangle fully inside the canvas:
{
  "location": [
    [0.2, 0.2],  // left_top
    [0.6, 0.2],  // right_top
    [0.6, 0.6],  // right_bottom
    [0.2, 0.6]   // left_bottom
  ]
}

  1. A rectangle partially outside the canvas
{
  "location": [
    [-0.2, -0.2],  // left_top
    [0.2, -0.2],   // right_top
    [0.2, 0.2],    // right_bottom
    [-0.2, 0.2]    // left_bottom
  ]
}


  1. Rectangle from Example 1 rotated 45 degrees clockwise
"location": [
   [0.4, 0.1172],   // left_top
   [0.6828, 0.4],   // right_top
   [0.4, 0.6828],   // right_bottom
   [0.1172, 0.4]    // left_bottom
]


Sample code for calculating rotated coordinates:

A positive rotation angle means clockwise; negative means counterclockwise.

function rotatePoint(point, center, angleDegrees) {
  const angleRadians = angleDegrees * Math.PI / 180;
  const cosTheta = Math.cos(angleRadians);
  const sinTheta = Math.sin(angleRadians);
  const offsetX = point[0] - center[0];
  const offsetY = point[1] - center[1];
  const rotatedX = center[0] + offsetX * cosTheta - offsetY * sinTheta;
  const rotatedY = center[1] + offsetX * sinTheta + offsetY * cosTheta;
  return [parseFloat(rotatedX.toFixed(4)), parseFloat(rotatedY.toFixed(4))];
}

function rotateRectangle(vertices, angleDegrees) {
  // Calculate the center as the average of the four points
  const centerX = (vertices[0][0] + vertices[1][0] + vertices[2][0] + vertices[3][0]) / 4;
  const centerY = (vertices[0][1] + vertices[1][1] + vertices[2][1] + vertices[3][1]) / 4;
  const center = [centerX, centerY];
  return vertices.map(vertex => rotatePoint(vertex, center, angleDegrees));
}

// Example input
const rectangleVertices = [
  [0.2, 0.2], // topLeft
  [0.6, 0.2], // topRight
  [0.6, 0.6], // bottomRight
  [0.2, 0.6]  // bottomLeft
];

const rotatedVertices = rotateRectangle(rectangleVertices, 45);
console.log(rotatedVertices);
// Output: [ [0.4, 0.1172], [0.6828, 0.4], [0.4, 0.6828], [0.1172, 0.4] ]

Sample Code: Strictly Checking If Four Vertices (Fixed Order) Form a Rectangle

// Check if four points form a rectangle (vertex order: left_top, right_top, right_bottom, left_bottom)
function isRectangleStrict(vertices) {
  if (!Array.isArray(vertices) || vertices.length !== 4) return false;

  function vector(a, b) {
    return [b[0] - a[0], b[1] - a[1]];
  }
  function dot(u, v) {
    return u[0] * v[0] + u[1] * v[1];
  }
  function length2(u) {
    return u[0] * u[0] + u[1] * u[1];
  }

  const v01 = vector(vertices[0], vertices[1]); // left_top -> right_top
  const v12 = vector(vertices[1], vertices[2]); // right_top -> right_bottom
  const v23 = vector(vertices[2], vertices[3]); // right_bottom -> left_bottom
  const v30 = vector(vertices[3], vertices[0]); // left_bottom -> left_top

  // Check if all four angles are right angles
  const rightAngles =
    Math.abs(dot(v01, v12)) < 1e-8 &&
    Math.abs(dot(v12, v23)) < 1e-8 &&
    Math.abs(dot(v23, v30)) < 1e-8 &&
    Math.abs(dot(v30, v01)) < 1e-8;

  // Check if opposite sides are equal in length
  const equalOppositeSides =
    Math.abs(length2(v01) - length2(v23)) < 1e-8 &&
    Math.abs(length2(v12) - length2(v30)) < 1e-8;

  return rightAngles && equalOppositeSides;
}

// 1. Standard rectangle, correct order
const rect1 = [
  [0, 0],   // left_top
  [2, 0],   // right_top
  [2, 1],   // right_bottom
  [0, 1]    // left_bottom
];
console.log(isRectangleStrict(rect1)); // true

// 2. Standard rectangle, wrong order (right_top, left_top, left_bottom, right_bottom)
const rect2 = [
  [2, 0],   // right_top
  [0, 0],   // left_top
  [0, 1],   // left_bottom
  [2, 1]    // right_bottom
];
console.log(isRectangleStrict(rect2)); // false

// 3. Not a rectangle
const notRect = [
  [0, 0],
  [2, 0],
  [1.5, 1],
  [0, 1]
];
console.log(isRectangleStrict(notRect)); // false

// 4. Degenerate case (duplicate points)
const degenerate = [
  [0, 0],
  [2, 0],
  [2, 0],
  [0, 1]
];
console.log(isRectangleStrict(degenerate)); // false
📌

Notes:

  • The vertex order must be strictly: left_top, right_top, right_bottom, left_bottom.
  • Incorrect order will return false.
  • Supports rotation and normalized coordinates.

Notes

  • The vertex order must be strictly maintained; otherwise, operations like rotation and rendering may not work as expected.
  • Normalized coordinates are suitable for responsive and multi-resolution canvas scenarios.
  • Coordinates can exceed [0, 1] as long as any part of the shape is within the canvas.

Let me know if you need a concise version or OpenAPI schema!