gpt4 book ai didi

android - Google Sky Map 开源 - 如何将点击操作映射到对象?

转载 作者:太空狗 更新时间:2023-10-29 14:28:51 24 4
gpt4 key购买 nike

随着 Google Sky Map 几天前开源,我正在尝试使用它。不幸的是,我无法将用户的点击操作映射到对象(行星等...)。

这个的入口点是 GestureInterceptor.onDown(MotionEvent e) 我认为。

但是如何将 MotionEvent 映射到对象?我完全迷失在这里。

您可以在这里找到源代码:http://code.google.com/p/stardroid/source/browse/#svn%2Ftrunk%2Fapp

目前的结果:

 AstronomerModel model = StardroidApplication.getModel();
Pointing pointing = model.getPointing();

所以我有了模型,我可以得到视线。但是接下来需要做的是将点击坐标转换为地心坐标(如何?),然后找到位于这些坐标的对象(如何?)。

最佳答案

好的,这就是我所做的。

我捕获了标签 Geocentric Positions 并将它们全部存储在 ApplicationConstants 类中。您可以在 ProtobufAstronomicalSource.getLabels() 中获取它们,行星除外,您可以在 PlanetSource.initialize() 中获取它们。

然后,当用户点击时,调用com.google.android.stardroid.touch.GestureInterpreter类中的onSingleTapConfirmed方法。在此方法中,我获取了所有标签,使用以下代码将 Geocentric Postions 转换为屏幕位置:

    @Override
public boolean onSingleTapConfirmed(MotionEvent e) {
Log.d(TAG, "Confirmed single tap");

Point screen = ApplicationConstants.getSizeOfScreen();
int screenHeight = screen.y;
int screenWidth = screen.x;
float yClicked = screenHeight - e.getRawY(); //e.y is inverted, this normalizes it
float xClicked = e.getRawX();
ArrayList<Label> labelArray = ApplicationConstants.getLabels();
Log.d("LabelClicked", "label count: " + labelArray.size());
ArrayList<LabelScreen> labelsOnScreen = new ArrayList<LabelScreen>();
for (Label label : labelArray) {
//calculets current screen position of all labels, most of this code comes from LabelObjectManager.drawLabel()
Vector3 lookDir = ApplicationConstants.getLookDir();
if (lookDir.x * label.x + lookDir.y * label.y + lookDir.z * label.z < ApplicationConstants.getmDotProductThreshold()) {
//return;
}

Vector3 mLabelOffset = ApplicationConstants.getmLabelOffset();

// Offset the label to be underneath the given position (so a label will
// always appear underneath a star no matter how the phone is rotated)
Vector3 v = new Vector3(
label.x - mLabelOffset.x * label.offset,
label.y - mLabelOffset.y * label.offset,
label.z - mLabelOffset.z * label.offset);

Vector3 screenPos = Matrix4x4.transformVector(
ApplicationConstants.setTransformToScreenMatrix(),
v);

// We want this to align consistently with the pixels on the screen, so we
// snap to the nearest x/y coordinate, and add a magic offset of less than
// half a pixel. Without this, rounding error can cause the bottom and
// top of a label to be one pixel off, which results in a noticeable
// distortion in the text.
final float MAGIC_OFFSET = 0.25f;
screenPos.x = (int)screenPos.x + MAGIC_OFFSET;
screenPos.y = (int)screenPos.y + MAGIC_OFFSET;

//by Marcio Granzotto Rodrigues
if ((screenPos.x < 0.0f) | (screenPos.y < 0.0f)) {
//not on screen
}else if ((screenPos.x > screenWidth) | (screenPos.y > screenHeight)) {
//not on screen
}else if (screenPos.z < 0) {
//not on screen
}else {
//on screen
Log.d("LabelClicked", "on screen: " + label.getText() + " - " + screenPos.x + " " + screenPos.y + " " + screenPos.z);
LabelScreen labelScreen = new LabelScreen(label, screenPos);
labelsOnScreen.add(labelScreen);
}//end else
}//end for

Log.i("LabelClicked", "Labels on Screen: " + labelsOnScreen.size());
LabelScreen theLabel = null;
for (LabelScreen labelScreen : labelsOnScreen) {
if (true) { //TODO check if label is on the clickable list
if (theLabel == null) {
//defines first label
theLabel = labelScreen;
Log.i("LabelClicked", "theLabel null -> " + theLabel.getLabel().getText());
}else {
//check if this label is closer to the click area than theLabel
float theLabelRelativeX = theLabel.getScreenPos().x - xClicked;
float theLabelRelativeY = theLabel.getScreenPos().y - yClicked;
float myLabelRealativeX = labelScreen.getScreenPos().x - xClicked;
float myLabelRealativeY = labelScreen.getScreenPos().y - yClicked;

if ((Math.abs(myLabelRealativeX) < Math.abs(theLabelRelativeX))
&& (Math.abs(myLabelRealativeY) < Math.abs(theLabelRelativeY))) {
Log.i("LabelClicked", "theLabel " + theLabel.getLabel().getText() + " -> " + labelScreen.getLabel().getText());
theLabel = labelScreen;
}
}
}
}

float theLabelRelativeX = theLabel.getScreenPos().x - xClicked;
float theLabelRelativeY = theLabel.getScreenPos().y - yClicked;
if ((theLabelRelativeX < screenWidth*0.1f) && (theLabelRelativeY < screenHeight*0.1f)) {
//clicked
if (theLabel.getLabel().getText().equals(ApplicationConstants.myContext.getString(com.google.android.stardroid.R.string.moon))) {
//ìf the clicked label is the moon, checks phase (in portuguese)
String moonPhase = "";
switch (ApplicationConstants.getMoonPhase()) {
case ApplicationConstants.MOON_FULL:
moonPhase = " cheia";
break;
case ApplicationConstants.MOON_CRESCENT:
moonPhase = " crescente";
break;
case ApplicationConstants.MOON_NEW:
moonPhase = " nova";
break;
case ApplicationConstants.MOON_GIBBOUS:
moonPhase = " minguante";
break;
default:
break;
}
Toast.makeText(ApplicationConstants.myContext, theLabel.getLabel().getText() + moonPhase, Toast.LENGTH_SHORT).show();
Log.i("LabelClicked", "You clicked: " + theLabel.getLabel().getText() + moonPhase);
}else {
Toast.makeText(ApplicationConstants.myContext, theLabel.getLabel().getText(), Toast.LENGTH_SHORT).show();
Log.i("LabelClicked", "You clicked: " + theLabel.getLabel().getText());
}
}
return false;
}

希望对您有所帮助。

关于android - Google Sky Map 开源 - 如何将点击操作映射到对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8971148/

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