Repository: flutter
Issue: Add motivation to globalToLocal implementation comments
Labels: framework,d: api docs,P2,team-framework,triaged-framework

The implementation of `globalToLocal` includes a blob of comments about projection and z-coordinates and perspective vs orthogonal. I'll reproduce the implementation below:

```dart
    /// Convert the given point from the global coordinate system in logical pixels
  /// to the local coordinate system for this box.
  ///
  /// This method will un-project the point from the screen onto the widget,
  /// which makes it different from [MatrixUtils.transformPoint].
  ///
  /// If the transform from global coordinates to local coordinates is
  /// degenerate, this function returns [Offset.zero].
  ///
  /// If `ancestor` is non-null, this function converts the given point from the
  /// coordinate system of `ancestor` (which must be an ancestor of this render
  /// object) instead of from the global coordinate system.
  ///
  /// This method is implemented in terms of [getTransformTo].
  Offset globalToLocal(Offset point, { RenderObject? ancestor }) {
    // We want to find point (p) that corresponds to a given point on the
    // screen (s), but that also physically resides on the local render plane,
    // so that it is useful for visually accurate gesture processing in the
    // local space. For that, we can't simply transform 2D screen point to
    // the 3D local space since the screen space lacks the depth component |z|,
    // and so there are many 3D points that correspond to the screen point.
    // We must first unproject the screen point onto the render plane to find
    // the true 3D point that corresponds to the screen point.
    // We do orthogonal unprojection after undoing perspective, in local space.
    // The render plane is specified by renderBox offset (o) and Z axis (n).
    // Unprojection is done by finding the intersection of the view vector (d)
    // with the local X-Y plane: (o-s).dot(n) == (p-s).dot(n), (p-s) == |z|*d.
    final Matrix4 transform = getTransformTo(ancestor);
    final double det = transform.invert();
    if (det == 0.0) {
      return Offset.zero;
    }
    final Vector3 n = Vector3(0.0, 0.0, 1.0);
    final Vector3 i = transform.perspectiveTransform(Vector3(0.0, 0.0, 0.0));
    final Vector3 d = transform.perspectiveTransform(Vector3(0.0, 0.0, 1.0)) - i;
    final Vector3 s = transform.perspectiveTransform(Vector3(point.dx, point.dy, 0.0));
    final Vector3 p = s - d * (n.dot(s) / n.dot(d));
    return Offset(p.x, p.y);
  }
```

When debugging coordinate mapping in custom `RenderObject`s and `ContainerLayer`s, it's important to understand what this method is doing and why.

The current explanation might make sense to those who work a lot with Linear Algebra and/or compositors, but I think it's more likely to confuse the average developer than to help.

One important thing that's missing for the average developer is the motivation. It's assumed that the developer who's reading this already knows why there's a z-offset involved with this calculation. But that's not obvious.

We know that we're dealing with a two dimensional screen. We're mapping a two dimensional `Offset` to another two dimensional `Offset`, so why would we immediately be concerned about "...we can't simply transform 2D screen point to the 3D local space since the screen space lacks the depth component |z|...". Why are we talking about "3D local space"? The existing comment seems to represent the explanation for a solution to a problem, but without a description of the problem. It's missing the motivation.

Second, there's a mention of a degenerate transform matrix. This kind of thing pops up in a number of locations in transformation code within Flutter. But what's lacking in all of those locations is any comment or doc mention of what it means to have a degenerate matrix. If such a situation arises, what does that likely say about the geometry of the render objects or layers? What should a developer take away from that?

Third, can we add any clarity to the actual lines of calculation? Do the variable names mean anything? Does `n` mean `normal`? If so, can we rename it? Does `p` mean `projection`? Or maybe `orthogonalProjection`? Do `i`, `d`, and `s` mean anything?

Similarly, can we add a comment above each line of computation that mentions what we're computing? For example, if I wanted to look up this computation in a Linear Algebra book, what might I look for? What's the intention of those computations of `i`, `d`, `s`, and `p`?