閉じた図形のマウスヒットテスト
2010.8.26

Language

トピックス

閉じた図形のマウスヒットテスト
2010.08.26


閉じていない図形のマウスヒットテスト
2010.08.26


任意2曲線の交点計算
2010.09.01


点から曲線への垂線の計算
2010.09.01


2曲線への共通垂線の計算
2016.10.20


Input Method Frameworkによる
テキストエディター
2010.12.01


部品ライブラリ
2012.09.16


専用カラーチューザー
2012.9.23



Chapter: 1. ソースコードダウンロード, 2. テスト結果, 3. テスト項目・方法, 4. テスト結果についてのコメント, 5. Test code

1. ソースコードダウンロード

=> RegionHitTest.zip



2. テスト結果戻る=>page top

図1 テストされる閉図形
テストは閉図形に対してのみ有効であるが、参考までに閉じていない図形に対しても行う。

図2 テスト結果
格子点ごとにヒットテストを行い結果を色で表示 - 青色:閉図形の内側, 灰色:外側, 赤色:境界上


3. テスト項目・方法戻る=>page top

java.awt.Shape interfaceで定義されるcontainsメソッドが閉図形(境界が閉曲線)のマウスヒットテストに有効で信頼性が高いかをテストする。ここでマウスヒットテストとはマウスの位置が表示中の閉図形のどこに位置しているかを判定するテストで、(1)内部、(2)外部、(3)境界上、と言った判定ができればよい。
この判定は図形の境界をクリックしたときにその図形が選択される、という風に使われるので境界線はある一定の幅をもっていると想定して行う。境界線の幅が0ピクセルだと、図形の選択は非常に難しくなるので実用的ではない。


さてjava.awt.Shape interfaceで定義されるcontainsメソッドは指定された点が図形の境界の内側にあるか否かを判定するメソッドである。この判定は境界の幅が0として行われる。したがってcontainsメソッドを利用してマウスヒットテストはつぎのように実行できる。


マウス位置の周りに4点のテスト点を考え、containsメソッドでこの4点が各々閉図形の内側にあるか否かを判定する。



(1)4点全てが閉図形の内部にあれば、マウスは図形の内部に位置している。
(2)4点全てが閉図形の外部にあれば、マウスは図形の外部に位置している
(3)(a), (b)以外の場合は、マウスは図形の境界上に位置している




<
(1) 閉図形の内部 (2) 閉図形の外部 (3) 境界上


4. テスト結果についてのコメント戻る=>page top

図2からわかるように、本テストは閉じていない図形 (Ex1, Ex5, Ex6, Ex9) に対しては使えない。始点、終点を結ぶ直線上ではマウスは境界上にあると判断されるため、ここをクリックすると図形が選択されてしまう。
したがって閉じていない図形に対しては、別の方法が必要である。
=> 閉じていない図形のマウスヒットテスト


5. Test code戻る=>page top

5.1 クラス一覧

クラス

説明

RegionHitTest

public class RegionHitTest extends JFrame
Jframe, JScrollPane, JViewport, Panelオブジェクトを作成し組み立てる。

RegionHitPanel

public class RegionHitPanel extends JPanel

このオブジェクトの上に図1, 図2のような図形を描画する。

TestCase class TestCase
1件のテストの構成データをストア。
TestCurve

public class TestCurve

テストに使う曲線を作成する。

パラメトリック曲線のクラス Segment2D, Curve2D, Rectangle2DE, RoundRectangle2DE, Ellipse2DE, Line2DE, Polyline2DE, CubicCurve2DE, GeneralCurve2DE, FergusonCurve2D
幾何計算ライブラリ Matrix, Matrix2D


5.2 クラス仕様
5.2.1 public class RegionHitPanel extends JPanel

メソッド

説明

createTestCase

public void createTestCase()

TestCaseオブジェクトを作成する。

getEnlargedBoundingBox

public Rectangle2D getEnlargedBoundingBox(Rectangle2D boundingBox, double wideEx, double heightEx)

引数:

box - Rectangle2D オブジェクト
wideEx - 水平方法の延長量
heightEx - 垂直方法の延長量.
戻り値:

拡大したRectangle2D オブジェクトを返す

処理:

引数で指定したRectangle2D オブジェクトを拡大して返す。

getGridPoints

public Point2D[] getGridPoints(Rectangle2D box)

引数:

box - Rectangle2D オブジェクト。
戻り値:

box内部に生成した格子点。

処理:

引数で指定したRectangle2D オブジェクトの内部に格子点を生成して返す。

=>図2の各表示図形内の格子点。

containsPT

public int containsPT(Shape shape, Point2D point)

引数:
shape - 閉図形
point - テストされる点(マウスの位置)

戻り値:
0 - shapeの外側
1 - shapeの内側
2 - shapeの境界上
処理:
点pointが shapeのどの位置にあるかを判定し、結果を0, 1 または 2で返す。

paint

public void paint(Graphics g)

処理:

このクラス(Panel)のオブジェクトに描画する。
paintShapesメソッドでTestCaseオブジェクトの図形を描画(図1)、paintContainsTestメソッドでマウスヒットテストの結果(図2)を描画する。

paintShapes

public void paintShapes(Graphics g)

処理:

TestCaseオブジェクトの図形を描画(図1)する。

paintContainsTest

public void paintContainsTest(Graphics g)

処理:

マウスヒットテストの結果(図2)を描画する(図2)。



5.2.2 public class TestCase

フィールド

説明

title

public String title = "";

テストケースのタイトル。図1図2のLine2DE, Rectangle2DEなどの文字列。

targetShape

public Curve2D targetShape

ターゲット図形オブジェクト。図形オブジェクトはCurve2Dクラス。

targetShapes public Curve2D[] targetShapes
ターゲット図形オブジェクトを複数格納。図形オブジェクトは Curve2Dクラス。
NormalLinesBetweenShapesBasic, NormalLinesBetweenShapesで使用。
testShape public Curve2D testShape
テスト図形オブジェクト。
testShapes public Curve2D[] testShapes
テスト図形オブジェクトを複数格納。
NormalLinesBetweenShapesBasic, NormalLinesBetweenShapesで使用。
testPoints public Point2D[] testPoints
getGridPointsメソッドで作成される格子点。図2に表示されている格子点で、各格子点についてフィールド変数targetShapeの外側/内側/境界上のいずれかかが判定される。

moveVector public Vector2D moveVector
testShapeなどを平行移動して、テストするときに指定する。
moveMax public int moveMax=0
testShapeなどを平行移動する回数。
drawRectangle public Rectangle2D drawRectangle
テストの表示エリア。
maxBoundingBox public Rectangle2D maxBoundingBox
setMaxBoundingBoxで設定する。boundingBoxの最大のものとストアする。

メソッド

説明

moveTestShape public static Curve2D moveTestShape(Curve2D testShape, double moveX, double moveY);
testShapeなどを移動、コピーして、そのオブジェクトを戻り値で返す。
setMaxBoundingBox public void setMaxBoundingBox(Rectangle2D box);
現在のフィールド変数maxBoundingBoxの矩形と、引数boxの矩形の両方を覆えるように フィールド変数maxBoundingBoxを更新する。
setMaxBoundingBox ublic void setMaxBoundingBox(Point2D point);
現在のフィールド変数maxBoundingBoxの矩形と、引数pointの点の両方を覆えるように フィールド変数maxBoundingBoxを更新する。


5.2.3 public class TestCurve
下図の図形を作成する。



Copyright (c) 2009-2013
All other trademarks are property of their respective owners.