Thank you both

very creative solutions that will fit 99% of use cases. The spark that ignited my question was trying to get a triangulated cone-shaped flower petal to have a rectangular UV.
I was fishing for a vex solution in the title, because the described situation is only the first step and I was going to expand this problem. What if we wanted to straighten only the sides and not the top and bottom parts of the island? What if we wanted the corner points to be arbitrary and exist only as a Python state in the viewport?
I'm basically trying to create a UV space lattice.
Yesterday I learned about
quadrilateral interpolation [
www.reedbeta.com]. I'm not a math person, so I only understand the core concept.
Here's what I got so far. I work on a point attribute UV to make it easier for myself for now.
The first point wrangle calculates the local uv of each point that will be used to recreate its position with interpolation
// corner points clockwise
i@pt0 = 90;
i@pt1 = 99;
i@pt2 = 9;
i@pt3 = 0;
float wedge2d(vector a; vector b) {
return a.x * b.y - a.y * b.x;
}
vector2 invert_bilinear(vector p0, p1, p2, p3; vector q)
{
vector b1 = p1 - p0;
vector b2 = p3 - p0;
vector b3 = p0 - p1 - p3 + p2;
float A = wedge2d(b2, b3);
float B = wedge2d(b3, q) - wedge2d(b1, b2);
float C = wedge2d(b1, q);
float v;
if (abs(A) < 1e-5) {
v = -C / B;
} else {
float discrim = B*B - 4*A*C;
v = 0.5 * (-B + sqrt(discrim)) / A;
}
vector denom = b1 + v * b3;
float u;
if (abs(denom.x) > abs(denom.y))
u = (q.x - b2.x * v) / denom.x;
else
u = (q.y - b2.y * v) / denom.y;
return set(u, v);
}
vector uv0 = point(0, "uv", i@pt0);
vector uv1 = point(0, "uv", i@pt1);
vector uv2 = point(0, "uv", i@pt2);
vector uv3 = point(0, "uv", i@pt3);
vector q = v@uv - uv0;
u@local_uv = invert_bilinear(uv0, uv1, uv2, uv3, q);
Then I displace my corners.
Then in another point wrangle I apply the interpolation against my new corner positions:
vector uv0 = point(0, "uv", i@pt0);
vector uv1 = point(0, "uv", i@pt1);
vector uv2 = point(0, "uv", i@pt2);
vector uv3 = point(0, "uv", i@pt3);
vector pu0 = lerp(uv0, uv1, u@local_uv.x);
vector pu1 = lerp(uv3, uv2, u@local_uv.x);
vector new_uv = lerp(pu0, pu1, u@local_uv.y);
v@uv = new_uv;
So far it seems to work perfectly as long as the affected UV points are between the 4 points.

So my current workflow would involve straightening desired edges with UV Flatten and then stretching them with vex. At least, as long as I don't figure out how to straighten them with vex. I'm attaching a hip.