座標の求め方

解決


YUU  2005-01-07 04:08:47  No: 12600

たぶん、Delphiと言うよりも
数学の問題なのでしょうが、残念ながら
弱いので、よろしくお願いします。

直線を描画する扱いで、キャンバス上の
2点で長方形を書きたいのです。各角は90度
(実際には長方形の中に更に、線を引き図形にしたいので
Rectangleとは意味合いが違うのです)
2点(高さ)は、マウスで把握

マウスダウン(座標把握)>移動>マウスアップ(座標把握)と
2点の座標が、識別できている状態で
この2点は、四角形の左の上、左の下の点とし
右側に、20の幅を持つ四角形とします。

マウスダウン  10,10
マウスアップ  10,50
のように垂直な座標であれば、
右上の点は  10、10+20
右下の点は  10、50+20
と、単純に計算できますが
垂直でない場合、
右の上・下の座標はどの様な算式で求められるのでしょうか?
数学の公式の世界の気がしますが、解りません

例えば
マウスダウン(左上)  10,10
マウスアップ(左下)  30,50
の場合、右上・右下の座標を算出するには  
どの様な計算になるのでしょうか。
よろしくお願いします。


  2005-01-07 05:50:40  No: 12601

名前にぴったりだったので  即答♪

type XY_Rect = record
  TopLeft ,
  TopRight ,
  BottomLeft ,
  BottomRight : TPoint;
end;

// 左上(x1,y1)、左下(x2、y2)、右下(x3,y3)、右上(x4,y4)
function SampleRect(X1,Y1,X2,Y2 ,Haba: integer) : XY_Rect;
  var R : TRect;
      sin,cos :real;
begin
  Result.TopLeft    := Point(X1,Y1);
  Result.BottomLeft := Point(X2,Y2);

   sin := (x2-x1) / sqrt(sqr(x1-x2)+sqr(y1-y2));
   cos := (y1-y2) / sqrt(sqr(x1-x2)+sqr(y1-y2));

  Result.BottomRight.X := trunc(x2+ cos * Haba);
  Result.BottomRight.Y := trunc(y2+ sin * Haba);
  Result.TopRight.X    := trunc(x1+ cos * Haba);
  Result.TopRight.Y    := trunc(y1+ sin * Haba);

// var sin,cos :real;
//   sin :=(x2-x1) / sqrt(sqr(x1-x2)+sqr(y1-y2));
//   cos :=(y2-y1) / sqrt(sqr(x1-x2)+sqr(y1-y2));
// x := x1 + cos * a
// y := y1 + sin * a
end;

// var b : XY_Rect;
//  b := SampleRect(0,40, 0,0 ,20);
//  Canvas.Polygon([b.TopLeft,b.BottomLeft,b.BottomRight,b.TopRight]);

三平方の定理
+
おまけ
数学/三角関数(SIN、COS、TAN関数)
http://homepage1.nifty.com/kenzo30/ex_kisotyu/ex_ks_tyukyu9_7.htm


  2005-01-07 06:13:52  No: 12602

原点左下で計算してるから
数字入れるとき注意してね。


YUU  2005-01-07 07:39:48  No: 12603

△さん、早速の書き込み
ありがとうございます。
三平方の定理???ですが、勉強してみます。
ソースも書いていただいたので  試してみましたが
使いこなせません。
それで  自分の、質問を見直していて大きな間違いに気が付きました。
右側に幅を取るのだから  幅20としたばあい
マウスダウン  10,10
マウスアップ  10,50
のように垂直な座標であれば、
右上の点は  10+20、10
右下の点は  10+20、50
が欲しい値です。
質問の内容はyを+20していました。

しかし、キャンバス上で  逆に
下から上にマウス操作した場合は  
マウスダウン  10,50
マウスアップ  10,10
垂直でも右側は反転して、(実際には左側に)
右上の点は  10-20、50
右下の点は  10-20、10
と、反対にならないといけないし・・
計算で求めることは難しいですかね


  2005-01-07 08:55:29  No: 12604

unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    Edit1: TEdit;
    procedure FormMouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure FormMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
  private
    { Private 宣言 }
  public
    { Public 宣言 }
    MouseDownXY : TPoint;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

type XY_Rect = record
  TopLeft ,
  TopRight ,
  BottomLeft ,
  BottomRight : TPoint;
end;

// Canvasは、上に原点があるので、出力時に混同しないように。
// 数字で考えましょう。
// 左上(x1,y1)、左下(x2、y2)、右下(x3,y3)、右上(x4,y4)
function SampleRect(X1,Y1,X2,Y2 ,Haba: integer) : XY_Rect;
  var R : TRect;
      sin,cos :real;
begin
  Result.TopLeft    := Point(X1,Y1);
  Result.BottomLeft := Point(X2,Y2);

   sin := (x2-x1) / sqrt(sqr(x1-x2)+sqr(y1-y2));
   cos := (y1-y2) / sqrt(sqr(x1-x2)+sqr(y1-y2));

  Result.BottomRight.X := trunc(x2+ cos * Haba);
  Result.BottomRight.Y := trunc(y2+ sin * Haba);
  Result.TopRight.X    := trunc(x1+ cos * Haba);
  Result.TopRight.Y    := trunc(y1+ sin * Haba);
end;

procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  MouseDownXY := Point(x,y);
end;

procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
  var MouseXY : XY_Rect;
begin
  with MouseXY do
  begin
    if (MouseDownXY.y<=y) then
      begin  // 座標の上下関係代入。
        TopLeft := Point(x,y);
        BottomLeft := MouseDownXY;
      end
      else
      begin
        TopLeft := MouseDownXY;
        BottomLeft := Point(x,y);
      end;

    MouseXY := SampleRect(TopLeft.x,TopLeft.y
                      , BottomLeft.x,BottomLeft.y
                      , StrToInt(Edit1.text));
      // Haba + : 画面右に
      // Haba - : 画面左に
    Canvas.Polygon([TopLeft,BottomLeft,BottomRight,TopRight]);
  end;
end;

end.


YUU  2005-01-07 09:16:07  No: 12605

△さん、この時間まで  またユニットソース毎提示していただき
ありがとうございました。
動かしてみました。
思い通りの座標で描画されます。
提示していただいたソースを元に、
意味合いを理解しようと思います。
本当に、ありがとうございました。


  2005-01-07 09:38:08  No: 12606

解決できてよかったですね。

頭で考えるとこんがらがるので、
いらない紙に  縦横十字線を引いて四角を描いて、
四角のかどに順番に(X1,Y1),(X2,Y2),(X3,Y3),(X4,Y4)と書くとわかりやすいですよ


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加