gpt4 book ai didi

java - Android 包含弧上的方法无法正常工作

转载 作者:行者123 更新时间:2023-11-30 01:33:31 26 4
gpt4 key购买 nike

我有自定义 View 控件,如下所示:

enter image description here

在我的 Activity 中,我希望能够通过在绿色 Arcs 上拖动它来在屏幕上移动这个 View (向左或向右并不重要)。

还希望能够检测是否点击了顶部的黄色圆弧、中间圆弧或底部圆弧。

我无法检测水龙头在哪个区域。这是我在 Activity 中使用的代码:

float dX, dY;
final MyCustomView myCustomView = (MyCustomView)findViewById(R.id.test);
final Boolean[] movable = {false};

myCustomView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent event) {

switch (event.getActionMasked()) {

case MotionEvent.ACTION_DOWN:
movable[0] = false;

dX = view.getX() - event.getRawX();
dY = view.getY() - event.getRawY();

int x = (int) event.getX();
int y = (int) event.getY();

if (myCustomView.leftArcRegion.contains(x,y) || myCustomView.rightArcRegion.contains(x,y)){
movable[0] = true;
} else if (myCustomView.topArcRegion.contains(x,y)){
//todo: do something if top arc area is selected
} else if (myCustomView.midRoundedBitmapRegion.contains(x,y)){
//todo: do something if mid bitmap area is selected
} else if (myCustomView.bottomArcRegion.contains(x,y)){
//todo: do something if bottom arc area is selected
}
break;

case MotionEvent.ACTION_MOVE:
if (movable[0]) {
view.animate()
.x(event.getRawX() + dX)
.y(event.getRawY() + dY)
.setDuration(0)
.start();
}
break;

case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:


break;
default:
return false;
}
return true;
}
});

这些是我的自定义 View 控件中的公共(public)字段:

public Region topArcRegion;
private Path topArc;

//topArc is my top arc path
RectF rectFTop = new RectF();
topArc.computeBounds(rectFTop, true);
topArcRegion = new Region();
topArcRegion.setPath(topArc, new Region((int) rectFTop.left, (int) rectFTop.top,
(int) rectFTop.right, (int) rectFTop.bottom));

但在使用“包含”方法检查时,这些区域看起来像是使用矩形,而不是弧形。因此,我没有得到预期的结果。

那么,为了应用我的应用程序逻辑,我如何检测初始点击位置(顶部圆弧、底部圆弧、侧面圆弧或中间位图)?

最佳答案

由于您只想检测弧段内的触摸,因此应该不会太复杂。

您的每个弧段都定义为两个同心圆之间以及起始角和结束角之间的空间。因此,您真正想要做的就是进行一点三角运算,以确定从圆心到您的触摸点的距离以及从圆心到您的触摸点的角度。

float x = touchevent.getX();
float y = touchevent.getY();

// Transform relative to arc centers
x -= circle1.x;
y -= circle1.y;

double dist = Math.sqrt(x*x + y*y);
double angle = Math.atan2(y,x) * 180 / Math.PI;

// Given an arc segment defined by circle1, circle2, angle1, angle2:
boolean touch = dist > circle1.radius && dist < circle2.radius &&
angle > angle1 && angle < angle2;

您可能需要根据 angle1 > angle2 或反之亦然进行一些尝试。如果任何角度有可能与零度角相交,它就会变得有点棘手。


Meta:为清楚起见,我使用了 sqrt() 来计算距离,但您可以通过跳过 sqrt() 并改为比较 distance² 来优化此代码:

double dist2 = x*x + y*y;
if (dist2 > circle1.radius * circle1.radius &&
dist2 < circle2.radius * circle2.radius &&
...

再编辑一下:计算三角函数可能很昂贵;当然比计算距离²要昂贵得多。

为了优化,您应该在使用三角函数之前检查圆半径的距离:

boolean touch = dist > circle1.radius && dist < circle2.radius;
if (touch) {
// This is only a *possible* touch, check the angles now
double angle = Math.atan2(y,x) * 180 / Math.PI;
touch = angle > angle1 && angle < angle2;
}

关于java - Android 包含弧上的方法无法正常工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35414749/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com