LINUX.ORG.RU

Векторная реализация resize для объектов в контейнере


0

1

Допустим есть некий объект-контейнер в виде прямоугольника на холсте, с координатой в левом верхнем углу (x1, y1) и координатой (x2, y2) в правом нижнем. Я делаю resize - т.е. например мышкой цепляюсь за нижний маркер этого контейнера и тяну его (пусть будет вниз), как правильно реализовать изменение размеров объетов которые лежат в контейнере. Размеры объектов в контейнере известны.


Ну тут всё от твоей задумки зависит. Можешь их не двигать вообще. Как нужно — так и делай.

А если хочешь изменять их так же, как холст, то можно использовать трансформации. Это универсально, ибо будет работать и для изменений размера, и для изменений угла, и для изменений позиции. Насчёт того, что такое трансформация — см. QTransform, например.

Obey-Kun ★★★★★
()
Ответ на: комментарий от Obey-Kun

То есть:

1) Вычисляем трансформацию

2) Применяем её к холсту

3) Применяем её ко всем детишкам

Это если детишки не используют систему координат холста.

Если же они используют систему координат холста (что логично! обычно используют верхний левый угол как точку отсчёта), то с поворотами и изменением позиции возиться незачем, ведь они в координатах детишек нулевые, то есть тут достаточно вычислить коэффициенты, которые ты применил к ширине. И применить их к детишкам.

Как-то так.

Obey-Kun ★★★★★
()
Ответ на: комментарий от Obey-Kun

> которые ты применил к ширине.

к ширине и высоте

Obey-Kun ★★★★★
()
Ответ на: комментарий от Obey-Kun

ну у меня такой холст что там трансформации-то скорее всего нет (GtkDrawingArea из библиотеки GTK+). И мне нужно изменять размер так не всех объектов, а только выделенных.

g-71
() автор топика
Ответ на: комментарий от Obey-Kun

то, что детишки не используют систему координат холста - это да

меня больше волнует как применять dX dY, которые я получаю от мыши. Они у меня каждый раз например (0,1) - двигаюсь вниз, (-1, 1) - двигаюсь в левый нижний угол и т.д. Т.е. приращение минимально, а координаты холста целочисленные.

Надо подумать на этой проблемой мне.

g-71
() автор топика
Ответ на: комментарий от g-71

>меня больше волнует как применять dX dY, которые я получаю от мыши. Они у меня каждый раз например (0,1) - двигаюсь вниз, (-1, 1) - двигаюсь в левый нижний угол и т.д. Т.е. приращение минимально, а координаты холста целочисленные.

1. Хранишь исходные координаты объектов и контейнера.
2. Хранишь общую дельту от мыши DX DY.
3. При каждом событии от мыши делаешь DX+=dx, DY+=dy. Для каждого объекта и для контейнера пересчитываешь итоговые координаты на основе DX DY и исходных координат.
4. При подтверждении ресайза (отпусканию мыши) копируешь итоговые координаты в исходные и обнуляешь DX DY.
5. При отмене ресайза просто обнуляешь DX DY и возвращаешь всё как было.

geekless ★★
()
Ответ на: комментарий от g-71

Можно, например, сделать так (я так масштабирую отображаемый график):

gboolean Gconfigure(GtkWidget *Area, GdkEventConfigure *event, gpointer none){
	int i;
	Point *ptr;
	gfloat W, H, xScale, yScale;
	GdkPoint *gptr;
	if(!Pdata)
		return FALSE;
	if(!Pdata->data || Pdata->n < 2)
		return FALSE;
	free(gPoints);
	Npts = Pdata->n;
	gPoints = malloc(Npts * sizeof(GdkPoint));
	ptr = Pdata->data;
	gptr = gPoints;
	W = Area->allocation.width;
	H = Area->allocation.height;
	xScale = W / gXm;
	yScale = H / (gYm - gY0);
	for(i = 0; i < Npts; i++, ptr++, gptr++){
		gptr->x = (int)(ptr->x * xScale + 0.5);
		gptr->y = (int)(H - (ptr->y - gY0) * yScale + 0.5);
	}
	//DBG("Npts=%d\n", Npts);
	return FALSE;
}
В массиве Pdata->data хранятся точки графика. В массиве gPoints - точки в оконных координатах. Узнаем размеры виджета (W, H), вычисляем масштабные коэффициенты (gXm и gYm - максимальные величины абсциссы и ординаты, gY0 - минимальное значение ординаты, минимальное значение абсциссы в моем случае = 0).

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от geekless

Ну или да, как тут pathfinder намекает, лучше тупо брать дельту от текущего и начального положения мыши.

geekless ★★
()
Ответ на: комментарий от g-71

При событии начала изменения размера - записать текущие размеры, текущую координату мыши как w0, h0, x0, y0.
При событии движения мыши (x1, y1) вычислить текущие размеры объекта w = w0 - x0 + x1, h = h0 - y0 + y1, применить трансформацию соответственно.
При событии отпускания мыши выполнить то же самое, что для прошлого шага, плюс другие нужные действия для реакции на подтверждение нового размера.

Координаты мыши не обязательно должны быть в системе холста, но масштаб должен соответствовать

note173 ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.