Looking for alternatives or improvements for accomplishing the following:

Given the position of points A, B, and C in both the x-y and u-v planes, determine transformation functions to map values between the x-y and u-v planes.

Points A and B are on the v axis.

Point C is on the u axis.

Below is what I have developed so far.

- Recommendations for improvements are welcome.
- Can this the result is expressed as an AffineTransform? This implementation uses (r + v).m but the AffineTransform uses r.m + v, perhaps there is a way to revise the implementation?

```
(*example data*)
{Axy, Bxy, Cxy,
Pxy} = {{0.2, 0.8}, {0.1, 0.15}, {0.8, 0.25}, {0.6, 0.7}};
{Auv, Cuv} = {{0, 75}, {100, 0}};
(*the unit vectors for the u-v plane, w.r.t. the x-y coordinate*)
Vxy = Normalize( Axy - Bxy);
Uxy = Normalize({Last(Vxy), -
First(Vxy) }); (*axis orthogonal to Vxy*)
(*the origin of the u-v plane in x-y coordinates is the intersection
of the v and u axis*)
UVoxy = First@(
Axy + k1 Vxy /. Solve( Axy + k1 Vxy == Cxy + k2 Uxy , {k1, k2} ) );
(*scale factors for u-v axis*)
Uscale = First@Cuv / EuclideanDistance(UVoxy, Cxy);
Vscale = Last@Auv / EuclideanDistance(UVoxy, Axy);
mUVscale = {{Uscale, 0}, {0, Vscale}};
(*rotation from x-y to u-v*)
r1 = RotationMatrix({{1, 0}, Uxy}) ;
(*combined rotation and scaling*)
mXYtoUV = r1 . mUVscale;
mUVtoXY = DiagonalMatrix((1 / Diagonal@mUVscale)) . Transpose(r1) ;
(*test: original xy points to uv*)
testUV = (# - UVoxy) . mXYtoUV & /@ {Axy, Bxy, Cxy, Pxy} ;
(*test: computed uv points to xy*)
testXY01 = (# . mUVtoXY + UVoxy) & /@ testUV;
(*test: original uv points to xy*)
testXY02 = (# . mUVtoXY + UVoxy) & /@ {Auv, Cuv} ;
(*report: xy to uv*)
Framed@Labeled(
Grid({ { "pt", Style("UV data", Bold), Style("UV computed", Bold)}
, { Column({"A", "B", "C", "P" })
, {Auv, {"-", "-"}, Cuv, {"-", "-"}} // MatrixForm
, testUV // MatrixForm
}
}
, Frame -> All), Style("xy to uv", 16, Bold), Top)
(*report: uv to xy*)
Framed@Labeled(
Grid({ { "pt", Style("xy data", Bold), Style("xy computed", Bold)}
, { Column({"A", "B", "C", "P" })
, {Axy, Bxy, Cxy, Pxy} // MatrixForm
, testXY01 // MatrixForm
}
}
, Frame -> All), Style("uv to xy", 16, Bold), Top)
```

**results**

Finally, here is the code to display a sketch of the system

```
(*sketch of the system*)
Graphics({AbsolutePointSize(10)
, Point({Axy, Bxy, Cxy, Pxy})
, AbsoluteThickness(1)
, AbsoluteDashing(10)
, Darker@Blue
, Arrowheads({-0.05, +0.05})
, Arrow({UVoxy - 0.35 Vxy, UVoxy + 0.65 Vxy})
, Arrowheads(+0.05)
, Arrow({UVoxy, UVoxy + 0.95 Uxy})
, Darker@Green
, Text(Style("A", Bold, 18), Axy + {0.03, 0.03}, {-1, 0})
, Text(Style("B", Bold, 18), Bxy + {0.03, 0.03}, {-1, 0})
, Text(Style("C", Bold, 18), Cxy + {0.03, 0.03}, {-1, 0})
, Darker@Red
, Text(Style("P", Bold, 18), Pxy + {0.03, 0.03}, {-1, 0})
, Darker@Blue
, Text(Style("u", Bold, Italic, 14), UVoxy + 0.95 Uxy , {-1, 0})
, Text(Style("v", Bold, Italic, 14), UVoxy + 0.65 Vxy , {-1, -1})
, Text(Style("-v", Bold, Italic, 14), UVoxy - 0.35 Vxy , {0.5, 1})
}
, Axes -> True
, PlotRange -> {{-0.1, 1.2}, {-0.1, 1.1} }
, Frame -> True
)
```