import java.awt.BorderLayout; import java.awt.Color; import java.awt.Container; import java.awt.Font; import java.awt.FontMetrics; import java.awt.Graphics; import javax.swing.JFrame; import javax.swing.JPanel; public class Bernoulli extends JFrame { public static void main(String[] args) { new Bernoulli("Bernoulli"); } public Bernoulli(String title) { super(title); this.setSize(1000, 680); JPanel panel = new BernoulliPanel(); Container content = this.getContentPane(); content.add(panel, BorderLayout.CENTER); this.setDefaultCloseOperation(EXIT_ON_CLOSE); this.setVisible(true); } public class BernoulliPanel extends JPanel { Font font = new Font("Georgia", Font.PLAIN, 14); @Override public void paintComponent(Graphics g) { int w = this.getSize().width; int h = this.getSize().height; g.setColor(Color.white); g.fillRect(0, 0, w, h); g.setColor(Color.black); g.setFont(font); this.drawBernoulli(15, g, 10, 10, 60, 40); } void drawRational(Rational r, Graphics g, int x, int y, int w, int h) { FontMetrics metrics = g.getFontMetrics(font); int hgt = metrics.getHeight(); int pady = (h - hgt) / 2 + hgt; if (r.p != 0 && r.q != 1) { { String text = String.valueOf(r.p); int adv = metrics.stringWidth(text); int padx = (w - adv) / 2; g.drawString(text, x + padx, y + pady - hgt / 2); } { String text = String.valueOf("------"); int adv = metrics.stringWidth(text); int padx = (w - adv) / 2; g.drawLine(x + padx, y + pady - hgt * 1 / 3, w - padx + x, y + pady - hgt * 1 / 3); } { String text = String.valueOf(r.q); int adv = metrics.stringWidth(text); int padx = (w - adv) / 2; g.drawString(text, x + padx, y + pady + hgt / 2); } } else { { String text = String.valueOf(r.p); int adv = metrics.stringWidth(text); int padx = (w - adv) / 2; g.drawString(text, x + padx, y + pady); } } } void drawBernoulli(int kmax, Graphics g, int x, int y, int w, int h) { Rational[] p = new Rational[kmax]; for (int k = 0; k < kmax; k++) { for (int m = 0; m < kmax - k; m++) { if (k == 0) { p[m] = new Rational(1, m + 1); } else { p[m] = p[m].sub(p[m + 1]).mul(new Rational(m + 1, 1)); } if (m == 0) { Color c = g.getColor(); g.setColor(new Color(255, 128, 128)); g.fillRect(x + w * m, y + h * k, w, h); g.setColor(c); g.drawRect(x + w * m, y + h * k, w, h); this.drawRational(p[m], g, x + w * m, y + h * k, w, h); g.setColor(c); } else { g.drawRect(x + w * m, y + h * k, w, h); this.drawRational(p[m], g, x + w * m, y + h * k, w, h); } } } } public class Rational { long p; long q; public Rational(long p, long q) { this.p = p; this.q = q; } public Rational sub(Rational v) { Rational n = new Rational(p, q); n.p = this.p * v.q - this.q * v.p; n.q = this.q * v.q; return n.reduction(); } public Rational mul(Rational v) { Rational n = new Rational(p, q); n.p = this.p * v.p; n.q = this.q * v.q; return n.reduction(); } public String toString() { if (p != 0 && q != 1) return "[" + p + "/" + q + "]"; else return "[" + p + "]"; } private long abs(long a) { return a >= 0 ? a : -a; } private Rational reduction() { long flag = p * q >= 0 ? 1 : -1; long[] a = { abs(p), abs(q) }; if (a[0] == 0) { q = 1; return this; } if (a[0] == a[1]) { p = 1 * flag; q = 1; return this; } if (a[0] < a[1]) { swap(a); } long r; while ((r = a[0] % a[1]) != 0) { a[0] = a[1]; a[1] = r; } p = abs(p) * flag / a[1]; q = abs(q) / a[1]; return this; } private void swap(long[] a) { long temp = a[0]; a[0] = a[1]; a[1] = temp; } } } }