Well! Maybe Mathematica doesn't provide the "best" way to deal with this problem. It's the user's job to come up with solution of it.
My solution: 1) MapThread; 2) Table
Clear["`*"];
a = {a1, a2}; b = {b1, b2}; ref1 = {x1, y1}; ref2 = {x2, y2};
oA1 = Plus[a, ref1];
oA2 = Plus[a, ref2];
oB1 = Plus[b, ref1];
oB2 = Plus[b, ref2];
{{oA1, oA2}, {oB1, oB2}}
MapThread[Plus, {{{a, a}, {b, b}}, {{ref1, ref2}, {ref1, ref2}}}]
Table[Plus[x, y], {x, {a, b}}, {y, {ref1, ref2}}]
(*
Result:
{{{a1 + x1, a2 + y1}, {a1 + x2, a2 + y2}}, {{b1 + x1, b2 + y1}, {b1 + x2, b2 + y2}}}
{{{a1 + x1, a2 + y1}, {a1 + x2, a2 + y2}}, {{b1 + x1, b2 + y1}, {b1 + x2, b2 + y2}}}
{{{a1 + x1, a2 + y1}, {a1 + x2, a2 + y2}}, {{b1 + x1, b2 + y1}, {b1 + x2, b2 + y2}}}
*)
These are my provisional solutions. For the moment, Table is the best choice.
By the way, MapThread also has its merit.
{oA1, oA2, oB1, oB2} = MapThread[Plus, {{a, a, b, b}, {ref1, ref2, ref1, ref2}}]
(*
Result:
{{a1 + x1, a2 + y1}, {a1 + x2, a2 + y2}, {b1 + x1, b2 + y1}, {b1 + x2, b2 + y2}}
*)
You don't need to Flatten the result and four points are directly assigned to variables.
With Table, you have to use Flatten or more curly braces.
{oA1, oA2, oB1, oB2} = Table[Plus[x, y], {x, {a, b}}, {y, {ref1, ref2}}]~Flatten~1
{{oA1, oA2}, {oB1, oB2}} = Table[Plus[x, y], {x, {a, b}}, {y, {ref1, ref2}}]