Javascript 如何将画布图像数据转换为嵌套象限

Javascript 如何将画布图像数据转换为嵌套象限,javascript,algorithm,math,canvas,Javascript,Algorithm,Math,Canvas,示例: 假设我有一个512x512分辨率的画布。我试图得到它的坐标,如下所示: 第一步:将每个画布划分为笛卡尔坐标象限 _____ _____ | | | | 2 | 1 | |_____|_____| | | | | 3 | 4 | |_____|_____| 我没有得到二进制数学,或者神奇的49数字?这是一个“1”字符串。使用它作为起点是一个好主意吗?如果x坐标是(大端)二进制中的abcdefghi,y坐标是二进制中的jklmnopqr,那么基

示例:

假设我有一个512x512分辨率的画布。我试图得到它的坐标,如下所示:

第一步:将每个画布划分为笛卡尔坐标象限

_____ _____ | | | | 2 | 1 | |_____|_____| | | | | 3 | 4 | |_____|_____|
我没有得到二进制数学,或者神奇的
49
数字?这是一个
“1”
字符串。使用它作为起点是一个好主意吗?

如果x坐标是(大端)二进制中的
abcdefghi
,y坐标是二进制中的
jklmnopqr
,那么基-4中表示的象限数(直到象限的一致重新编号)是交错的
ajbkcldmenfogphqir
。下面是一些位旋转的C代码,用于32位坐标(为其他目的编写)


假设您的图像的宽度为2^p==高度。
像素的每个(x,y)坐标都有一个x和y,在p位上编码。
好的是象限坐标只是x和y坐标的交错:

我们可以一点一点地写x,如下所示:

x = x(p-1) x(p-2)  ... x2 x1 x0
和y为:

x = y(p-1) y(p-2)  ... y2 y1 y0
那么q是x和y的交错:

q = x(p-1)y(p-1) x(p-2)y(p-2)  ... x2y2 x1y1 x0y0 
q是您正在搜索的象限坐标,但其构建方式如下:

 _____ _____
|     |     |
|  0  |  2  |
|_____|_____|
|     |     |
|  1  |  3  |
|_____|_____|
也许这个方案更清楚,比如:

_____ _____ _____ _____ | | | | | | 22 | 21 | 12 | 11 | |_____|_____|_____|_____| | | | | | | 23 | 24 | 13 | 14 | |_____|_____|_____|_____| | | | | | | 32 | 31 | 42 | 41 | |_____|_____|_____|_____| | | | | | | 33 | 34 | 43 | 44 | |_____|_____|_____|_____|
 x = 0   x = 1
 _____________
|      |      |
|  00  |  10  |  y = 0
|______|______|
|      |      |
|  01  |  11  |  y = 1    (figures inside are in binary form)
|______|______|
事实上,在上面的方案中,x由第一位编码,y由第二位编码

更一般地说,在最上面的象限中,点仅取决于x中的高位和y中的高位。
你可以很快想象,如果x>255,我们在右边,否则我们在左边。y也是一样:如果y 255,我们就不是。测试x>255与测试x&256=>测试是否设置了最重要的位相同。
事实上,如果你仔细想想,在所有分辨率下都会出现完全相同的方案:假设我们在象限00上。现在看看我们是在这个象限的左边还是右边,我们将x和127进行比较。y也一样。事实上,我们正在测试x和y的第二位

你可以看到,(x,y)点的交错位描述了点象限[xp-1yp-1],[xp-2yp-2],…,[x2y2],[x1y1],[x0y0]

现在,您可以在此处找到live的代码:

x,y->象限坐标函数是非常简单的位混合:

var widthLog=10;  // 2^10 = 1024 X 1024 picture

function getQuadrant(x,y) {
    var q=0;
    var mask = 1 << (widthLog-1) ; 
    for (var i=0; i<widthLog; i++) {
        q<<=1;
        q |= ((x & mask ) == mask);
        q<<=1;
        q |= ((y & mask) == mask);
         x<<=1; y<<=1;      
    }
    return q;
}
widthLog=3/width=8的结果:

000  002  020  022  200  202  220  222  
001  003  021  023  201  203  221  223  
010  012  030  032  210  212  230  232  
011  013  031  033  211  213  231  233 
100  102  120  122  300  302  320  322  
101  103  121  123  301  303  321  323  
110  112  130  132  310  312  330  332  
111  113  131  133  311  313  331  333  

JavaScript中位运算符的快速参考:我建议不要使用该循环,它循环~4194304次,并导致我的chrome控制台停止响应。我们可以假设1)宽度和高度是2的幂和/或2)宽度==高度吗??(取决于此,这是一个非常简单的解决方案)@gamealchest你说得对!你可能应该把这个例子翻译成JavaScript,因为这是OP所要求的,而现在大多数(主流)计算机都是小端的,所以大端的例子可能没有那么有用?@Cryptoburner(1)C->JavaScript的音译对于这样的代码并不难。(2) 代码是与endian无关的。你能解释一下你是如何得到这个解决方案的吗?@Alexander:我澄清并举例说明了我的帖子。
 _____ _____
|     |     |
|  0  |  2  |
|_____|_____|
|     |     |
|  1  |  3  |
|_____|_____|
 x = 0   x = 1
 _____________
|      |      |
|  00  |  10  |  y = 0
|______|______|
|      |      |
|  01  |  11  |  y = 1    (figures inside are in binary form)
|______|______|
var widthLog=10;  // 2^10 = 1024 X 1024 picture

function getQuadrant(x,y) {
    var q=0;
    var mask = 1 << (widthLog-1) ; 
    for (var i=0; i<widthLog; i++) {
        q<<=1;
        q |= ((x & mask ) == mask);
        q<<=1;
        q |= ((y & mask) == mask);
         x<<=1; y<<=1;      
    }
    return q;
}
function getCoords(q, pt) {
  var x=0, y=0;
    var mask = 1 << (2*(widthLog)-1) ; 
    for (var i=0; i<widthLog; i++) { 
      x<<=1;
      x |= ((q & mask)==mask);
      q<<=1;
      y<<=1;
      y |= ((q & mask)==mask);
      q<<=1;    
    }  
  pt.x = x;
  pt.y = y;
}
function quadrantToNum ( q ) {
     var res = 0;
     var bitIndex = 2*widthLog ;
     var mask = 3 << (bitIndex);
     while ( mask ) {
       var qi = (q & mask) >> bitIndex ;
       bitIndex -=2 ;
       mask >>= 2;
       res = 10*res + qi ;
     }
  return res;
}
00  02  20  22 
01  03  21  23 
10  12  30  32 
11  13  31  33 
000  002  020  022  200  202  220  222  
001  003  021  023  201  203  221  223  
010  012  030  032  210  212  230  232  
011  013  031  033  211  213  231  233 
100  102  120  122  300  302  320  322  
101  103  121  123  301  303  321  323  
110  112  130  132  310  312  330  332  
111  113  131  133  311  313  331  333