Análisis del tema final de la Copa Puente Azul: Curva de Peano

El enlace del título original gracias al autor
https://blog.csdn.net/qq_43449564/article/details/124584232

Introducción a las curvas de Peano

Una curva de Peano es una curva en un plano.

La siguiente figura muestra la situación de primer orden de la curva de Peano, que comienza desde la esquina inferior izquierda, pasa por cada cuadrícula en una cuadrícula de 3 × 3 y finalmente llega a una curva en la esquina superior derecha. Para facilitar el cálculo y la comprensión, podemos girar la imagen 90 grados en el sentido de las agujas del reloj, es decir, el punto inicial se convierte en coordenadas peano [0] [0] y el punto final se convierte en peano [2] [2]
  inserte la descripción de la imagen aquíinserte la descripción de la imagen aquí

La siguiente figura muestra la situación de segundo orden de la curva de Peano
inserte la descripción de la imagen aquí
. En la curva de Peano de segundo orden, encontramos las siguientes reglas:

  1. Se puede dividir en 9 bloques, y cada bloque es una curva de Peano de orden 1 (el índice de bloque es par), o una forma transformada de la curva de Peano de orden 1 (el índice de bloque es impar), como se muestra en la siguiente figura
    inserte la descripción de la imagen aquíinserte la descripción de la imagen aquí
  2. Después del análisis, podemos ver que los puntos en la forma de transformación de la curva de Peano de primer orden y la curva de Peano original son el resultado de una transformación simétrica según el eje x (porque ambas son entradas y la entrada de la curva de Peano de primer orden). -La curva de Peano de orden es peano[0][0] y la forma de transformación de la curva de Peano de primer orden es peano[2][0])
  3. Los índices de los 9 bloques están ordenados según la forma de bucle de la curva de Peano de izquierda a derecha y de arriba a abajo (0,1,2,5,4,3,6,7,8)
  4. Al pasar por los bloques 3, 4 y 5, el punto inicial es el punto final original y el punto final es el punto inicial original, por lo que debe transformarse, es decir, usar la longitud de la ruta que incluye el subbloque actual. ((blockIndex + 1) * 9 - el subbloque actual ha recorrido la Ruta-1) Si hay dos líneas arriba y abajo, calcule directamente la ruta recorrida por el subbloque anterior + la ruta recorrida por el subbloque actual bloquear.

Análisis de respuesta:

/**
 * 皮亚诺曲线解析
 * 
 * 1. 一阶皮亚诺为一个九宫格组成的曲线
 * 2. 二阶皮亚诺为9个一阶皮亚诺组成的矩阵
 * 3. 性质:
 * 		1. 皮亚诺的矩阵大小 为 3 的 (k + 1)幂次方,k为皮亚诺阶层。
 * 		2. 二阶开始的皮亚诺曲线中出现了两种不同类型的一阶皮亚诺曲线
 * 		   这两种不同的皮亚诺曲线关于x中轴线对称。
 * 4.计算两点间距离
 * 		1. 高阶的皮亚诺曲线可以转变成9个k-1阶的皮亚诺曲线
 * 		2. 皮亚诺曲线中两点间的距离可以通过两点到原点的距离差进行计算
 * @author zygswo
 *
 */
public class PeanoGraph {
    
    

	/**
	 * 将高次的皮亚诺分割成低一阶层的皮亚诺,其中存放的是区块的索引
	 * 按照皮亚诺曲线的回环形状排列
	 */
	private static int[][] block = new int[][]{
    
    
		{
    
    0,1,2},{
    
    5,4,3},{
    
    6,7,8}
	};
	
	/**
	 * blockSize 数组表示每个区块的尺寸
	 */
	private static int blockSize[];
	
	/**
	 * 计算离原点的距离
	 * @param k 皮亚诺的阶层
	 * @param x x
	 * @param y y
	 * @return
	 */
	private static int calc(int k, int x, int y) {
    
    
		// 结束递归
		if (k == 0) {
    
    
			return 0;
		}
		// 获取当前坐标所在的区块的坐标(即走过了几个子块)
		int blockIndex = block[x / blockSize[k]][ y / blockSize[k]];
		// blockIndex为奇数和偶数表示不同类型的皮亚诺曲线
		if (blockIndex % 2 == 1) {
    
    
			// 进行轴变换(例如,原来 在第3行的就到了第1行,原来第二行的就不变)
			x = blockSize[k] - 1 - x % blockSize[k];
		}
		/*
		 *  判断是否当前的点位于中间线上,即block索引为3,4,5
		 *  这时我们发现中间线上的皮亚诺曲线和两边的起点终点位置相反
		 * 	那么中间线上的点到起点的距离即为前面的方块的所有位置和 + 当前块中终点到当前的点距离
		 * 	当前块中终点到当前的点距离 = 当前块的位置和 - 当前块起点到当前的点的位置 
		 *  x % blockSize[k] = x 在当前块中的相对位置
		 *  y % blockSize[k] = y 在当前块中的相对位置
		 */
		if (blockIndex / 3 == 1) {
    
    
			return (blockIndex + 1) * blockSize[k] * blockSize[k]
					- 1 - calc(k-1, x % blockSize[k], y % blockSize[k]);
		} else {
    
    
			return blockIndex * blockSize[k] * blockSize[k]
					+ calc(k-1, x % blockSize[k], y % blockSize[k]);
		}
	}
	
	private static int abs(int a) {
    
    
		return a > 0 ? a : -a;
	}
	
	public static void main(String[] args) {
    
    
		// 不同阶级的块的尺寸不同
		blockSize = new int[] {
    
    
				0,1,3,9
		};
		// 计算距离
		System.out.println(abs(calc(2,3,0) - calc(2,2,0)));
	}
}

Supongo que te gusta

Origin blog.csdn.net/qq_31236027/article/details/124653940
Recomendado
Clasificación