莫顿码Morton code的c语言实现

12 篇文章 9 订阅
11 篇文章 2 订阅

十进制 Morton码可以使用栅格单元的行列号计算


###原理部分
遵循C语言规范,矩阵的第一行为“0”行、第一列为“0”列,先将十进制的行列号转换成二进制数,进行“位”运算操作,即行号和列号的二进制数两两交叉,得到以二进制数表示的MD码,再将其转换为十进制数。
例如图中第二行和第三列对应的栅格单元,其二进制的行列号分别为:I=0010,J=0011;得到的MD码为:MD=(0001101)2=(13)10;用类似的方法,也可以由MD码反求栅格单元的行列号。
 Morton码顺序表
基本过程


###基本算法

// 输入 x 和 y, 交叉后为 xyxyxy。  
unsigned short x;   // x在奇数位
unsigned short y;   // y在偶数位
unsigned int md = 0; // 存储生成的Md码  
for (int i = 0; i < sizeof(x) * CHAR_BIT; i++) // 核心交叉算法,基本思想为移位和位运算..  
{  
  md |= (x & 1U << i) << (i + 1) | (y & 1U << i) << i;  
} 

###完整代码
#####代码一:

#include<stdio.h>
#include<limits.h>	//定义CHAR_BIT

int main(void)
{
	unsigned short i,j;	//行号、列号 
	unsigned short n;	//栅格大小 
	unsigned int md[n][n];	//每个码位的值 
		
	printf("请输入栅格的行列数(0<=n<=65535):");
	if(scanf("%hd",&n) == 0)
		return 0;
	for(i = 0;i < n;i++)	//行循环 
	{
		for(j = 0;j < n;j++)	//列循环 
		{
			md[i][j] = 0;
			for(int x = 0;x < sizeof(unsigned short) * CHAR_BIT;x++)	//行列号计算 
				md[i][j] |= (i & 1U << x) << (x + 1) | (j & 1U << x) << x;
			printf("%5u ",md[i][j]);	//打印输出 
		}
		printf("\n");
	}
			
	return 1;
 } 

#####代码二:

#include<stdio.h>
#include<limits.h>
void to_binary1(unsigned short n);
void to_binary2(unsigned int n);

int main(void)
{
	unsigned short x,y;
	unsigned int md;
	
	printf("请输入行号和列号(q to quit):");
	while(scanf("%hd %hd",&x,&y) != 0)
	{
		printf("行号I=(%hd)10=(",x);
		to_binary1(x);
		printf(")2\n");
		printf("列号J=(%hd)10=(",y);
		to_binary1(y);
		printf(")2\n");
		
		md = 0;
		for(int i = 0;i < sizeof(x) * CHAR_BIT;i++)
			md |= (x & 1U << i) << (i + 1) | (y & 1U << i) << i;
			
		printf("莫顿码MD=(%u)10=(",md);
		to_binary2(md);
		printf(")2\n");
		printf("\n请输入行号和列号(q to quit):");
	}
	printf("Done.\n");
	return 0;
}

void to_binary1(unsigned short n)
{
	int r;
	
	r = n % 2;
	if (n >= 2)
		to_binary1(n / 2);
	putchar(r == 0 ? '0' : '1');
	
	return;
}

void to_binary2(unsigned int n)
{
	int r;
	
	r = n % 2;
	if (n >= 2)
		to_binary2(n / 2);
	putchar(r == 0 ? '0' : '1');
	
	return;
}
  • 5
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

撼沧

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值