How to Localize the Barycenter of a Triangle in Java


The challenge

The medians of a triangle are the segments that unit the vertices with the midpoint of their opposite sides. The three medians of a triangle intersect at the same point, called the barycenter or the centroid. Given a triangle, defined by the cartesian coordinates of its vertices we need to localize its barycenter or centroid.

The function bar_triang() or barTriang or bar-triang, receives the coordinates of the three vertices A, B and C as three different arguments and outputs the coordinates of the barycenter O in an array [xO, yO]

This is how our asked function should work: the result of the coordinates should be expressed up to four decimals, (rounded result).

You know that the coordinates of the barycenter are given by the following formulas.

For additional information about this important point of a triangle see at: (https://en.wikipedia.org/wiki/Centroid )

Let’s see some cases:

barTriang([4, 6], [12, 4], [10, 10]) ------> {8.6667, 6.6667}

barTriang([4, 2], [12, 2], [6, 10] ------> {7.3333, 4.6667}

The given points form a real or a degenerate triangle but in each case the above formulas can be used.

The solution in Java code

Option 1 (using a simple double):

class Barycenter {
    
    public static double[] barTriang(double[] x, double[] y, double[] z) {
        double[] res = new double[2];
        res[0] = (double)((int)Math.round((x[0]+y[0]+z[0])/3*10000))/10000;
        res[1] = (double)((int)Math.round((x[1]+y[1]+z[1])/3*10000))/10000;
        return res;
    }
}

Option 2 (using a loop):

import java.text.DecimalFormat;

class Barycenter {
    
    public static double[] barTriang(double[] x, double[] y, double[] z) {
        double[] coordinates = new double[2];
        
        for(int i=0;i<2;i++) {
            coordinates[i] = Double.parseDouble(new DecimalFormat("##.####").format((x[i]+y[i]+z[i])/3));
        }
        
        return coordinates;
    }
}

Option 3 (using BigDecimal):

import java.math.BigDecimal;
import java.math.RoundingMode;

class Barycenter {

  public static double[] barTriang(double[] x, double[] y, double[] z) {

    double x0 = new BigDecimal((x[0] + y[0] + z[0]) / 3).setScale(4, RoundingMode.HALF_UP).doubleValue();
    double y0 = new BigDecimal((x[1] + y[1] + z[1]) / 3).setScale(4, RoundingMode.HALF_UP).doubleValue();
    double[] zet = new double[] { x0, y0 };
    return zet;

  }
}

Test cases to validate our Java code

import static org.junit.Assert.*;
import java.util.Arrays;
import org.junit.Test;

public class BarycenterTest {

    private static int randInt(int min, int max) {
        return min + (int)(Math.random() * ((max - min) + 1));
    }
    private static double round4Sol(double d) {
        return Math.floor(d * 10000 +.5) / 10000;
    }
    public static String barTriangSol(double[] x, double[] y, double[] z)
    {
        double[] res = new double[]{round4Sol((x[0]+y[0]+z[0])/3.0), round4Sol((x[1]+y[1]+z[1])/3.0)};
        return Arrays.toString(res);
    }
    @Test
    public void test() {
        System.out.println("Fixed Tests");  
        assertEquals("[8.6667, 6.6667]", Arrays.toString(Barycenter.barTriang(
                new double[]{4,6}, new double[]{12,4}, new double[]{10,10})));
        assertEquals("[7.3333, 4.6667]", Arrays.toString(Barycenter.barTriang(
                new double[]{4,2}, new double[]{12,2}, new double[]{6,10})));
        assertEquals("[9.3333, 5.3333]", Arrays.toString(Barycenter.barTriang(
                new double[]{4,8}, new double[]{8,2}, new double[]{16,6})));
        assertEquals("[0.0, 3.0]", Arrays.toString(Barycenter.barTriang(
                new double[]{0,0}, new double[]{1,3}, new double[]{-1,6})));
        assertEquals("[3.0, 0.0]", Arrays.toString(Barycenter.barTriang(
                new double[]{0,0}, new double[]{1,6}, new double[]{8,-6})));
        
    }
    @Test
    public void test1() {
        System.out.println("100 Random Tests");
        for (int i = 0; i < 100; i++) { 
            double a = randInt(1, 8);
            double b = randInt(11, 15);
            double c = randInt(12, 20);
            assertEquals(BarycenterTest.barTriangSol(
                    new double[]{a,0}, new double[]{c+0.25,0.5}, new double[]{20,b+0.5}), 
                    Arrays.toString(Barycenter.barTriang(
                            new double[]{a,0}, new double[]{c+0.25,0.5}, new double[]{20,b+0.5})));
        }
    }
}