たぶん、Delphiと言うよりも
数学の問題なのでしょうが、残念ながら
弱いので、よろしくお願いします。
直線を描画する扱いで、キャンバス上の
2点で長方形を書きたいのです。各角は90度
(実際には長方形の中に更に、線を引き図形にしたいので
Rectangleとは意味合いが違うのです)
2点(高さ)は、マウスで把握
マウスダウン(座標把握)>移動>マウスアップ(座標把握)と
2点の座標が、識別できている状態で
この2点は、四角形の左の上、左の下の点とし
右側に、20の幅を持つ四角形とします。
マウスダウン 10,10
マウスアップ 10,50
のように垂直な座標であれば、
右上の点は 10、10+20
右下の点は 10、50+20
と、単純に計算できますが
垂直でない場合、
右の上・下の座標はどの様な算式で求められるのでしょうか?
数学の公式の世界の気がしますが、解りません
例えば
マウスダウン(左上) 10,10
マウスアップ(左下) 30,50
の場合、右上・右下の座標を算出するには
どの様な計算になるのでしょうか。
よろしくお願いします。
名前にぴったりだったので 即答♪
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
原点左下で計算してるから
数字入れるとき注意してね。
△さん、早速の書き込み
ありがとうございます。
三平方の定理???ですが、勉強してみます。
ソースも書いていただいたので 試してみましたが
使いこなせません。
それで 自分の、質問を見直していて大きな間違いに気が付きました。
右側に幅を取るのだから 幅20としたばあい
マウスダウン 10,10
マウスアップ 10,50
のように垂直な座標であれば、
右上の点は 10+20、10
右下の点は 10+20、50
が欲しい値です。
質問の内容はyを+20していました。
しかし、キャンバス上で 逆に
下から上にマウス操作した場合は
マウスダウン 10,50
マウスアップ 10,10
垂直でも右側は反転して、(実際には左側に)
右上の点は 10-20、50
右下の点は 10-20、10
と、反対にならないといけないし・・
計算で求めることは難しいですかね
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.
△さん、この時間まで またユニットソース毎提示していただき
ありがとうございました。
動かしてみました。
思い通りの座標で描画されます。
提示していただいたソースを元に、
意味合いを理解しようと思います。
本当に、ありがとうございました。
解決できてよかったですね。
頭で考えるとこんがらがるので、
いらない紙に 縦横十字線を引いて四角を描いて、
四角のかどに順番に(X1,Y1),(X2,Y2),(X3,Y3),(X4,Y4)と書くとわかりやすいですよ
ツイート | ![]() |