Tengo una enorme matriz 2D con las coordenadas de los vértices de los hexágonos. que se ve así:

let arr = [
  [150.3073578016,95.9815785601,149.1526572632,97.9815785601,150.3073578016,99.9815785601,152.6167588783,99.9815785601,153.7714594167,97.9815785601,152.6167588783,95.9815785601],
  [120.5738189383,54.4815785601,121.7285194767,54.4815785601,122.3058697459,55.4815785601,121.7285194767,56.4815785601,120.5738189383,56.4815785601,119.9964686691,55.4815785601],
  [119.9964686691,78.4815785601,122.3058697459,78.4815785601,123.4605702842,80.4815785601,122.3058697459,82.4815785601,119.9964686691,82.4815785601,118.8417681307,80.4815785601],
  [115.6663416502,100.9815785601,117.9757427269,100.9815785601,119.1304432653,102.9815785601,117.9757427269,104.9815785601,115.6663416502,104.9815785601,114.5116411118,102.9815785601],
  [124.326595688,100.9815785601,126.6359967648,100.9815785601,127.7906973032,102.9815785601,126.6359967648,104.9815785601,124.326595688,104.9815785601,123.1718951496,102.9815785601],
];

Un hexágono tiene 6 vértices. cada subarreglo es un hexágono y tiene las coordenadas xey de cada vértice.

Por lo que cada submatriz contiene 12 valores.

Nota: ¡No todos los hexágonos tienen el mismo tamaño!

Estructurado así ( SIN CLASIFICAR ): [x,y,x,y,x,y,x,y,x,y,x,y];

Mi problema ahora es: ¿cómo puedo ordenar la matriz 2d para que esté ordenada por filas, yendo de arriba a la izquierda a abajo a la derecha? ingrese la descripción de la imagen aquí

Mi idea era sumar cada valor secundario, pero no me da el orden que quiero.

function sortHexagons(hexCoordinates) {
  function sort(arr) {
    const reducer = (accumulator, currentValue) => accumulator + currentValue;
    return arr.reduce(reducer);
  }
  hexCoordinates.sort((a, b) => sort(a) - sort(b));
}
2
David 17 ago. 2020 a las 14:58

2 respuestas

La mejor respuesta

Aquí hay un intento no probado. Hago un promedio de los valores de xey de cada hexágono, luego ordeno primero por y descendente y segundo por x ascendente. Hace suposiciones sobre la uniformidad de sus hexágonos.

EDITAR: cometió un pequeño error en el primer intento, lo he arreglado.

    var arr = [
    [150.3073578016,95.9815785601,149.1526572632,97.9815785601,150.3073578016,99.9815785601,152.6167588783,99.9815785601,153.7714594167,97.9815785601,152.6167588783,95.9815785601],
    [120.5738189383,54.4815785601,121.7285194767,54.4815785601,122.3058697459,55.4815785601,121.7285194767,56.4815785601,120.5738189383,56.4815785601,119.9964686691,55.4815785601],
    [119.9964686691,78.4815785601,122.3058697459,78.4815785601,123.4605702842,80.4815785601,122.3058697459,82.4815785601,119.9964686691,82.4815785601,118.8417681307,80.4815785601],
    [115.6663416502,100.9815785601,117.9757427269,100.9815785601,119.1304432653,102.9815785601,117.9757427269,104.9815785601,115.6663416502,104.9815785601,114.5116411118,102.9815785601],
    [124.326595688,100.9815785601,126.6359967648,100.9815785601,127.7906973032,102.9815785601,126.6359967648,104.9815785601,124.326595688,104.9815785601,123.1718951496,102.9815785601],
  ];

// get the average x and y values of each array
var averageTracker = []
for (let x = 0; x < arr.length; x++) {
    var xSum = 0;
    var ySum = 0;
    for (let y = 0; y < arr[x].length; y++) {
        if (y % 2 == 0) {
            xSum = xSum + arr[x][y];
        } else {
            ySum = ySum + arr[x][y];
        }
    }
    // save the average x and y value of a hexagon against the index of the hexagon
    var indexTracker = {
        arrayPosition: x,
        xAverage: xSum / (arr[x].length / 2),
        yAverage: ySum / (arr[x].length / 2),
    };
    averageTracker.push(indexTracker);
}

// sort the hexagons by y descending, followed by x ascending
averageTracker.sort(function (a, b) {
    return b.yAverage - a.yAverage || a.xAverage - b.xAverage;
});

// get the hexagon out of the original array by index
var newArr = [];
for (let x = 0; x < averageTracker.length; x++) {
    newArr.push(arr[averageTracker[x].arrayPosition]);
}
1
bm13563 17 ago. 2020 a las 12:34

Si está utilizando esto como JavaScript simple, debe agregar CDN para la biblioteca lodash o está utilizando el marco y la biblioteca de JavaScript que necesita instalar lodash

$ yarn add lodash / npm install lodash

En la página actual o componente use lodash usando

const _ = require('lodash'); or import * as _ from 'lodash';

Eres buena para ir

const coordinatesArray = _.map(arr, (row) => {
  // convert every row element into chank of two element
  const coordinates = _.chunk(row, 2)
  // convert coordinates into readable form using x and y axis
  return _.map(coordinates, (i) => ({ x: i[0], y: i[1] }))
})
const sortedCoordinates = _.map(coordinatesArray, (row) => {
  // sort array based on x axis you can change ASC DESC
  return _.sortBy(row, 'x')
})
const sortHexagons = _.map(sortedCoordinates, (row) => {
  const newrow = []
  // deconstruct corrdinated into array of array form to get desicre result
  _.map(row, (i) => {
    // deconstruction on coordination
    newrow.push(i.x)
    newrow.push(i.y)
  })
  return newrow
})
// required result 
console.log(sortHexagons)
1
Ashok 17 ago. 2020 a las 12:44