Если я правильно понял, вам нужен способ хранения двумерного массива с плавающей запятой в C ++.Вам понадобится некоторое преобразование, потому что C ++ «поддерживает только одномерные массивы» (это не совсем верно, но мы будем притворяться, что это так).
Сначала нам нужно узнать диапазоны и приращения.Вы предоставили их, и для X диапазон составляет [0, 200]
, а для Y [0, 103]
с приращениями 1
и 1.5
соответственно.
Это означает, что у нас есть ((200-0)/1) = 200
возможных значений для X и ((103-0)/1.5) = 68.666...
возможные значения для Y. Мы выберем 69 возможных значений для Y.
Итак, у нас может быть следующий массив:
int my_array_of_ints[69 * 200];
Например, элемент [X=0][Y=0]
будетбудет нашим [0 * 69 + 0]
индексом (элемент my_array_of_ints[0]
), в то время как наш [X=1][Y=1.5]
будет нашим [1 * 69 + 1]
индексом (элемент my_array_of_ints[70]
).Обратите внимание, что у нас не может быть элементов с [Y = 0,5] или [Y = 1], потому что приращение Y установлено на 1,5 (т. Е. Y должно быть 0 или 1,5 или 3 или 4,5 или 6 или ...).
Эта функция для преобразования 2D-индекса в 1D-линейный индекс будет иметь вид:
#include <cmath>
int get_element(float x, float y){
int index_x = std::round(x / 1);
int index_y = std::round(y / 1.5);
if ((0 <= index_x) && (index_x < 200) &&
(0 <= index_y) && (index_y < 69)){
return my_array_of_ints[index_y * 200 + index_x];
} else {
// You should decide what to do if x or y is out-of-range
return 0;
}
}
Где:
1
- это приращение x 1.5
- приращение y 200
- количество возможных значений x в этом диапазоне с этим приращением 69
- количество возможных значений yв этом диапазоне с этим приращением.
Итак, мы могли бы сделать что-то вроде этого:
get_element(1, 1.5)
И оно вернуло бы значение [X=1][Y=1.5]
внутри my_array_of_ints
.
Оборачивание этого кода вокруг класса, шаблонизация типа массива, обобщение диапазонов и приращений и предоставление фиктивной основной:
#include <cmath>
#include <iostream>
template <typename Datatype> class Vector2D {
float x_increment;
float x_minimum;
float x_maximum;
float y_increment;
float y_minimum;
float y_maximum;
// For example, Y range [0, 103] with increment 1.5
// results in 69 possibles values for Y, and we need to
// remember to "linearize" the indexes
int x_possibles;
int y_possibles;
Datatype *array;
public:
Vector2D(float x_increment, float y_increment,
float x_maximum, float y_maximum,
float x_minimum=0, float y_minimum=0)
: x_increment(x_increment), x_minimum(x_minimum),
x_maximum(x_maximum), y_increment(y_increment),
y_minimum(y_minimum), y_maximum(y_maximum),
// These two may seem arcane, but they are the
// generalization of how we found the values initially
x_possibles(std::ceil((x_maximum-x_minimum)/x_increment)),
y_possibles(std::ceil((y_maximum-y_minimum)/y_increment)),
array(new Datatype[y_possibles * x_possibles]) {
// This may help to understand this 2D Vector
std::cout << "Creating 2D vector X in range ["
<< x_minimum << ", " << x_maximum
<< "] with increment of " << x_increment
<< " (totalizing " << x_possibles
<< " possible values for x) "
<< " and Y in range [" << y_minimum
<< ", " << y_maximum << "] with increment of "
<< y_increment << " (totalizing " << y_possibles
<< " values for y)."
<< std::endl;
}
// Frees up the raw array
~Vector2D(){
delete this->array;
}
Datatype& get_element(float x, float y){
int index_x = std::round((x-x_minimum)/this->x_increment);
int index_y = std::round((y-y_minimum)/this->y_increment);
// This debug message may help understand this function
// It is, in some sense, the answer of this question
std::cout << "The 2D point [X=" << x << ", Y=" << y
<< "] is mapped into the vector index ["
<< index_y << " * " << x_possibles
<< " + " << index_x << "]" << std::endl;
if ((0 <= index_x) && (index_x < x_possibles) &&
(0 <= index_y) && (index_y < y_possibles)){
return this->array[index_y * x_possibles + index_x];
} else {
// You should decide what to do if x or y is out-of-range
return this->array[0];
}
}
};
int main(){
// And you could use that class like this:
// A 2D-like vector with X [0, 200] inc. 1
// and Y [0, 103] inc. 1.5 of floats
Vector2D<float> my_data(1, 1.5, 200, 103, 0, 0);
// Sets [X=1][Y=1] to 0.61345
my_data.get_element(1, 1) = 0.61345;
auto elem1 = my_data.get_element(1, 1);
// Prints the [X=1][Y=1] to screen
std::cout << "[X=1][Y=1] is "
<< elem1
<< std::endl;
// Gets a few more interesting points
my_data.get_element(0, 0);
my_data.get_element(1, 1.5);
my_data.get_element(10, 15);
my_data.get_element(200, 103);
// A separator
std::cout << "---" << std::endl;
// Another example, this time using chars
// X is [-10, 1] inc. 0.1 and Y is [-5, 3] inc. 0.05
Vector2D<char> my_chars(0.1, 0.05, 1, 3, -10, -5);
// Sets [X=-4.3][Y=2.25] to '!'
my_chars.get_element(-4.3, 2.25) = '!';
auto elem2 = my_chars.get_element(-4.3, 2.25);
std::cout << "[X=-4.3][Y=2.25] is "
<< elem2
<< std::endl;
}
Выходы:
Creating 2D vector X in range [0, 200] with increment of 1 (totalizing 200 possible values for x) and Y in range [0, 103] with increment of 1.5 (totalizing 69 values for y).
The 2D point [X=1, Y=1] is mapped into the vector index [1 * 200 + 1]
The 2D point [X=1, Y=1] is mapped into the vector index [1 * 200 + 1]
[X=1][Y=1] is 0.61345
The 2D point [X=0, Y=0] is mapped into the vector index [0 * 200 + 0]
The 2D point [X=1, Y=1.5] is mapped into the vector index [1 * 200 + 1]
The 2D point [X=10, Y=15] is mapped into the vector index [10 * 200 + 10]
The 2D point [X=200, Y=103] is mapped into the vector index [69 * 200 + 200]
---
Creating 2D vector X in range [-10, 1] with increment of 0.1 (totalizing 110 possible values for x) and Y in range [-5, 3] with increment of 0.05 (totalizing 160 values for y).
The 2D point [X=-4.3, Y=2.25] is mapped into the vector index [145 * 110 + 57]
The 2D point [X=-4.3, Y=2.25] is mapped into the vector index [145 * 110 + 57]
[X=-4.3][Y=2.25] is !
Надеюсь, что это может помочь.