Xpoint
   [напомнить пароль]

Хитрый (ли) Ellipse в MS WORD

Метки: [без меток]
2004-08-09 13:14:50 [обр] Владислав[досье]

Я конечно новичок в С#, но этот недостаток я думаю пройдет со временем.
Запустите MS WORD, включите если у вас не включена панель инструментов
рисование. Нарисуйте эллипс. По умолчанию он будет выделен.
Видно что он вписан в прямоугольник. Но если медленно
вести мышку от угла этого прямоугольника к центру эллипса
вы можете заметить, что Курсор принимает форму Size только когда
находится внутри эллипса. Как это реализованно ? Какой алгоритм ?
Я так понял это у них это визульный компонент.
На С# я пробовал создать похожий.

using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Windows.Forms;

namespace Rama
{
   public class Rama : System.Windows.Forms.UserControl
   {
      private System.ComponentModel.Container components = null;
      public Rama()
      {
         // Ниже две строчки делают UserControl прозрачным
         SetStyle(ControlStyles.SupportsTransparentBackColor, true);
         this.BackColor = Color.Transparent;
         InitializeComponent();
      }
      protected override void Dispose( bool disposing )
      {
         if( disposing )
         {
            if( components != null )
               components.Dispose();
         }
         base.Dispose( disposing );
      }

      #region Component Designer generated code

      private void InitializeComponent()
      {
         this.Name = "Rama";
         this.Size = new System.Drawing.Size(165, 154);
         this.Paint += new System.Windows.Forms.PaintEventHandler(this.Rama_Paint);
         this.MouseMove += new System.Windows.Forms.MouseEventHandler(this.Rama_MouseMove);
      }

      #endregion

      private void Rama_Paint(object sender, PaintEventArgs e)
      {
         // Рисуем эллипсе
         e.Graphics.DrawEllipse(PenWin,0,0,this.Width-1,this.Height-1);
      }

      private void Rama_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
      {
         // Даже я понимаю что курсор примет форму Size просто когда
         // попадет на Rect Controla
         this.Cursor = System.Windows.Forms.Cursors.SizeAll;
      }
   }
}
А может я вообще не в ту сторону дую.

спустя 27 минут [обр] Владимир Палант(27/4445)[досье]
То есть проблема у вас в том, чтобы определить, находится ли курсор внутри эллипса? Вспоминаем уравнение эллипса: x^2/a^2 + y^2/b^2 = 1, где a и b длины полуосей эллипса, а x и y координаты от центра эллипса. Поскольку вы хотите проверять, находится ли курсор внутри эллипса, а не только на линии, то равенство заменяем на <=. Вот и все, собственно - нужно лишь взять все переменные и проверить неравенство.
спустя 40 минут [обр] Владислав[досье]
А куда я должен подставлять координаты моей мыши
в формулу ?
a = Width/2;
b = Height/2
if ((X(мыши)^2/a^2) + (Y(мыши)^2/b^2) <= 1) тогда меняем курсор. ТАК ?
спустя 37 минут [обр] Владимир Палант(27/4445)[досье]
Да, только переведите X(мыши) и Y(мыши) сначала в координаты относительно центра эллипса (то есть вычтите из них Width/2 и Height/2).
спустя 8 минут [обр] Владислав[досье]

ВАУ !!! Работает !!!
Большое спасибо.

float a = (this.Width-1)/2; // Длина полуоси по Х
float b = (this.Height-1)/2;// Длина полуоси по Y
float Xm = e.X-a;
float Ym = e.Y-b;
                   
if ((((Xm*Xm)/(a*a))+((Ym*Ym)/(b*b)))<=1)
{
   this.Cursor = System.Windows.Forms.Cursors.SizeAll;
}
else
   this.Cursor = System.Windows.Forms.Cursors.Arrow;
}

спустя 23 минуты [обр] Владислав[досье]
Мне нужны такие формулы для трапеции, полукруга, параллерограмма и др.
Подскажите пожалуйста где взять ?
спустя 1 час 57 минут [обр] Владимир Палант(27/4445)[досье]
Круг - спецслучай эллипса, обычно пишется как x^2 + y^2 = r^2. С полукругом вы сами разберетесь, я думаю...
Прямоугольный треугольник (катеты a и b на положительных x- и y-осях): x/a + y/b <= 1 && x >= 0 && y >= 0
Из него (и прямоугольника, но про него вы и так все знаете) можно сконструировать трапецию и параллелограмм - если у вас нет произвольных вращений, с ними будет немного сложнее.
спустя 16 дней [обр] Даниэль Алиевский(1/125)[досье]

С произвольно повернутым параллелограммом ABCD ситуация тоже не сильно сложная. Нужно перевести координаты точки в косоугольную систему координат параллелограмма, т.е. выразить радиус-вектор точки r=(x,y) в виде r = A + x'*p + y'*q, где A = радиус-вектор точки A, p=(px,py) - это вектор AB, q=(qx,qy) - вектор AD. (Например, px = x-координата_точки_B - x-координата_точки_A.) В новых координатах неравенства параллелограмма тривиальны: 0 <= x',y' <= 1. Чтобы найти x',y', нужно решить простенькую систему 2 уравнений; несложная формула ответа (формула Крамера) есть в любом справочнике.

Если ABCD - трапеция, AD || BC, то неравенства чуть усложняются. По-прежнему 0 <= y' <=1, 0 <= x', но вместо x' <= 1 придется взять более сложное неравенство: вроде как, x' <= 1 + y'*((BC-AD)/AD).

спустя 3 дня [обр] Владимир Палант(27/4445)[досье]
Даниэль Алиевский[досье]
Ну, я бы просто повернул координаты мышки вокруг центра вращения фигуры в обратном направлении. И дальше можно было бы работать так, будто фигура не повёрнута.
спустя 12 часов [обр] Даниэль Алиевский(1/125)[досье]
Владимир Палант[досье] Мой переход к x',y' - это и есть такой разворот, но плюс к этому еще и "перекашивание", делающее угол BAD прямым. Разве не логичнее сразу перейти к косоугольной системе координат x',y'? Может быть, по количеству машинных операций и можно что-то выгадать, если ограничиться простым поворотом (за счет ортогональности матрицы), но "идеологически" мое решение, вроде бы, проще.
спустя 4 часа 40 минут [обр] Владимир Палант(27/4445)[досье]
Даниэль Алиевский[досье]
Нет, с параллелограммом - конечно. Просто моё решение подходит для любой фигуры.
Powered by POEM™ Engine Copyright © 2002-2005