title: In ARCore, how do I best place a triangle in my world near a Pose, that I can use for ray intersection?
body: <p>I'm working with ARCore in Android Studio using java and am trying to implement ray intersection with an object.
  I started with Google's provided sample (as found here: <a href="https://developers.google.com/ar/develop/java/getting-started" rel="nofollow noreferrer">https://developers.google.com/ar/develop/java/getting-started</a>).
  Upon touching the screen, a ray gets projected and when this ray touches a Plane, a PlaneAttachment (with an Anchor/a Pose) is created in the intersection point.</p>
  
  <p>I would then like to put a 3D triangle in the world attached to this Pose.
  At the moment I create my Triangle based on the Pose's translation, like this:</p>
  
  <p><strong>In HelloArActivity, during onDrawFrame(...)</strong></p>
  
  <pre><code>//Code from sample, determining the hits on planes
  MotionEvent tap = mQueuedSingleTaps.poll();
  if (tap != null &amp;&amp; frame.getTrackingState() == TrackingState.TRACKING) {
      for (HitResult hit : frame.hitTest(tap)) {
          // Check if any plane was hit, and if it was hit inside the plane polygon.
          if (hit instanceof PlaneHitResult &amp;&amp; ((PlaneHitResult) hit).isHitInPolygon()) {
              mTouches.add(new PlaneAttachment(
                  ((PlaneHitResult) hit).getPlane(),
                  mSession.addAnchor(hit.getHitPose())));
  
              //creating a triangle in the world
              Pose hitPose = hit.getHitPose();
              float[] poseCoords = new float[3];
              hitPose.getTranslation(poseCoords, 0);
  
              mTriangle = new Triangle(poseCoords);
          }
      }
  }
  </code></pre>
  
  <p>Note: I am aware that the triangle's coordinates should be updated every time the Pose's coordinates get updated. I left this out as it is not part of my issue.</p>
  
  <p><strong>Triangle class</strong></p>
  
  <pre><code>public class Triangle {
      public float[] v0;
      public float[] v1;
      public float[] v2;
  
      //create triangle around a given coordinate
      public Triangle(float[] poseCoords){
          float x = poseCoords[0], y = poseCoords[1], z = poseCoords[2];
          this.v0 = new float[]{x+0.0001f, y-0.0001f, z};
          this.v1 = new float[]{x, y+ 0.0001f, z-0.0001f};
          this.v2 = new float[]{x-0.0001f, y, z+ 0.0001f};
  }
  </code></pre>
  
  <p>After this, upon tapping the screen again I create a ray projected from the tapped (x,y) part of the screen, using <em>Ian M</em> his code sample provided in the answer to this question: <a href="https://stackoverflow.com/questions/46017301/how-to-check-ray-intersection-with-object-in-arcore">how to check ray intersection with object in ARCore</a></p>
  
  <p><strong>Ray Creation, in HelloArActivity</strong></p>
  
  <pre><code>/**
   * Returns a world coordinate frame ray for a screen point.  The ray is
   * defined using a 6-element float array containing the head location
   * followed by a normalized direction vector.
   */
  float[] screenPointToWorldRay(float xPx, float yPx, Frame frame) {
      float[] points = new float[12];  // {clip query, camera query, camera origin}
      // Set up the clip-space coordinates of our query point
      // +x is right:
      points[0] = 2.0f * xPx / mSurfaceView.getMeasuredWidth() - 1.0f;
      // +y is up (android UI Y is down):
      points[1] = 1.0f - 2.0f * yPx / mSurfaceView.getMeasuredHeight();
      points[2] = 1.0f; // +z is forwards (remember clip, not camera)
      points[3] = 1.0f; // w (homogenous coordinates)
  
      float[] matrices = new float[32];  // {proj, inverse proj}
      // If you'll be calling this several times per frame factor out
      // the next two lines to run when Frame.isDisplayRotationChanged().
      mSession.getProjectionMatrix(matrices, 0, 1.0f, 100.0f);
      Matrix.invertM(matrices, 16, matrices, 0);
      // Transform clip-space point to camera-space.
      Matrix.multiplyMV(points, 4, matrices, 16, points, 0);
      // points[4,5,6] is now a camera-space vector.  Transform to world space to get a point
      // along the ray.
      float[] out = new float[6];
      frame.getPose().transformPoint(points, 4, out, 3);
      // use points[8,9,10] as a zero vector to get the ray head position in world space.
      frame.getPose().transformPoint(points, 8, out, 0);
      // normalize the direction vector:
      float dx = out[3] - out[0];
      float dy = out[4] - out[1];
      float dz = out[5] - out[2];
      float scale = 1.0f / (float) Math.sqrt(dx*dx + dy*dy + dz*dz);
      out[3] = dx * scale;
      out[4] = dy * scale;
      out[5] = dz * scale;
      return out;
  }
  </code></pre>
  
  <p>The result of this however is that, no matter where I tap the screen, it always counts as a hit (regardless of how much distance I add between the points, in Triangle's constructor).</p>
  
  <p>I <em>suspect</em> this has to do with how a Pose is located in the world, and using the Pose's translation coordinates as a reference point for my triangle is not the way to go, so I'm looking for the correct way to do this, but any remarks regarding other parts of my method are welcome!</p>
  
  <p>Also I have tested my method for ray-triangle intersection and I don't think it is the problem, but I'll include it here for completeness:</p>
  
  <pre><code>public Point3f intersectRayTriangle(CustomRay R, Triangle T) {
      Point3f I = new Point3f();
      Vector3f    u, v, n;
      Vector3f    dir, w0, w;
      float     r, a, b;
  
      u = new Vector3f(T.V1);
      u.sub(new Point3f(T.V0));
      v = new Vector3f(T.V2);
      v.sub(new Point3f(T.V0));
      n = new Vector3f(); // cross product
      n.cross(u, v);
  
      if (n.length() == 0) {
          return null;
      }
  
      dir = new Vector3f(R.direction);
      w0 = new Vector3f(R.origin);
      w0.sub(new Point3f(T.V0));
      a = -(new Vector3f(n).dot(w0));
      b = new Vector3f(n).dot(dir);
  
      if ((float)Math.abs(b) &lt; SMALL_NUM) {
          return null;
      }
  
      r = a / b;
      if (r &lt; 0.0) {
          return null;
      }
  
      I = new Point3f(R.origin);
      I.x += r * dir.x;
      I.y += r * dir.y;
      I.z += r * dir.z;
  
      return I;
  }
  </code></pre>
  
  <p>Thanks in advance!</p>