取っかかりがつかめずに行き詰まっております。
どなたかアドバイスや参考サイト、検索キーワードなど、
なにか教えて頂けないでしょうか?
[やりたいこと]
1.地図画像を表示させ、
2.その中のある地域を囲んだ線を表示させ、
3.マウスがそのエリア内に来たら、
線の色を変えて表示
こんなことを実現したいです。
2と3の部分をどうすれば実現できますでしょうか?
// ちなみに、2の部分も線でなく画像(ある地域の形をした背景透過GIF)で
// 済ませられると、とても楽なのですが、こんなことは
// 多分無理なのでしょうね...。
どうぞよろしくお願いいたします。
(環境:Delphi2010)
Image に地図画像を表示させ
OnMouseMove で X,Y の値が
2.その中のある地域を囲んだ線を表示させ、
の領域内にきたら
線の色を変えて表示
KHE00221さん
ありがとうございました。
お教え頂いたキーワードから、imageを2つと Canvas を使ってみました。
しかし、[ある地域を囲んだ線を表示] でつまづいてしまいました。
結果は下のGyazo画面のように、範囲外が白く塗りつぶされてしまうのですが、
範囲外も透過させるにはどうすればいいのでしょうか?
http://gyazo.com/7fd55e4c9082ac5bbc751ba652f28673
一応、いまのソースはこれです。
procedure TForm1.Button1Click(Sender: TObject);
begin
//Image1へ背景図読み込み
Image1.Picture.LoadFromFile('map.gif');
//Image2へ図形描画
Image2.Transparent:=True;
image2.Canvas.Polygon([
Point(20,20),
Point(200,20),
Point(220,170),
Point(20,150)
]);
end;
追記です。
Polyline だと、中も外も白くなってしまうのですね・・・
http://gyazo.com/11d51a38e4d0d30e60ab0380691d8b1f
procedure TForm1.Button2Click(Sender: TObject);
var
Points : array[0..4] of TPoint;
begin
//背景図読み込み
Image1.Picture.LoadFromFile('map.gif');
//図形描画
Image2.Transparent:=True;
Points[0] := Point(20,20);
Points[1] := Point(200,20);
Points[2] := Point(220,170);
Points[3] := Point(20,150);
Points[4] := Point(20,20);
image2.Canvas.Polyline(Points);
end;
結局、VCLのリファレンスを読まないことには、目的の動作をするにはどの関数を組み合わせたら良いかは分かりません。
ポリゴン描画で中を透明にしたければ、
image2.Canvas.Brush.Style := bsClear;です。
TImageはあくまで表示専用ですので、
描画を色々変更する場合はその他にイメージを保持しておかなくてはなりません。
YYさんがやりたい事はこんな感じですかね?
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics,
Controls, Forms, ExtCtrls, GIFimg;
type
TMyPolygon = class(TObject)
private
fPolygon : array of TPoint;
function GetCount: Integer;
procedure SetCount(const Value: Integer);
function GetPolygon(aIndex: Integer): TPoint;
procedure SetPolygon(aIndex: Integer; const Value: TPoint);
public
function IsIn(aPos:TPoint):Boolean;
procedure Add(aPos:TPoint);
procedure Draw(aCanvas:TCanvas; aColor:TColor);
property Count:Integer read GetCount write SetCount;
property Polygon[aIndex:Integer]:TPoint read GetPolygon write SetPolygon;
end;
TForm1 = class(TForm)
Image1: TImage;
procedure FormCreate(Sender: TObject);
procedure Image1MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure Image1MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
procedure Image1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
private
{ Private 宣言 }
fPolygon : array of TPoint;
fMyPolygonInMouse:Boolean;
fMyPolygon:TMyPolygon;
fBmp:TBitmap;
procedure Draw;
public
{ Public 宣言 }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
//http://delfusa.main.jp/delfusafloor/archive/www.nifty.ne.jp_forum_fdelphi/samples/00786.html
function PolygonExterior(x,y,n:integer;pt:array of TPoint):boolean;
var i,ct,nx,dx,dy,rx,ry:integer;
begin
pt[n]:=pt[0]; {始点は終点と等しいとします}
ct :=0;
for i:=0 to n-1 do begin
rx:=x-pt[i].x;
nx:=x-pt[i+1].x;
if ((rx<0)and(nx>=0)) or ((rx>=0) and (nx<0)) then begin
ry:=y-pt[i].y;
dx:= pt[i+1].x- pt[i].x;
dy:= pt[i+1].y- pt[i].y;
if longint(rx)*longint(dy)<longint(ry)*longint(dx)
then Inc (ct) else Dec(ct);
end;
end;
Result:=ct=0;
end;
{ TMyPolygon }
procedure TMyPolygon.Add(aPos: TPoint);
var
aCount:Integer;
begin
aCount := Count;
SetLength(fPolygon,aCount+1);
Polygon[aCount]:=aPos;
end;
procedure TMyPolygon.Draw(aCanvas: TCanvas; aColor: TColor);
var
i: Integer;
begin
if Count <= 0 then
Exit;
aCanvas.Pen.Color := aColor;
//aCanvas.Brush.Style := bsClear;
//aCanvas.Polyline(fPolygon);
aCanvas.MoveTo(Polygon[Count-1].X,Polygon[Count-1].Y);
for i := 0 to Count-1 do
aCanvas.LineTo(Polygon[i].X,Polygon[i].Y);
end;
function TMyPolygon.GetCount: Integer;
begin
Result:=Length(fPolygon);
end;
function TMyPolygon.GetPolygon(aIndex: Integer): TPoint;
begin
Result := fPolygon[aIndex];
end;
function TMyPolygon.IsIn(aPos: TPoint): Boolean;
begin
Result:= not PolygonExterior(aPos.X,aPos.Y,Count,fPolygon);
end;
procedure TMyPolygon.SetCount(const Value: Integer);
begin
SetLength(fPolygon,Value);
end;
procedure TMyPolygon.SetPolygon(aIndex: Integer; const Value: TPoint);
begin
fPolygon[aIndex]:=Value;
end;
{ TForm1 }
procedure TForm1.Draw;
begin
Image1.Canvas.Draw(0,0,fBmp);
if fMyPolygonInMouse then
fMyPolygon.Draw(Image1.Canvas,clRed) else
fMyPolygon.Draw(Image1.Canvas,clBlue);
end;
procedure TForm1.FormCreate(Sender: TObject);
var
aGif:TGIFImage;
begin
fMyPolygon := TMyPolygon.Create;
aGif := TGIFImage.Create;
aGif.LoadFromFile('test.gif');
fBmp := TBitmap.Create;
fBmp.Assign(aGif);
aGif.Free;
Draw;
end;
procedure TForm1.Image1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
fMyPolygon.Count:=0;
Draw;
fMyPolygon.Add(Point(X,Y));
Image1.Canvas.Pen.Color := clAqua;
Image1.Canvas.MoveTo(X,Y);
end;
procedure TForm1.Image1MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
var
aBool:Boolean;
begin
if ssLeft in Shift then
begin
Image1.Canvas.LineTo(X,Y);
fMyPolygon.Add(Point(X,Y));
end else begin
aBool := fMyPolygonInMouse;
fMyPolygonInMouse := fMyPolygon.IsIn(Point(X,Y));
if aBool <> fMyPolygonInMouse then
Draw;
end;
end;
procedure TForm1.Image1MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
fMyPolygonInMouse := fMyPolygon.IsIn(Point(X,Y));
Draw;
end;
end.
monaaさん
ご丁寧なアドバイス、ありがとうございます。
多角形の内と外の判定 も見させて頂きました。
私が到底みつけられない答えでまだ理解もできてません。
ひとつひとつ理解して、なんとか身につけていきたいと思います。
KHE00221さん、monaaさん
ありがとうございました。
ツイート | ![]() |