Skip to content

Understanding XOR response #135

@objectiveSee

Description

@objectiveSee

I am using your library to construct a room that looks like the image below. Black space represents negative space where the polygon would not be located. I am using the XOR operation because I need to create this outer shell and inner shell. The result that I get back (See JSON below) is an array of polygons but it's unclear which polygons are negative "holes" and which ones are positive space. Is there some reliable way of determining the holes? Right now my best guess is that the 2nd polygon in an array is negative, but I am not sure if that is always true.

Screen Shot 2022-04-25 at 11 45 44 AM

Here is a basic working example where I am trying to remove the outer polygon but add the inner polygon to essentially create a square donut. Any thoughts on how to interpret the resulting JSON so that I can identify the hole and non-hole bodies?

As a reference, I need the hole indicies in order to use earcut: https://github.com/mapbox/earcut

import polygonClipping, { Polygon, Ring } from 'polygon-clipping';
import fs from 'fs';

const writeOut = (res: any, filename: string = './out.json') => {
  try {
    fs.writeFileSync(filename, JSON.stringify(res), {
      encoding: 'utf8',
      flag: 'w',
    });
    //file written successfully
  } catch (err) {
    console.error(err);
  }
};

interface BasicZone {
  x: number;
  y: number;
  width: number;
  height: number;
}

// helper function. returns a polygon from the zone and insets or offsets its dimensions
const bodyFromZone = (zone: BasicZone, zoneOffset: number = 0): Polygon => {
  const xMin = zone.x - zoneOffset;
  const xMax = zone.x + zone.width + zoneOffset;
  const yMin = zone.y - zoneOffset;
  const yMax = zone.y + zone.height + zoneOffset;
  if (xMax < xMin || yMax < yMin) {
    throw new Error(`bad poly offset`);
  }
  return [
    [
      [xMin, yMin],
      [xMax, yMin],
      [xMax, yMax],
      [xMin, yMax],
      [xMin, yMin],
    ],
  ];
};

const world = [bodyFromZone({ x: 0, y: 0, width: 1000, height: 1000 })];
const outer = bodyFromZone({ x: 200, y: 200, width: 100, height: 100 });
const inner = bodyFromZone({ x: 200, y: 200, width: 100, height: 100 }, -10);

const result = polygonClipping.xor(world, outer, inner);
writeOut(result, './polygon-clipping.json');

Output.json:

[
  [
    [
      [0, 0],
      [1000, 0],
      [1000, 1000],
      [0, 1000],
      [0, 0]
    ],
    [
      [200, 200],
      [200, 300],
      [300, 300],
      [300, 200],
      [200, 200]
    ]
  ],
  [
    [
      [210, 210],
      [290, 210],
      [290, 290],
      [210, 290],
      [210, 210]
    ]
  ]
]

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions