1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
| package example;
public class Complex {
public static interface IParameter {
}
public static final class X implements IParameter {
private final double value;
private X(final double value) {
this.value = value;
}
}
public static final X x(final double value) {
return new X(value);
}
public static final class Y implements IParameter {
private final double value;
private Y(final double value) {
this.value = value;
}
}
public static final Y y(final double value) {
return new Y(value);
}
public static final class Angle implements IParameter {
public static enum Unit { DEG, RAD; };
private final double value;
private Angle(final double value, final Unit unit) {
switch (unit) {
case DEG:
this.value = Math.toRadians(value);
break;
case RAD:
this.value = value;
break;
default:
throw new IllegalArgumentException(unit.toString());
}
}
}
public static final Angle angle(final double value, final Angle.Unit unit) {
return new Angle(value, unit);
}
public static final class R implements IParameter {
private final double value;
private R(final double value) {
this.value = value;
}
}
public static final R r(final double value) {
return new R(value);
}
@SuppressWarnings("serial")
public final class ParameterException extends RuntimeException {
public ParameterException(final String message) {
super(message);
}
}
private final double x, y;
/**
* The parameters must be created with two of { <code>Complex.x(double)</code>, <code>Complex.y(double)</code>, <code>Complex.angle(double, Complex.Angle.Unit)</code>, <code>Complex.r(double)</code> }.<br>
* Example : <code>new Complex(Complex.y(33), Complex.x(42));</code>.<br>
* @param parameters set of exactly 2 parameters: (x and y) or (angle and r) ; the order doesn't matter.<br>
* @throws ParameterException if:<ul>
* <li>parameters.length != 2;</li>
* <li>there is a duplicate parameter;</li>
* <li>there is not enough information to construct the object (missing parameters).</li>
* </ul>
*/
public Complex(final IParameter... parameters) {
if (parameters.length != 2) throw new ParameterException("Exactly 2 parameters needed");
Double x = null;
Double y = null;
Double angle = null;
Double r = null;
for (final IParameter parameter : parameters) {
if (parameter instanceof X) {
if (x != null) throw new ParameterException("Duplicate parameter: x");
x = ((X)parameter).value;
}
if (parameter instanceof Y) {
if (y != null) throw new ParameterException("Duplicate parameter: y");
y = ((Y)parameter).value;
}
if (parameter instanceof Angle) {
if (angle != null) throw new ParameterException("Duplicate parameter: angle");
angle = ((Angle)parameter).value;
}
if (parameter instanceof R) {
if (r != null) throw new ParameterException("Duplicate parameter: r");
r = ((R)parameter).value;
}
}
if (x == null) {
if (angle == null) throw new ParameterException("Missing parameter: angle");
if (r == null) throw new ParameterException("Missing parameter: r");
x = r * Math.cos(angle);
}
if (y == null) {
if (angle == null) throw new ParameterException("Missing parameter: angle");
if (r == null) throw new ParameterException("Missing parameter: r");
y = r * Math.sin(angle);
}
this.x = x;
this.y = y;
}
public final double getX() {
return this.x;
}
public final double getY() {
return this.y;
}
/**
* @return angle in radians.<br>
*/
public final double getAngle() {
return Math.atan2(this.y, this.x);
}
public final double getR() {
return Math.sqrt(this.x * this.x + this.y * this.y);
}
@Override
public final String toString() {
return "(x: " + this.getX() + "; y: " + this.getY() + "; angle: " + this.getAngle() + " rad; r: " + this.getR() + ")";
}
} |
Partager