Skip to content
Astera Technology

Convert a bounded rectangle to surface fractions

Retain the source size and reject rectangles outside it.

Download complete case notes and answer keys ↓

Source contract and expected records

This is an original, fully synthetic mapping example. Inputs are plain, acyclic JSON-shaped records with the fields shown; the canonical shape and rejection codes belong to this example. Adapt the contract before using a different source.

Surface width/height and rectangle width/height are positive safe integers; x/y are nonnegative safe integers. The rectangle must fit completely within the surface, touching edges permitted. Divide x and width by surface width, and y and height by surface height. Retain sourceSize and tag unit fraction.

Editable synthetic mapping cases
CaseInput record (JSON)Expected output (JSON)
Scale a supplied rectangle{"surface":{"width":200,"height":100},"rect":{"x":20,"y":10,"width":100,"height":40}}{"ok":true,"value":{"left":0.1,"top":0.1,"width":0.5,"height":0.4,"unit":"fraction","sourceSize":{"width":200,"height":100}}}
Reject outside edge{"surface":{"width":200,"height":100},"rect":{"x":190,"y":0,"width":20,"height":10}}{"ok":false,"error":"RECTANGLE_BOUNDS"}
Preserve touching edges{"surface":{"width":200,"height":100},"rect":{"x":100,"y":0,"width":100,"height":100}}{"ok":true,"value":{"left":0.5,"top":0,"width":0.5,"height":1,"unit":"fraction","sourceSize":{"width":200,"height":100}}}
Download editable CSV ↓

Run the local transformation

Run the complete example as a JavaScript module in Node.js. It contains the pure mapping function, all three inputs and literal expected outputs; assertions stop on a mismatch. A rejected case returns ok=false with an error code, rather than a partial canonical record.

Complete function and executable cases
import assert from 'node:assert/strict';

function rectangleFractions(i){
  const fail=error=>({ok:false,error});if(!i||!i.surface||!i.rect)return fail('RECTANGLE_SHAPE');
  const s=i.surface,r=i.rect;
  if(![s.width,s.height].every(n=>Number.isSafeInteger(n)&&n>0))return fail('SURFACE_SIZE');
  if(![r.x,r.y,r.width,r.height].every(Number.isSafeInteger)||r.x<0||r.y<0||r.width<=0||r.height<=0||r.x+r.width>s.width||r.y+r.height>s.height)return fail('RECTANGLE_BOUNDS');
  return {ok:true,value:{left:r.x/s.width,top:r.y/s.height,width:r.width/s.width,height:r.height/s.height,unit:'fraction',sourceSize:{width:s.width,height:s.height}}};
}

// Original synthetic cases; expected outputs are literal records.
const cases = [
  {
    "label": "Scale a supplied rectangle",
    "input": {
      "surface": {
        "width": 200,
        "height": 100
      },
      "rect": {
        "x": 20,
        "y": 10,
        "width": 100,
        "height": 40
      }
    },
    "expected": {
      "ok": true,
      "value": {
        "left": 0.1,
        "top": 0.1,
        "width": 0.5,
        "height": 0.4,
        "unit": "fraction",
        "sourceSize": {
          "width": 200,
          "height": 100
        }
      }
    }
  },
  {
    "label": "Reject outside edge",
    "input": {
      "surface": {
        "width": 200,
        "height": 100
      },
      "rect": {
        "x": 190,
        "y": 0,
        "width": 20,
        "height": 10
      }
    },
    "expected": {
      "ok": false,
      "error": "RECTANGLE_BOUNDS"
    }
  },
  {
    "label": "Preserve touching edges",
    "input": {
      "surface": {
        "width": 200,
        "height": 100
      },
      "rect": {
        "x": 100,
        "y": 0,
        "width": 100,
        "height": 100
      }
    },
    "expected": {
      "ok": true,
      "value": {
        "left": 0.5,
        "top": 0,
        "width": 0.5,
        "height": 1,
        "unit": "fraction",
        "sourceSize": {
          "width": 200,
          "height": 100
        }
      }
    }
  }
];
for (const sample of cases) {
  const actual = rectangleFractions(sample.input);
  assert.deepEqual(actual, sample.expected);
  console.log(sample.label, JSON.stringify(actual));
}
Download runnable example ↓

Work through the boundary

On a 200×100 surface, what does x20/y10/w100/h40 become?

Show the worked answer

left=20/200=0.1, top=10/100=0.1, width=100/200=0.5, height=40/100=0.4. The rectangle ends at x120/y50, within the source bounds.

Related resources