Hi @Coco_K, you have the best answers already, but I'm a scripter and I was intrigued by this challenge from a scripting perspective.
So, I've written a script called "Close Path By Mirroring". Select one or more open paths and run script and here's what it looks like:

Full script is below (sorry, it's long!).
- Mark
/**
* Close Path By Mirroring.js
*
* Usage:
* 1. select one or more *open* path items
* 2. run script
*
* @author m1b
* @discussion https://community.adobe.com/t5/illustrator-discussions/mirroring-group-of-objects-horizontally-to-the-exact-central-point-of-the-figure/m-p/14458608
*/
(function () {
var doc = app.activeDocument,
items = doc.selection;
closePathByMirroring(items);
})();
/**
* Close item's paths by flipping path across
* the axis of its first and last points.
* @author m1b
* @version 2024-03-01
* @param {PathItem|CompoundPathItem} item - the item to mirror.
*/
function closePathByMirroring(item) {
// process an array of items
if ('Array' === item.constructor.name) {
for (var i = 0; i < item.length; i++)
closePathByMirroring(item[i]);
return;
}
if (
item.hasOwnProperty('pathItems')
&& item.pathItems.length > 0
) {
for (var i = 0; i < item.pathItems.length; i++)
closePathByMirroring(item.pathItems[i]);
return;
}
if (
!item.hasOwnProperty('pathPoints')
|| item.pathPoints.length < 2
)
return;
if (true === item.closed)
// ignore closed paths
return;
var len = item.pathPoints.length - 1,
pFirst = item.pathPoints[0],
pLast = item.pathPoints[len],
fulcrum = pFirst.anchor,
angle = angleBetweenPoints(pFirst.anchor, pLast.anchor, true) + 1.5707963268;
// matrix to move fulcrum to origin, straighten and flip (and move back)
var flip = multiplyMatrices([
translationMatrix([-fulcrum[0], -fulcrum[1]]),
rotationMatrix(-angle, false),
scaleMatrix(-1, 1),
rotationMatrix(angle, false),
translationMatrix([fulcrum[0], fulcrum[1]]),
]);
// add mirrored path points
for (var i = len, p; i >= 0; i--) {
if (len === i) {
item.pathPoints[i].rightDirection = transformPoint(item.pathPoints[i].leftDirection, flip);
}
else if (0 === i) {
item.closed = true;
item.pathPoints[0].leftDirection = transformPoint(item.pathPoints[i].rightDirection, flip);
}
else {
p = item.pathPoints.add();
p.anchor = transformPoint(item.pathPoints[i].anchor, flip);
p.leftDirection = transformPoint(item.pathPoints[i].rightDirection, flip);
p.rightDirection = transformPoint(item.pathPoints[i].leftDirection, flip);
}
}
};
/**
* Returns angle between two points
* and horizontal.
* @param {Array} p1 - a point array [x, y].
* @param {Array} p2 - a point array [x, y].
* @param {Boolean} asRadians - whether the result should be in radians (default: false).
* @returns {Number} - the angle.
*/
function angleBetweenPoints(p1, p2, asRadians) {
var delta = differenceBetweenPoints(p1, p2),
theta = Math.atan2(-delta[1], -delta[0]); // radians
if (asRadians)
return theta;
return theta * (180 / Math.PI);
};
/**
* Returns x, y difference between two points.
* @param {Array} p1 - a point array [x, y].
* @param {Array} p2 - a point array [x, y].
* @returns {Array} - [dx, dy].
*/
function differenceBetweenPoints(p1, p2) {
return [-(p2[0] - p1[0]), -(p2[1] - p1[1])];
};
/**
* Returns a translation matrix.
* @param {Array<Number>} v - the translation vector [tx, ty].
* @returns {Array<Number>} - 3x3 matrix.
*/
function translationMatrix(v) {
return [
[1, 0, v[0]],
[0, 1, v[1]],
[0, 0, 1],
];
};
/**
* Returns a matrix to scale by `sx` x `sy`.
* @param {Number} sx - the horizontal scale factor [0..1].
* @param {Number} sy - the vertical scale factor [0..1].
* @returns {Array<Number>} - 3x3 matrix.
*/
function scaleMatrix(sx, sy) {
return [
[sx, 0, 0],
[0, sy, 0],
[0, 0, 1],
];
};
/**
* Returns a matrix with `angle` rotation.
* @param {Number} angle - the rotation amount.
* @param {Boolean} angleIsDegrees - whether the angle unit is degrees (default: radians).
* @returns {Array<Number>} - 3x3 matrix.
*/
function rotationMatrix(angle, angleIsDegrees) {
if (angleIsDegrees)
angle *= (Math.PI / 180);
return [
[Math.cos(angle), -Math.sin(angle), 0],
[Math.sin(angle), Math.cos(angle), 0],
[0, 0, 1],
];
};
/**
* Multiply two or more 3x3 matrices.
* @param {Array<matrix>} matrices - a 2D matrix [[a,b,tx], [d,e,ty], [0,0,1]].
* @returns {matrix}
*/
function multiplyMatrices(matrices) {
if (
undefined == matrices
|| 0 === matrices.length
)
throw Error('Mat.multiplyMatrices: no matrices supplied.');
// initialize result matrix
var result,
len = matrices.length - 1;
// multiply each subsequent matrix with the result matrix
for (var i = len; i >= 0; i--) {
var m = matrices[i],
rowCount = m.length,
columnCount = m[0].length;
if (
rowCount !== 3
|| columnCount !== 3
)
throw Error('Mat.multiplyMatrices: matrix ' + i + ' is bad.');
if (len === i) {
// initialise result
result = m;
continue;
}
var temp = new Array(rowCount);
for (var r = 0; r < rowCount; ++r) {
temp[r] = new Array(columnCount);
for (var c = 0; c < columnCount; ++c) {
temp[r][c] = 0;
for (var k = 0; k < columnCount; ++k)
temp[r][c] += result[r][k] * m[k][c];
}
}
result = temp;
}
return result;
};
/**
* Transformation a point with a matrix.
* @param {Array<Number>} point - a point [x, y].
* @param {Array<Array<Number>>} matrix - a 3x3 matrix.
* @returns {Array<Number>} - [tx, ty].
*/
function transformPoint(point, matrix) {
// add 1 to the point for homogeneity with the matrix
var p = multiplyMatrixVector(matrix, [point[0], point[1], 1]);
return [p[0], p[1]];
};
/**
* Multiplies a matrix by a vector,
* returning the resulting vector.
* Note: will throw error if the vector
* length is less than the number of
* columns in the matrix.
* @param {Array<Array<Number>>} matrix - the matrix to multiply.
* @param {Array<Number>} vector - the vector to multiple.
* @returns {Array<Number>}
*/
function multiplyMatrixVector(matrix, vector) {
var result = [];
for (var i = 0; i < matrix.length; i++) {
result[i] = 0;
for (var j = 0; j < vector.length; j++)
result[i] += matrix[i][j] * vector[j];
}
return result;
};
/**
* Transforms a path item using a 3x3 matrix.
* @author m1b
* @version 2024-03-01
* @param {Object} options
* @param {PathItem|CompoundPathItem} options.item - a path item or compoundPathItem.
* @param {Array<Array<Number>>} options.matrix - a 3x3 matrix.
* @param {Array<Number>} [options.netTranslationVector] - described a pre-transform and post-transform translation, which serves to specify the `fulcrum` of the transform.
*/
function transformPathItem(options) {
options = options || {};
var item = options.item,
matrix = options.matrix;
for (var i = 0, p, l = item.pathPoints.length; i < l; i++)
transformPathPoint(item.pathPoints[i], matrix);
};
/**
* Transform `pathPoint` with `matrix`.
* @author m1b
* @version 2024-03-01
* @param {PathPoint} pathPoint - the PathPoint to transform.
* @param {matrix} matrix - the matrix (3x3 array).
*/
function transformPathPoint(pathPoint, matrix) {
pathPoint.anchor = transformPoint(pathPoint.anchor, matrix);
pathPoint.leftDirection = transformPoint(pathPoint.leftDirection, matrix);
pathPoint.rightDirection = transformPoint(pathPoint.rightDirection, matrix);
};
Edit 2024-03-01: Fixed bug where closing point's left control was not mirrored. Thanks @Ton Frederiks!