2013-12-01 2 views
-1

У меня есть старый код, который использует библиотеку cairo для рисования png и вызова следующей функции. Я не мог понять следующий код. Я знаю, что это вопрос, который взял какой-то код и задал вопрос. Но здорово, если кто-нибудь предоставит.Cairo library: cairo_line_to Функция

#define IMAGE_SIZE_W 1024 
#define IMAGE_SIZE_H 768 

#define GRAPH_MARGIN_L 48 
#define GRAPH_MARGIN_R 21 
#define GRAPH_MARGIN_B 27 
#define GRAPH_MARGIN_T 22 

#define GRAPH_SIZE_W (IMAGE_SIZE_W-(GRAPH_MARGIN_L+GRAPH_MARGIN_R)) 
#define GRAPH_SIZE_H (IMAGE_SIZE_H-(GRAPH_MARGIN_B+GRAPH_MARGIN_T)) 
#define SCALE_TO_CANVAS(v,low,high,fws,margin,a,b) (((a+b*((v-low)/(high-low)))*fws)+margin) 

#define SCALE_TO_CANVAS_Y(v,low,high) SCALE_TO_CANVAS(v,low,high,GRAPH_SIZE_H,GRAPH_MARGIN_T,1,-1) 
#define SCALE_TO_CANVAS_X(v,low,high) SCALE_TO_CANVAS(v,low,high,GRAPH_SIZE_W,GRAPH_MARGIN_L,0,1) 

void line_to_point(cairo_t *cr,float x, float y){ 
    cairo_line_to(cr,x,y); 
} 
void move_to_point(cairo_t *cr,float x, float y){ 
    cairo_move_to(cr,x,y); 
} 

Имеются данные по x и y и построены графики x и y. Функция абонент /* счетчик числа х и у ряда

for(i = 0; i< counter; i++) 
{ 
move_to_point(cr,SCALE_TO_CANVAS_X(xvals[i-1],lowX,highX),SCALE_TO_CANVAS_Y(yvals[i-1],lowY,highY)); 
line_to_point(cr,SCALE_TO_CANVAS_X(x,lowX,highX),SCALE_TO_CANVAS_Y(y,lowY,highY)); 
} 

чем после того, как он вызывает write_png, который является своего рода прямой функции.

Если вы посмотрите, SCALE_TO_CANVAS выполнил много расчетов, которые я не могу понять. cairo_line_to x и y изменили значение и построили его.

ответ

0

Я не смотрел слишком близко, но я бы предположил, что ваши данные x находятся между lowX и highX и ваши данные y между lowY и highY. Эти данные масштабируются так, чтобы они вписывались в поверхность изображения (что означает между 0x0 и 1024x768).

Кроме того, это, по-видимому, добавляет маржу со всех сторон (L/R/B/T будет означать левый, правый, нижний, верхний).

Если вы хотите, чтобы объяснение математики использовалось вместо ее значения, просто спросите.

Edit:

Хорошо, у нас есть данные, которые описывают точки на графике. Верхний левый угол наших входных данных находится в положении (lowX, lowY), нижний правый угол находится в (highX, highY).

Площадь, которую мы рисуем, имеет размер 1024x768. Таким образом, мы хотим масштабировать входные данные так, чтобы они вписывались в это пространство. Чтобы сделать вещи немного сложнее, мы хотим сохранить пустую маржу вокруг графика. Это занимает GRAPH_MARGIN_L пикселей слева, GRAPH_MARGIN_T пикселей на вершине и т.д.

Таким образом, область рисования имеет свой верхний левый угол в точке (GRAPH_MARGIN_L, GRAPH_MARGIN_T) и ее правом нижнем углу на (1024-GRAPH_MARGIN_R, 768-GRAPH_MARGIN_B). Поэтому мы ищем формулу, которая отображает (lowX, lowY) в (GRAPH_MARGIN_L, GRAPH_MARGIN_T) и (highX, highY) в (1024-GRAPH_MARGIN_R, 768-GRAPH_MARGIN_B).

В следующем примере давайте просто взглянем на одну из двух координат точки, например. координата x. Для точки х мы сначала вычислим процент, который описывает, насколько далеко вдоль оси она. 0% должно означать «в верхнем/левом конце», 100% - «внизу/вправо». Доступное пространство начинается с lowX и переходит на highX, поэтому возможны высокие значения highX-lowX. Таким образом, x-lowX (так что «top/left» действительно находится на нуле) падает где-то в этот диапазон и (x-lowX) * 100/(highX-lowX) - это процент, который мы ищем.

Этот процент теперь должен отображаться в целевой области. Сначала мы умножим это на ширину целевого пространства (и разделим на 100, чтобы процентное соотношение ушло), так что мы имеем значение, которое охватывает возможный диапазон. Затем мы должны добавить минимально возможное значение, так что вместо того, чтобы начинать с нуля и подниматься до возможной ширины (которая является высокой-низкой), мы имеем значение, которое находится между низким и высоким.

Все вместе, формула становится smallestTargetX + (х-lowX)/(highX-lowX) * widthOfTheTargetArea, или с точки зрения ваших устанавливает: GRAPH_MARGIN_L + (х-lowX)/(highX-lowX) * GRAPH_SIZE_W.

Дополнительные переменные a и b, которые используются в GRAPH_TO_CANVAS, используются для «направлений обмена». Кажется, что вместо того, чтобы иметь (0, 0) в верхнем левом углу и положительные координаты, идущие вправо/снизу, ваша система координат имеет (0, 0) в нижнем левом углу, а положительные координаты идут вправо/Вверх. Чтобы справиться с этим, проценты, вычисленные выше, умножаются на -1, а 1 добавляется к координате, чтобы сделать отображение действительно сопоставляющим точки друг с другом, что нужно. Это два последних аргумента для макроса GRAPH_TO_CANVAS.

Надеюсь, это поможет вам понять, что макросы.

+0

Действительно, я не мог понять о математике, а также действительно почему мы это делаем. – user765443

+0

Пытался объяснить математику («Mathmagics») и почему («Чтобы отобразить диапазон входных данных в доступное пространство для отображения») , –

+0

Большое спасибо за предоставленную информацию. Я провожу половину дня, но ничего не понимаю. Это код, написанный одним человеком, который покинул организацию. Можете ли вы дать некоторую учебную информацию для лучшего понимания. Каков этот подход. почему мы это делаем. – user765443