Завъртане на картина с помощта на позиция на мишката в C#

По принцип това, което се опитвам да направя, е да завъртя картина с помощта на събития на мишката. Например, докато държите натиснат левия бутон на мишката, картината се завърта, когато движите мишката нагоре и надолу. Намерих друг въпрос тук, почти като моя (Как да завъртя снимка в C#), но при съпоставяне на параметъра на ъгъла в метода за завъртане (изходния код на метода във връзката) към изчисления ъгъл между мишката и центъра на изображението получавам изключение за препълване. Изображението, което се опитвам да завъртя, е в поле за картина. Някакви идеи? Трябва ли да правя това по друг начин?

Благодаря предварително!

---------РЕДАКТИРАНЕ 1-----------

Добре, мисля, че моят тригон беше изключен, промених го на...

Ъгъл = Atan((mousePosY - imageCenterY)/(mousePosX - imageCenterX)

Но сега изображението не се върти, то просто се движи (програмирах възможността и то да се движи, но това работи добре). Ето частта от кода, с която имам работа.

    private void pictureBox_MouseDown(object sender, MouseEventArgs e)
    {
        isDragging = true;

        pbCurrentX = e.X;
        pbCurrentY = e.Y;

    }

    private void pictureBox_MouseMove(object sender, MouseEventArgs e)
    {
        // For moving the image
        if (isDragging)
        {
            this.pictureBox1.Top = this.pictureBox1.Top + (e.Y - pbCurrentY);
            this.pictureBox1.Left = this.pictureBox1.Left + (e.X - pbCurrentX);
        }

        // For rotating the image
        if (rotateMode  && isDragging)
        {
            y2 = e.Y;
            y1 = (this.pictureBox1.Location.Y + (this.pictureBox1.Height / 2));
            x2 = e.X;
            x1 = (this.pictureBox1.Location.X + (this.pictureBox1.Width / 2));

            angle = (float)Math.Atan((y2-y1)/(x2-x1));

            // RotateImage method from the other question linked above
            this.pictureBox1.Image = RotateImage(this.pictureBox1.Image, angle);
        }


    }

Флагът rotateMode е зададен на true, когато върху pictureBox се щракне два пъти. Благодаря на всички!

---------ОТГОВОР-----------

Благодарение на Гейб открих всички малки пречупвания в моя код и сега работи добре. Единственото нещо е, че трябваше да направя размера на полето с картината по-голям, за да пасне на завъртяното изображение. Ето правилния код за всички, които искат да знаят отговора.

private void pictureBox_MouseDown(object sender, MouseEventArgs e)
    {
        isDragging = true;

        pbCurrentX = e.X;
        pbCurrentY = e.Y;

    }

    private void pictureBox_MouseMove(object sender, MouseEventArgs e)
    {

        if (isDragging && !rotateMode)
        {
            this.pictureBox1.Top = this.pictureBox1.Top + (e.Y - pbCurrentY);
            this.pictureBox1.Left = this.pictureBox1.Left + (e.X - pbCurrentX);
        }

        if (rotateMode  && isDragging)
        {
            y2 = e.Y;
            y1 = (this.pictureBox1.Location.Y + (this.pictureBox1.Height / 2));
            x2 = e.X;
            x1 = (this.pictureBox1.Location.X + (this.pictureBox1.Width / 2));

            angle = (float)Math.Atan2((y1 - y2), (x1 - x2));

            pictureBox1.Image =  RotateImage(currentImage, (100*angle));
        } 

    }

    private void pictureBox_MouseUp(object sender, MouseEventArgs e)
    {
        isDragging = false;
    }

Благодаря на Гейб и на всички останали!


person Gaax    schedule 28.02.2010    source източник
comment
Бихте ли могли да покажете кода, който се проваля?   -  person Vlad    schedule 28.02.2010
comment
Може да сте се опитвали да използвате ъгъл в градуси, докато параметърът за въртене трябва да е в радиани.   -  person Gabe    schedule 28.02.2010
comment
Слава Богу, че все още има хора, които имат любезността да публикуват решенията си, за да могат другите да се учат от тях!   -  person    schedule 22.08.2010


Отговори (4)


Опитвали ли сте нещо от рода на this.pictureBox1.Image = RotateImage(this.pictureBox1.Image, angle);? Функцията RotateImage, към която сте се свързали, върна ново завъртяно изображение, вместо да го завърти на място, както очаква вашият код.

За съжаление това завърта вече завъртяно изображение. Това, което трябва да направите, е да съхраните някъде оригиналното изображение, да речем originalImage. След това имайте this.pictureBox1.Image = RotateImage(originalImage, angle);. По този начин винаги се върти нова версия на оригинала.

person Gabe    schedule 28.02.2010
comment
Аха! Не разбрах това и сега работи, благодаря! Но сега имам изцяло нов проблем... хаха, изкривява изображението всеки път, когато се завърти до степен, в която е неразпознаваем. Някакви идеи? - person Gaax; 28.02.2010
comment
Настроих глобална променлива, наречена currentImage, за да съхранява оригиналното изображение: Image currentImage = picturebox1.Image Сега получавам NullReferenceException вътре в метода RotateImage, когато създава ново растерно изображение, използвайки размерите на изображението: Препратката към обект не е зададена на екземпляр на обект. - person Gaax; 28.02.2010
comment
Ако получавате NullReferenceException, това просто означава, че не инициализирате currentImage в правилния момент или не извиквате RotateImage(currentImage, angle). - person Gabe; 28.02.2010
comment
Ха, да, прав си. Чувствам се някак глупаво, че дори публикувах това ›‹ Благодаря, човече, сега всичко работи добре! - person Gaax; 28.02.2010

Без да виждаме вашия код, можем само да гадаем. Предполагам, че правите някакво тригонометрично изчисление, като например:

theta = Math.Atan((y2 - y1) / (x2 - x1));

Ако вашият x2-x1 върви към 0, вашият аргумент към Math.Atan отива към безкрайност и препълва.

person mbeckish    schedule 28.02.2010

Ъгъл = Atan((mousePosY - imageCenterY)/(mousePosX - imageCenterY)

Използвате imageCenterY два пъти там (въпреки че е добре в кода, който сте публикували).

Във всеки случай бих предложил да използвате Atan2 вместо Atan.

person Community    schedule 28.02.2010
comment
Промених го, но все още имам същия проблем :( - person Gaax; 28.02.2010
comment
Да, трябва да използвате Atan2 за това, в противен случай изображението ви няма да може да се завърти в пълен кръг. - person Gabe; 28.02.2010

     int  y2 = _cursory; // Cursor.Postion.Y

     int   y1 = (this.pictureBox1.Location.Y + (this.pictureBox1.Height / 2));
     int x2 = _cursorx; // Cursor.Postion.X
     int   x1 = (this.pictureBox1.Location.X + (this.pictureBox1.Width / 2));

      float  angle = (float)Math.Atan2((y1 - y2), (x1 - x2));
      float xDistance = x1 - this.pictureBox1.Location.X;
      float yDistance = y1 - this.pictureBox1.Location.Y;

      double deg = angle / Math.PI * 180 + 180;
      pictureBox1.Image = RotateImage(img, (int)deg);

// img == оригинално изображение

този код работи за мен

person Ehsan KHAN    schedule 27.11.2019