2011-09-23 62 views
1

我有一堆需要绘制到网格中的块。现在显示它们不缩放一切都很好,但是当我尝试缩小它们以适应窗口时,我得到了“缩放工件”,因为我使用了正常的缩放比例公式并浮动。如何在不引起像素重叠的情况下缩小块

有没有办法避免这些问题?

常见的例子数据:

Original length: 200000 

缩小到25x25 pixel grid(这是这个小的开发和调试) 按比例缩小的最大长度:625(25 * 25)

Scale-ratio: (625/200000) = 0,003125 

示例数据1 - 重叠,缩放块彼此重写 块开始=>块结束:[开始,结束]

1: 2100 => 2800 
2: 2800 => 3600 
3: 3600 => 4500 
4: 4500 => 5500 

跳过显示此示例的输出,因为我认为示例2和示例3将获得点。为了完整性留下它。

实施例数据2 - 不正确的空间2和 开始块=>块的端部的之间3:[开始,结束)

1: 960 => 1440 
2: 1440 => 1920 
3: 1920 => 2400 

1: 960 => 1440, length: 480, scaled length: 1.5: 
2: 1440 => 1920, length: 480, scaled length: 1.5: 
3: 1920 => 2400, length: 480, scaled length: 1.5: 

像素开始,结束,长度

1: 3, 0, 1 
2: 4, 0, 1 
3: 6, 0, 1 

显示格:

[ 0, 0, 0, 1, 2, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] 
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] 
... 

个实施例数据3 - 1移动的步骤背面错误 开始块=>块的端部的:[开始,结束)

1: 896 => 1344 
2: 1344 => 1792 
3: 1792 => 2240 

1: 896 => 1344, length: 448, scaled length: 1.4: 
2: 1344 => 1792, length: 448, scaled length: 1.4: 
3: 1792 => 2240, length: 448, scaled length: 1.4: 

像素开始,结束,长度

1: 2, 0, 1 
2: 4, 0, 1 
3: 5, 0, 1 

显示网格:

[ 0, 0, 1, 0, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] 
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] 
... 

什么事例数据2和3应该看起来像:

[ 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] 
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] 
... 

记住块值[起点,终点)

先发制人(下选民/拖钓者)记住:我不是心理或心灵阅读器。如果你想给予否定的做法,或者它是无用的(我不会学到任何东西),只会污染线程。

更新

#include <iostream> 
#include <math.h> 
#include <limits.h> 
#include <assert.h> 
#include <vector> 
#include <array> 
#include <utility> // pair 
#include <algorithm> // for_each 

using namespace std; 

const size_t width_size = 25; // 25 pixels 
const size_t height_size = 25; // 25 pixels 
const size_t grid_length = width_size * height_size; // width * height 
array<size_t, grid_length> grid; 

const size_t original_length = 200000; 

typedef pair<unsigned long, unsigned long> block; 
vector<block> test_values; 

void show_grid() 
{ 
    for (size_t y = 0; y < height_size; ++y) { 
     const size_t start_pos_for_current_heigth = y * width_size; 
     const size_t end_pos_for_current_heigth = start_pos_for_current_heigth + width_size; 

     cout << "[ "; 
     for (size_t i = start_pos_for_current_heigth; i < end_pos_for_current_heigth; ++i) { 
      if (i + 1 < end_pos_for_current_heigth) 
       cout << grid[i] << ", "; 
      else 
       cout << grid[i]; 
     }; 
     cout << " ]" << endl; 
    } 
} 

void scale_and_add(const float scale) 
{ 
    size_t test_value_id = 1; 

    for_each(test_values.cbegin(), test_values.cend(), [&](const block &p) { 
     const float s_f = p.first * scale; 
     const unsigned long s = round(s_f); 
     const float e_f = p.second * scale; 
     const unsigned long e = round(e_f); 
     const unsigned long block_length = p.second - p.first; 
     const float block_length_scaled = block_length * scale; 
     assert(s <= grid_length); 
     assert(e <= grid_length); 

     cout << test_value_id << ":" << endl; 
     cout << " " << p.first << " => " << p.second << " length: " << block_length << endl; 
     cout << " " << s << " (" << s_f << ") => " << e << " (" << e_f << ") length: " << (e - s) << " (" << block_length_scaled << ")" << " (scaled)" << endl; 

     for (size_t i = s; i < e; ++i) { 
      if (grid[i] != 0) { 
       cout << "overlapp detected !" << endl; 
      } 
      grid[i] = test_value_id; 
     } 

     ++test_value_id; 
    }); 
} 

void reset_common() 
{ 
    grid.fill(0); 
    test_values.clear(); 
} 

int main() 
{ 
    const float scale = ((float)grid_length/(float)original_length); 
    cout << "scale: " << scale << " length per pixel: " << ((float)original_length/(float)grid_length) << endl; 

    // Example data 1 
/* cout << "Example data 1" << endl; 

    test_values.push_back(make_pair(2100, 2800)); 
    test_values.push_back(make_pair(2800, 3600)); 
    test_values.push_back(make_pair(3600, 4500)); 
    test_values.push_back(make_pair(4500, 5500)); 

    scale_and_add(scale); 
    show_grid(); 

    reset_common(); 

    // Example data 2 
    cout << "Example data 2" << endl; 

    test_values.push_back(make_pair(960, 1440)); 
    test_values.push_back(make_pair(1440, 1920)); 
    test_values.push_back(make_pair(1920, 2400)); 

    scale_and_add(scale); 
    show_grid(); 

    reset_common(); 

    // Example data 3 
    cout << endl << "Example data 3" << endl; 

    test_values.push_back(make_pair(896, 1344)); 
    test_values.push_back(make_pair(1344, 1792)); 
    test_values.push_back(make_pair(1792, 2240)); 

    scale_and_add(scale); 
    show_grid(); 

    reset_common();*/ 

    // Generated data - to quickly find the problem 
    cout << "Generated data" << endl; 

    auto to_op = [&](const size_t v) { 
     return v * (original_length/grid_length) * 1.3; // 1.4 and 1.5 are also good values to show the problem 
    }; 
    size_t pos = 0; 
    size_t psize = 1; // Note this value (length) and check it with the displayed one, you'll be surprised ! 
    for (size_t g = 0; g < 10; ++g) { 
     test_values.push_back(make_pair(to_op(pos), to_op(pos + psize))); 
     pos += psize; 
    } 

    scale_and_add(scale); 
    show_grid(); 

    return 0; 
} 

输出:

scale: 0.003125 length per pixel: 320 
    Generated data 
1: 
0 => 416 length: 416 
0 (0) => 1 (1.3) length: 1 (1.3) (scaled) 
2: 
416 => 832 length: 416 
1 (1.3) => 3 (2.6) length: 2 (1.3) (scaled) 
3: 
832 => 1248 length: 416 
3 (2.6) => 4 (3.9) length: 1 (1.3) (scaled) 
4: 
1248 => 1664 length: 416 
4 (3.9) => 5 (5.2) length: 1 (1.3) (scaled) 
5: 
1664 => 2080 length: 416 
5 (5.2) => 7 (6.5) length: 2 (1.3) (scaled) 
6: 
2080 => 2496 length: 416 
7 (6.5) => 8 (7.8) length: 1 (1.3) (scaled) 
7: 
2496 => 2912 length: 416 
8 (7.8) => 9 (9.1) length: 1 (1.3) (scaled) 
8: 
2912 => 3328 length: 416 
9 (9.1) => 10 (10.4) length: 1 (1.3) (scaled) 
9: 
3328 => 3744 length: 416 
10 (10.4) => 12 (11.7) length: 2 (1.3) (scaled) 
10: 
3744 => 4160 length: 416 
12 (11.7) => 13 (13) length: 1 (1.3) (scaled) 
[ 1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 9, 9, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] 
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] 
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] 
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] 
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] 
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] 
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] 
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] 
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] 
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] 
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] 
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] 
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] 
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] 
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] 
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] 
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] 
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] 
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] 
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] 
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] 
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] 
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] 
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] 
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] 

此代码示例更清楚地表明了我的问题。

有趣的事实:我用来写这个例子的mingw-g ++显示了稍微不同的值。我通常使用visual studio 2010,但这次不行,因为我不在家。

+0

照片可能有助于了解这里的问题。 –

+0

我没有图片展示此问题。 “显示网格”是我用来查找此问题的控制台程序的直接复制和粘贴输出。但是我可以向你展示一个图像,它与图形看起来很像: [link](http://i55.tinypic.com/s4cj9s。gif) –

回答

0

是的+1让你备份,问题是确定的。 我不知道为什么人们的事情是如此有趣,downvote甚至没有留下评论。

好了,:-)

通常问题绘图时你有这个重叠的问题,并在三维计算机图形与扫描线渲染器(的DirectX & OpenGL的前)他们通常会跳过只有一个像素(比如所有的右侧和下侧)。 也许这可以帮助你。

当分割是完美的时候,你也可能没有人为因素,所以你必须处理这个问题(例如,如果该值是一个'完美整数',例如185.000000,那么不要删除最后一个像素)。

HTH

0

我不知道如果我得到这个问题发言,但我会采取刺伤它。你有连续显示的信息范围,范围通常是[a,b]。当a和b直接表示要绘制的像素时,一切都很好,但当您想要缩放整个事物时遇到问题。

不处理多行像素,如果您有两个范围R1 = [a,b)和R2 = [b,c),则只需从a绘制到b-1并从b绘制到c-1,你的范围被绘制出来,从(int)(a * scale)到((int)(b * scale)-1)然后从(int)(b * scale)到( int)(c * scale)-1),你可以使用任何浮点数来进行整数转换,舍入,地板或天花板,你应该没问题。

如果您的比例范围量小于1个像素,在这种情况下,可能需要检测是否缩放的范围的大小是0,并且携带的校正因子(以像素为单位),其被添加的下一个问题领域将是在计算结束时。

DrawRanges(List<Range> ranges, float scale) 
    int carry = 0; 
    foreach(Range range in ranges) 
    { 
     int newStart = ceiling(range.start*scale); 
     int newEnd = ceiling(range.end*scale)-1; 

     if (newStart <= newEnd) 
     { 
     newEnd = newStart; 
     ++carry; 
     } 
     DrawRange(newStart+carry,newEnd+carry); 
    } 

,如果你有比你缩小网格块多个范围这将最终失败,你就必须弄清楚如何完全删除范围。在绘制范围内,您将索引映射到实际的块坐标。

这是否解决问题了吗?

+0

请参阅新添加的代码示例,我道歉,我应该添加一个代码示例开始。 –

+0

我在代码中可以看到的是,您要分别缩放开始,结束和块长度,您应该只能缩放这三个值中的两个,然后进行第三个缩放,这样该集合将保持一致,所以按比例开始,结束并计算从那个或比例开始和长度开始的长度并从中计算结束。缩放所有三个会让你陷入困境,特别是使用round()。这是家庭作业btw吗? –

+0

长度在那里作为调试值。如果你仔细看,我只是打印长度。家庭作业,我希望,那么我可以问一个老师这件事。这只是另一个有趣的宠物项目。 –

相关问题