From 1b9efaa239dfb10668beeede7bdd84ccf8f517e8 Mon Sep 17 00:00:00 2001 From: Benjamin Date: Mon, 27 Apr 2026 15:18:30 +0200 Subject: [PATCH] =?UTF-8?q?Trac=C3=A9=20des=20points=20et=20de=20la=20regr?= =?UTF-8?q?ession?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/ecoparasite/Application.java | 14 +- src/ecoparasite/completion/Completion.java | 12 ++ .../svg/{SVGAxes.java => SVGBuilder.java} | 167 +++++++++++++++++- src/ecoparasite/svg/SVGFactory.java | 127 ------------- src/ecoparasite/svg/elements/Circle.java | 4 +- 5 files changed, 182 insertions(+), 142 deletions(-) rename src/ecoparasite/svg/{SVGAxes.java => SVGBuilder.java} (50%) diff --git a/src/ecoparasite/Application.java b/src/ecoparasite/Application.java index 6b777ed..f92ed4a 100644 --- a/src/ecoparasite/Application.java +++ b/src/ecoparasite/Application.java @@ -10,9 +10,8 @@ import ecoparasite.poisson.MackerelSerra; import ecoparasite.poisson.Poisson; import ecoparasite.representation.ValeursXY; import ecoparasite.svg.IncorrectAxesPointsException; -import ecoparasite.svg.SVGAxes; +import ecoparasite.svg.SVGBuilder; import ecoparasite.svg.SVGFactory; -import ecoparasite.svg.SVGResizing; import ecoparasite.svg.elements.Element; import java.util.ArrayList; @@ -39,18 +38,21 @@ public class Application { mackerelSet = Completion.completeColumnsLinear( mackerelSet, getLength, getInfes, setInfes ); HashSet mackerelXY = ValeursXY.convertToXY( mackerelSet, getLength, getInfes ); - HashMap> axes = SVGFactory.PointAXES( mackerelXY ); + HashMap> axes = SVGBuilder.calcPointAxes( mackerelXY ); System.out.println( axes ); - SVGAxes axesInstance; + SVGBuilder axesInstance; try { - axesInstance = new SVGAxes(axes); + axesInstance = new SVGBuilder(axes); } catch (IncorrectAxesPointsException e) { System.out.println( "Mauvais format communiqué" ); return; } - ArrayList SVGElements = axesInstance.buildAll( "Length", "Infestation" ); + // Sauvegarde pour plus tard. + double[] ABCoef = Completion.getLinearCoef(mackerelSet, getLength, getInfes); + + ArrayList SVGElements = axesInstance.buildAll( "Length", "Infestation", mackerelXY, ABCoef[0], ABCoef[1] ); SVGFactory.createSVG( SVGElements ); } diff --git a/src/ecoparasite/completion/Completion.java b/src/ecoparasite/completion/Completion.java index 2c1d8bb..a2036d3 100644 --- a/src/ecoparasite/completion/Completion.java +++ b/src/ecoparasite/completion/Completion.java @@ -139,4 +139,16 @@ public class Completion { return meanY - valueA * meanX; } + public static double[] getLinearCoef( HashSet list, Function getX, Function getY ){ + + double meanX = calculateMean(list, getX); + double meanY = calculateMean(list, getY); + + double a = calculateLinearA(list,getX,getY,meanX,meanY); + double b = calculateLinearB(meanX,meanY,a); + + return new double[]{a,b}; + + } + } diff --git a/src/ecoparasite/svg/SVGAxes.java b/src/ecoparasite/svg/SVGBuilder.java similarity index 50% rename from src/ecoparasite/svg/SVGAxes.java rename to src/ecoparasite/svg/SVGBuilder.java index 4d5446d..23ce293 100644 --- a/src/ecoparasite/svg/SVGAxes.java +++ b/src/ecoparasite/svg/SVGBuilder.java @@ -1,16 +1,13 @@ package ecoparasite.svg; -import ecoparasite.svg.elements.Element; -import ecoparasite.svg.elements.ElementsFactory; -import ecoparasite.svg.elements.Line; -import ecoparasite.svg.elements.Text; +import ecoparasite.representation.ValeursXY; +import ecoparasite.svg.elements.*; -import java.lang.reflect.Array; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; -public class SVGAxes { +public class SVGBuilder { final int SIZE_TICK_TEXT = ElementsFactory.AXES_TEXT_SIZE - 3; @@ -25,7 +22,7 @@ public class SVGAxes { private Double maxPointsX; private Double maxPointsY; - public SVGAxes( HashMap> axesPoints ) throws IncorrectAxesPointsException { + public SVGBuilder(HashMap> axesPoints ) throws IncorrectAxesPointsException { if( axesPoints.get("AxeX") == null || axesPoints.get("AxeY") == null || axesPoints.get("OffsetX") == null || axesPoints.get("OffsetY") == null ){ throw new IncorrectAxesPointsException(); @@ -70,12 +67,15 @@ public class SVGAxes { this.resizer = resizer; } - public ArrayList buildAll(String XLabel, String YLabel){ + public ArrayList buildAll(String XLabel, String YLabel, HashSet points, double A, double B){ ArrayList elements = new ArrayList<>(); + elements.addAll(buildAxes(XLabel, YLabel)); elements.addAll(buildXTicks()); elements.addAll(buildYTicks()); + elements.addAll(buildPoints(points)); + elements.addAll(buildRegression(A,B)); return elements; } @@ -171,6 +171,30 @@ public class SVGAxes { return elements; } + public ArrayList buildPoints( HashSet points ){ + + ArrayList elements = new ArrayList<>(); + for( ValeursXY point : points ){ + Coordonnees coords = getResizer().resize( point.getX(), point.getY() ); + elements.add(new Circle(coords,3,ElementsFactory.COLOR_BLUE) ); + } + + return elements; + } + + public ArrayList buildRegression( double A, double B ){ + ArrayList elements = new ArrayList<>(); + + double y1 = A * minPointsX + B; + double y2 = A * maxPointsX + B; + + Coordonnees coords1 = getResizer().resize(minPointsX, y1); + Coordonnees coords2 = getResizer().resize(maxPointsX, y2); + + elements.add( new Line( coords1, coords2, ElementsFactory.COLOR_RED, 2 ) ); + return elements; + } + private double getBeginAxeX(){ return ( minPointsX > 0 ) ? minPointsX : ( maxPointsX < 0 ? maxPointsX : 0 ); } @@ -178,4 +202,131 @@ public class SVGAxes { private double getBeginAxeY(){ return ( minPointsY > 0 ) ? minPointsY : ( maxPointsY < 0 ? maxPointsY : 0 ); } + + /** + * Permet de renvoyer des valeurs "clean" pour l'affichage des axes + * @param h Contient les Coordonnées de chacun des points de nos données + * @return une HashMap de String et de Hashset de Double. + * Avec la String "AxeX", un Hashset de Double contenant les valeurs des gradations de l'axe X + * Avec la String "AxeY", un Hashset de Double contenant les valeurs des gragations de l'axe Y + * Avec la String "OffsetX", un Hashset de Double contenant uniquement la valeur de l'offset des points par rapport à l'axe X + * Avec la String "OffsetY", un Hashset de Double contenant uniquement la valeur de l'offset des points par rapport à l'axe Y + */ + public static HashMap< String ,ArrayList> calcPointAxes(HashSet h){ + + HashMap< String, ArrayList > map = new HashMap<>(); + + //Définition des min et max + double max_x = Double.MIN_VALUE; + double min_x = Double.MAX_VALUE; + double max_y = Double.MIN_VALUE; + double min_y = Double.MAX_VALUE; + + //Trouvé les min et max + for (ValeursXY var : h) { + + if (max_x < var.getX()){ + max_x = var.getX(); + } + if (min_x > var.getX()){ + min_x = var.getX(); + } + + if (max_y < var.getY()){ + max_y = var.getY(); + } + if (min_y > var.getY()){ + min_y = var.getY(); + } + + } + + double range_x = max_x-min_x; + double range_y = max_y-min_y; + + int target = 10; // Ideal Number of Gradation + + double step_x = niceStep(range_x,target); + double step_y = niceStep(range_y,target); + + double nicemin_x = roundMin(min_x,step_x); + double nicemax_x = roundMax(max_x,step_x); + double nicemin_y = roundMin(min_y,step_y); + double nicemax_y = roundMax(max_y,step_y); + + // Compléter un Hashset de Double pour X et pour Y et Offset X et Y. TODO + ArrayList axeX = new ArrayList<>(); + ArrayList axeY = new ArrayList<>(); + ArrayList OffsetX = new ArrayList<>(); + ArrayList OffsetY = new ArrayList<>(); + + Double ix = nicemin_x; + while ( ix <= nicemax_x ) { + axeX.add(ix); + ix+=step_x; + }; + map.put("AxeX", axeX); + + Double iy = nicemin_y; + while ( iy <= nicemax_y ) { + axeY.add(iy); + iy+=step_y; + } + map.put("AxeY",axeY); + + double offsetX = min_x - nicemin_x; + double offsetY = min_y - nicemin_y; + + ArrayList offsetXHash = new ArrayList<>(); + offsetXHash.add(offsetX); + ArrayList offsetYHash = new ArrayList<>(); + offsetYHash.add(offsetY); + + map.put("OffsetX", offsetXHash); + map.put("OffsetY", offsetYHash); + + return map; + } + + /** + * Fonction de calcul d'un step rond + * Cette fonction est basé sur une idée demandée à ChatGPT + * @param range écart entre la plus petite et la plus grande valeur + * @param targetTicks nombre de gradation ideal + * @return + */ + public static double niceStep(double range, int targetTicks) { + + double rawStep = range / targetTicks; + + double exponent = Math.floor(Math.log10(rawStep)); + double fraction = rawStep / Math.pow(10, exponent); + + double niceFraction; + + if (fraction < 1.5) + niceFraction = 1; + else if (fraction < 3) + niceFraction = 2; + else if (fraction < 7) + niceFraction = 5; + else + niceFraction = 10; + + return niceFraction * Math.pow(10, exponent); + } + + /** + * retourne une valeur arrondi "joli" adapter à un graphique + * @param value + * @param step + * @return + */ + public static double roundMin(double value, double step) { + return Math.floor(value / step) * step; + } + + public static double roundMax(double value, double step) { + return Math.ceil(value / step) * step; + } } diff --git a/src/ecoparasite/svg/SVGFactory.java b/src/ecoparasite/svg/SVGFactory.java index c49b50c..6c1eb68 100644 --- a/src/ecoparasite/svg/SVGFactory.java +++ b/src/ecoparasite/svg/SVGFactory.java @@ -103,131 +103,4 @@ public class SVGFactory { } - /** - * Permet de renvoyer des valeurs "clean" pour l'affichage des axes - * @param h Contient les Coordonnées de chacun des points de nos données - * @return une HashMap de String et de Hashset de Double. - * Avec la String "AxeX", un Hashset de Double contenant les valeurs des gradations de l'axe X - * Avec la String "AxeY", un Hashset de Double contenant les valeurs des gragations de l'axe Y - * Avec la String "OffsetX", un Hashset de Double contenant uniquement la valeur de l'offset des points par rapport à l'axe X - * Avec la String "OffsetY", un Hashset de Double contenant uniquement la valeur de l'offset des points par rapport à l'axe Y - */ - public static HashMap< String ,ArrayList> PointAXES(HashSet h){ - - HashMap< String, ArrayList > map = new HashMap<>(); - - //Définition des min et max - double max_x = Double.MIN_VALUE; - double min_x = Double.MAX_VALUE; - double max_y = Double.MIN_VALUE; - double min_y = Double.MAX_VALUE; - - //Trouvé les min et max - for (ValeursXY var : h) { - - if (max_x < var.getX()){ - max_x = var.getX(); - } - if (min_x > var.getX()){ - min_x = var.getX(); - } - - if (max_y < var.getY()){ - max_y = var.getY(); - } - if (min_y > var.getY()){ - min_y = var.getY(); - } - - } - - double range_x = max_x-min_x; - double range_y = max_y-min_y; - - int target = 10; // Ideal Number of Gradation - - double step_x = niceStep(range_x,target); - double step_y = niceStep(range_y,target); - - double nicemin_x = roundMin(min_x,step_x); - double nicemax_x = roundMax(max_x,step_x); - double nicemin_y = roundMin(min_y,step_y); - double nicemax_y = roundMax(max_y,step_y); - - // Compléter un Hashset de Double pour X et pour Y et Offset X et Y. TODO - ArrayList axeX = new ArrayList<>(); - ArrayList axeY = new ArrayList<>(); - ArrayList OffsetX = new ArrayList<>(); - ArrayList OffsetY = new ArrayList<>(); - - Double ix = nicemin_x; - while ( ix <= nicemax_x ) { - axeX.add(ix); - ix+=step_x; - }; - map.put("AxeX", axeX); - - Double iy = nicemin_y; - while ( iy <= nicemax_y ) { - axeY.add(iy); - iy+=step_y; - } - map.put("AxeY",axeY); - - double offsetX = min_x - nicemin_x; - double offsetY = min_y - nicemin_y; - - ArrayList offsetXHash = new ArrayList<>(); - offsetXHash.add(offsetX); - ArrayList offsetYHash = new ArrayList<>(); - offsetYHash.add(offsetY); - - map.put("OffsetX", offsetXHash); - map.put("OffsetY", offsetYHash); - - return map; - } - - /** - * Fonction de calcul d'un step rond - * Cette fonction est basé sur une idée demandée à ChatGPT - * @param range écart entre la plus petite et la plus grande valeur - * @param targetTicks nombre de gradation ideal - * @return - */ - public static double niceStep(double range, int targetTicks) { - - double rawStep = range / targetTicks; - - double exponent = Math.floor(Math.log10(rawStep)); - double fraction = rawStep / Math.pow(10, exponent); - - double niceFraction; - - if (fraction < 1.5) - niceFraction = 1; - else if (fraction < 3) - niceFraction = 2; - else if (fraction < 7) - niceFraction = 5; - else - niceFraction = 10; - - return niceFraction * Math.pow(10, exponent); - } - - /** - * retourne une valeur arrondi "joli" adapter à un graphique - * @param value - * @param step - * @return - */ - public static double roundMin(double value, double step) { - return Math.floor(value / step) * step; - } - - public static double roundMax(double value, double step) { - return Math.ceil(value / step) * step; - } - } diff --git a/src/ecoparasite/svg/elements/Circle.java b/src/ecoparasite/svg/elements/Circle.java index c76a724..d9cd47e 100644 --- a/src/ecoparasite/svg/elements/Circle.java +++ b/src/ecoparasite/svg/elements/Circle.java @@ -2,6 +2,8 @@ package ecoparasite.svg.elements; import ecoparasite.svg.Coordonnees; +import java.util.Locale; + public class Circle extends Element { private int rayon; @@ -40,7 +42,7 @@ public class Circle extends Element { StringBuilder svg = new StringBuilder(); svg.append(""); -- 2.39.5