私は問題を解決することを確認簡単な方法は存在するが、これは次のように行うことができないです:あなたは、実行時にすべてのこれらの変数を持っているので、
解析ベクトルXML。あなたはすべてのフィールドを簡単にするためにハードコードされている参照として
private static class VectorData {
private int width = 24;
private int height = 24;
private double viewportHeight = 1052.3622;
private double viewportWidth = 744.0945;
private String path = "M182.9,349.5m-74.7,0a74.7,74.7 0,1 1,149.3 0a74.7,74.7 0,1 1,-149.3 0";
private double scaleVectorX(Context context) {
return dpToPx(context, width)/viewportWidth;
}
private double scaleVectorY(Context context) {
return dpToPx(context, height)/viewportHeight;
}
private static float dpToPx(Context context, float dp) {
return dp * context.getResources().getDisplayMetrics().density;
}
}
:構文解析はここで覆われていない、あなたは私たちが以降で動作するデータ構造を以下したと仮定しましょう。
android.graphics.Path path = android.util.PathParser.createPathFromPathData(vectorData.path);
android.util.PathParserが含まれていませんが、あなたはここにソースを見つけることができます:
次のステップは、android.graphics.Pathに変換ベクトルパスデータを解析することですhttps://android.googlesource.com/platform/frameworks/base/+/17e64ffd852f8fe23b8e2e2ff1b62ee742af17a6/core/java/android/util/PathParser.java。それをコピーして使用することがどれほど合法であるかはわかりません。
パスを持つと、N個の点(座標)を見つける必要があります。より多くのポイント - より正確な結果があることと遅く処理されます:
final Collection<Point> points = getPoints(path, iv.getX(), iv.getY(), vectorData);
private static class Point {
private float x;
private float y;
Point(float x, float y) {
this.x = x;
this.y = y;
}
@Override
public String toString() {
return "Point{" +
"x=" + x +
", y=" + y +
'}';
}
}
private Collection<Point> getPoints(Path path, float viewX, float viewY, VectorData vectorData) {
Collection<Point> points = new ArrayList<>();
PathMeasure pm = new PathMeasure(path, false);
float length = pm.getLength();
float distance = 0f;
int size = N;
float speed = length/size;
int counter = 0;
float[] aCoordinates = new float[2];
while ((distance < length) && (counter < size)) {
// get point from the path
pm.getPosTan(distance, aCoordinates, null);
float pathX = aCoordinates[0];
float pathY = aCoordinates[1];
float x = (float) (vectorData.scaleVectorX(this) * pathX) + viewX;
float y = (float) (vectorData.scaleVectorY(this) * pathY) + viewY;
points.add(new Point(x, y));
counter++;
distance = distance + speed;
}
return points;
}
パス - 私たちは前に取得する私たちのパスがあり、IVは - (例えば、ImageViewの)ベクトルコンテナである、我々はポイントの座標を調整するためにそれを必要とします。 vectorData - ベクトルを解析する前に取得した構造体です。
は、今、私たちは、パスが閉じられている場合を処理するための領域を画定する必要があると我々は0距離としてパスの内側をクリック扱いたい:
方法を、次の分の距離を計算するために
final Region region = new Region();
RectF rectF = new RectF();
path.computeBounds(rectF, true);
region.setPath(path, new Region((int) rectF.left, (int) rectF.top, (int) rectF.right, (int) rectF.bottom));
を使用する必要があります。
private int getMinDistance(float eventX, float eventY, Collection<Point> pathPoints, Region pathRegion, VectorData vectorData) {
int minDistance = Integer.MAX_VALUE;
boolean contains = pathRegion.contains((int) (eventX/vectorData.scaleVectorX(this)), (int) (eventY/vectorData.scaleVectorY(this)));
if (contains) {
minDistance = 0;
} else {
for (Point point : pathPoints) {
int distance = getDistanceBetweenPoints((int) eventX, (int) eventY, (int) point.x, (int) point.y);
if (distance < minDistance) {
minDistance = distance;
}
}
}
return minDistance;
}
private int getDistanceBetweenPoints(int x, int y, int x1, int y1) {
return (int) Math.sqrt((x1 - x) * (x1 - x) + (y1 - y) * (y1 - y));
}
あなたのコードがどれほど単純かに依存します。 – petey