моно c# CairoHelper.Translate

с использованием Каира;

Я нарисовал прямоугольник внутри большего прямоугольника, который находится внутри области рисования.

Мне удалось прикрепить событие к области рисования, ведь это объект, который я расширил от него.

this.AddEvents ((int) EventMask.ButtonPressMask);

this.ButtonPressEvent += delegate(object o, ButtonPressEventArgs args) {
    hasInterface(args.Event.X, args.Event.Y);

    Console.WriteLine("Button Pressed " + args.Event.X + ", " + args.Event.Y);
};

Я динамически рисую квадраты, используя:

cr.Translate(width/2, height/2);

cr.Rectangle((pX + (i * tmp)) , pY, boxsize, boxsize);      

private void recordPosition(double x, double y)
{
    x = x*2;
    y = y*2;
    boxCoordinates.Add( new double[,]
        { 
            {x, y}
        }
    ); // store coords
}


List<double,double> boxCoordinates

Таким образом, для внутренней части области рисования квадрат рисуется в координатах x=0, y=0, с точки зрения «снаружи» это координаты x=90, y=45; ширина = 180, высота = 100. Я использовал перевод (поскольку половина этого копируется) размера / 2, так что это означает, что область рисования изменяла размер квадрата, чтобы решить эту проблему, я сохранял умножение позиции это на 2, но это не работает, я получаю «попадания» за пределы нарисованного прямоугольника.

Как лучше всего это сделать? Я имею в виду перевести позиции X Y из окна в область рисования, я видел, что это возможно на других языках, но не уверен, как это сделать в С# и области рисования из моно.

Спасибо за любую помощь.


person Fernando André    schedule 25.02.2012    source источник


Ответы (1)


Я делал это несколько раз в Cw SDL и C# с Cairo, в основном, вы хотите иметь возможность преобразовывать ограничивающую рамку каждого из ваших прямоугольников в координаты, которые вы используете для рендеринга на холсте cairo, и из них.

Для каждого из ваших прямоугольников у вас будет местоположение ваших прямоугольников в их собственном мире. Мне нравится называть их «мировыми координатами» и их «экранными координатами» (которые сопоставляются с тем, где будет находиться ваша мышь).

Вы можете сохранить мировые координаты каждого блока, а затем преобразовать их в экранные для каждого кадра, который вы визуализируете.

public class Shape {
  public Point WorldLoc { get; set; }
}

Вы бы сделали всю свою физику (если она у вас есть) на значениях WorldLoc. Когда вы приступите к рендерингу, вы захотите иметь возможность конвертировать WorldLoc в ScreenLoc.

public class Scene {
  public double Zoom;
  public Point Offset;

  public Point WorldToScreen( Point world ){
    var p = new Point();
    p.x = (world.x - Offset.x) * Zoom;
    p.y = (world.y - Offset.y) * Zoom;
    return p;
  }
} 

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

person IanNorton    schedule 25.02.2012
comment
Есть сомнения, логика очень похожа на то, что я делаю, но откуда берется эта переменная Offset, я имею в виду, как вы ее инициализируете? Также я использую List‹double,double›, чтобы сохранить положение фигуры, но имеет больше смысла делать это так, как вы, но для тестирования я думаю продолжать использовать список. - person Fernando André; 27.02.2012
comment
Смещение будет расположением верхнего левого угла вашего окна просмотра в вашем мире. Хранение большого количества объектов списка кажется расточительным. - person IanNorton; 27.02.2012
comment
То, что я имел в виду, больше похоже на List‹Shape› Shape имеет x и y и другие детали об этом объекте. Спасибо за вашу помощь. - person Fernando André; 28.02.2012