Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Клуб программистов > Свободное общение
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 05.11.2010, 21:33   #11
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Вот смотрите на чем я в принципе запхнулся, надо было эту пургу сразу в топик выложить да постеснялся
Код:
unit Unit1;

interface

uses math,
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs;

type
  TElips=class
   private
     fCx,fCy,fa,fb,fAngle:Double;
     function GetX(ang:Double):Double;
     function GetY(ang:Double):Double;
   public
    Canvas:TCanvas;
    Procedure Draw;
    Procedure DrawPnt(x,y:double);
    Function PoinInEllips(x,y:Double):Boolean;
    Constructor Create(Cx,Cy,a,b,Angle:Double);
  end;

  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure FormPaint(Sender: TObject);
    procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
  private  e:TElips;
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

{ TElips }

constructor TElips.Create(Cx, Cy, a, b, Angle: Double);
begin
 fCx:=Cx;fCy:=Cy;
 fa:=a;fb:=b;
 fAngle:=Angle;
end;

procedure TElips.Draw;
var x,y,ang:double;ix,iy:Integer;
begin
 ang:=0;
 with Canvas do begin
   while ang<(2*pi) do begin
    x:=GetX(ang);
    y:=GetY(ang);
    ix:=round(x+fCx);
    iy:=round(y+fCy);
    if ang=0 then MoveTo(ix,iy) else    LineTo(ix,iy);
    ang:=ang+pi/100;
   end;
 end;
end;


procedure TElips.DrawPnt;
const aga=10;
var ang,angx,angy,ln:double;ix,iy:Integer;
begin
   // Рассчитаем расстояние
   ln:=sqrt(sqr(x-fcx)+sqr(y-fcy));
   // Получим угол в градусах
    ang:=abs(x-fcx)/ln;
    angx:=RadToGrad(arccos(ang));
    form1.Caption:=format('%f',[angx]);
    // Вычислим по углу точку на эллипсе
    x:=GetX((angx));
    y:=Gety((angx));
    ix:=round(x+fCx);
    iy:=round(y+fCy);
    Canvas.Brush.Style:=bsSolid;
    Canvas.Brush.Color:=clRed;
    Canvas.Ellipse(ix-aga,iy-aga,ix+aga,iY+aga);
end;

function TElips.GetX(ang: Double): Double;
begin
 Result:=fa*cos(ang);
end;

function TElips.GetY(ang: Double): Double;
begin
 Result:=fb*sin(ang);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
 e:=TElips.Create(Width div 2,Height div 2,100,200,0);
 e.Canvas:=Canvas;
end;

procedure TForm1.FormPaint(Sender: TObject);
begin
 e.Draw;
end;

procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
 Repaint;
 Caption:=BoolToStr(e.PoinInEllips(x,y),true);
 e.DrawPnt(x,y);
end;

function TElips.PoinInEllips(x, y: Double): Boolean;
begin
 Result:= ((Sqr(fcx-X) / Sqr(fA)) + (Sqr(fcy-Y) / Sqr(fB))) < 1;
end;

end.
Здесь procedure TElips.DrawPnt; как раз должна рисовать точку на эллипсе, которая по идее при перемещении мышки будет за курсором "следить"
Но она вертится как уж на сковородке...
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 05.11.2010, 21:59   #12
alexBlack
Участник клуба
 
Регистрация: 12.10.2007
Сообщений: 1,204
По умолчанию

angx:= arccos(ang); - д.б. без приведения к градусам.

Но если рассматривать первую задачу, проблема в том, что в уравнениях
x = a cos(t)
y = b sin(t)
t это параметр, которых хотя и измеряется в радианах, но не соответствует углу от центра эллипса (есть небольшая разница. это можно увидеть если нарисовать лучи от центра элиипса).

Проще будет все-таки совместить систему координат.
Совмещаем центр эллипса с (0,0)
x = x - x0, y = y - y0
Поворачиваем
x = x cos(f) - y sin(f)
y = x sin(f) - y cos(f)
Теперь работаем с неповернутым эллипсом

x, y - координаты проверяемой точки
x0, y0 - координаты центра эллипса

Цитата:
Дык, так можно вместо поворота эллипса повернуть точку делов-то.
Я в общем-то точку и поворачиваю.
Что касается слежения за курсором мышки и вычисления точки по углу:

Код:
var fcx, fcy, fa, fb : integer;
    fangle : Single;

function GetQuadransRad(var a:Single):integer;
var n:integer;
begin
   if a > pi  then a := a - 2*pi;
   if a < -pi then a := a + 2*pi;

   n := 0;
   if a > 0 then begin
      if      (a >=  0)   and (a <= pi/2)  then n := 1
      else if (a >  pi/2) and (a <= pi)    then begin n := 2; a := pi-a; end
   end else begin
      if      (a <=   0)   and (a >= -pi/2) then begin n := 4; a := -a;        end
      else if (a <  -pi/2) and (a >= -pi  ) then begin n := 3; a := pi+a;      end
   end;
   result := n;
end;

function GetArcPoint(f, a, b:Single):TPoint;
var n:integer;
    t, x, y, t2, a2, b2:Single;
begin
   // Определяем в какой полуплоскости находится точка пересечения
   n := GetQuadransRad(f);

   if abs(f-pi/2) < 0.001 then begin
      x := 0; y := b;
   end else begin
      t := tan(f);
      t2 := t*t;
      b2 := b*b;
      a2 := a*a;
      x := sqrt((a2*b2) / (a2*t2+b2));
      y := x*t;
   end;
   case n of
      1 : begin x := +x; y := +y; end;
      2 : begin x := -x; y := +y; end;
      3 : begin x := -x; y := -y; end;
      4 : begin x := +x; y := -y; end;
   end;
   result.x := trunc(x);
   result.y := trunc(y);
end;

procedure TForm10.FormCreate(Sender: TObject);
begin
   fCX := Width div 2;
   fCY := Height div 2;
   fa := 100;
   fb := 200;
   fangle := 0;
end;

function GetX(ang: Double): Double;
begin
 Result:=fa*cos(ang);
end;

function GetY(ang: Double): Double;
begin
 Result:=fb*sin(ang);
end;

procedure TForm10.FormPaint(Sender: TObject);
var x,y,ang:double;ix,iy:Integer;
begin
 ang:=0;
 with Canvas do begin
   while ang<(2*pi) do begin
    x:=GetX(ang);
    y:=GetY(ang);
    ix:=round(x+fCx);
    iy:=round(y+fCy);
    if ang=0 then MoveTo(ix,iy) else    LineTo(ix,iy);
    ang:=ang+pi/18;

    Canvas.Moveto(fCx, fCy);
    Canvas.Lineto(ix, iy);
   end;
 end;
end;

procedure TForm10.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
const aga=10;
var ang,angx,angy,ln:double;ix,iy:Integer;
    x1, y1 : double;
    p : TPoint;
begin
    // Рассчитаем расстояние
    ln:=sqrt(sqr(x-fcx)+sqr(y-fcy));
    // Получим угол в градусах
    ang:=abs(x-fcx)/ln;
    angx:= arccos(ang);
    if x - fcx < 0 then angx := pi-angx;
    if y - fcy < 0 then angx := -angx;



    p := GetArcPoint(angx, fa, fb);

    Canvas.Brush.Style:=bsSolid;
    Canvas.Brush.Color:=clRed;
    Canvas.Ellipse(fcx+p.x-4,fcy+p.y-4,fcx+p.x+4,fcy+p.y+4);
end;

Последний раз редактировалось alexBlack; 05.11.2010 в 22:35.
alexBlack вне форума Ответить с цитированием
Старый 05.11.2010, 22:19   #13
Levsha100
Заблокирован
Старожил
 
Регистрация: 20.07.2008
Сообщений: 4,032
По умолчанию

Дык, так можно вместо поворота эллипса повернуть точку делов-то.
Levsha100 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Наклонный эллипс SomeBod Компоненты Delphi 2 12.02.2016 02:04
С вопросом о Rave я в этот раздел попала? J[OGR]A Помощь студентам 3 17.03.2009 10:19
где сдесь туплю не пойму Doget Помощь студентам 2 04.02.2009 08:46
Эллипс по параметрам rzrwolf Microsoft Office Excel 6 21.12.2008 01:47
Определить попала ли точка в область? Iogan Gamba Puti Общие вопросы Delphi 7 13.05.2008 00:15