X-Git-Url: http://source.jalview.org/gitweb/?p=jalview.git;a=blobdiff_plain;f=src2%2Ffr%2Forsay%2Flri%2Fvarna%2Fmodels%2Fgeom%2FComputeArcCenter.java;fp=src2%2Ffr%2Forsay%2Flri%2Fvarna%2Fmodels%2Fgeom%2FComputeArcCenter.java;h=0aa8ebf724827ce9061524cc64dc370a26644aa1;hp=0000000000000000000000000000000000000000;hb=665d2c2f4c1310e6985b93b7c2c8a8eec2fa9086;hpb=0e684f72690bd6532272a39ab6c188a27559fd09 diff --git a/src2/fr/orsay/lri/varna/models/geom/ComputeArcCenter.java b/src2/fr/orsay/lri/varna/models/geom/ComputeArcCenter.java new file mode 100644 index 0000000..0aa8ebf --- /dev/null +++ b/src2/fr/orsay/lri/varna/models/geom/ComputeArcCenter.java @@ -0,0 +1,54 @@ +/** + * File written by Raphael Champeimont + * UMR 7238 Genomique des Microorganismes + */ +package fr.orsay.lri.varna.models.geom; + +public class ComputeArcCenter { + + /** + * Given an arc length (l) and segment length (delta) of the arc, + * find where to put the center, returned as a position of the perpendicular + * bisector of the segment. The positive side is the one where the arc is drawn. + * It works using Newton's method. + */ + public static double computeArcCenter(double delta, double l) { + double x_n = 0; + double x_n_plus_1, f_x_n, f_x_n_plus_1; + f_x_n = f(x_n,delta); + while (true) { + x_n_plus_1 = x_n - (f_x_n - l)/fprime(x_n,delta); + f_x_n_plus_1 = f(x_n_plus_1,delta); + // We want a precision of 0.1 on arc length + if (x_n_plus_1 == Double.NEGATIVE_INFINITY || Math.abs(f_x_n_plus_1 - f_x_n) < 0.1) { + //System.out.println("computeArcCenter: steps = " + steps + " result = " + x_n_plus_1); + return x_n_plus_1; + } + x_n = x_n_plus_1; + f_x_n = f_x_n_plus_1; + } + } + + private static double f(double c, double delta) { + if (c < 0) { + return 2*Math.atan(delta/(-2*c)) * Math.sqrt(delta*delta/4 + c*c); + } else if (c != 0) { // c > 0 + return (2*Math.PI - 2*Math.atan(delta/(2*c))) * Math.sqrt(delta*delta/4 + c*c); + } else { // c == 0 + return Math.PI * Math.sqrt(delta*delta/4 + c*c); + } + } + + /** + * d/dc f(c,delta) + */ + private static double fprime(double c, double delta) { + if (c < 0) { + return delta/(c*c + delta/4)*Math.sqrt(delta*delta/4 + c*c) + 2*Math.atan(delta/(-2*c))*c/Math.sqrt(delta*delta/4 + c*c); + } else if (c != 0) { // c > 0 + return delta/(c*c + delta/4)*Math.sqrt(delta*delta/4 + c*c) + (2*Math.PI - 2*Math.atan(delta/(-2*c)))*c/Math.sqrt(delta*delta/4 + c*c); + } else { // c == 0 + return 2; + } + } +} \ No newline at end of file