Skip to content

Instantly share code, notes, and snippets.

@kishida
Last active March 7, 2024 14:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kishida/b9156d8f1632792e3bce8afb451474c2 to your computer and use it in GitHub Desktop.
Save kishida/b9156d8f1632792e3bce8afb451474c2 to your computer and use it in GitHub Desktop.
2点 A(-4,0), B(2,0)からの距離の比が2:1である点Pの軌跡を求める
#! /usr/bin/java --enable-preview --source 21
// ※Shebangで起動するときは拡張子をつけないか.java以外の拡張子にする
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import javax.swing.*;
import java.util.ArrayList;
record Point(double x, double y) {}
record IntPoint(int x, int y) {}
// ※ここはフィールドになるのでvarが使えない
double rate = 30;
IntPoint O = new IntPoint(200, 200);
/**
* 2点 A(-4,0), B(2,0)からの距離の比が2:1である点Pの軌跡を求めよ
*/
void main() {
var frame = new JFrame("円");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(600, 400);
frame.setLocation(500, 300);
var img = new BufferedImage(600, 400, BufferedImage.TYPE_INT_RGB);
var label = new JLabel(new ImageIcon(img));
frame.add(label);
frame.setVisible(true);
var points = new ArrayList<Point>();
Thread.ofVirtual().start(() -> {
Point A = new Point(-4, 0);
Point B = new Point(2, 0);
double gap = 0.07;
//上下を繰り返す
for (var dir = true;; dir = !dir) {
// 辺APの長さを4から12まで動かす
for (double d = 4 + gap; d < 12; d += gap) {
// 下側では12から4まで動く
var ap = dir ? d : (16 - d);
//System.out.println(ap);
var g = img.createGraphics();
g.setColor(Color.WHITE);
g.fillRect(0, 0, 600, 400);
g.setColor(Color.BLACK);
g.drawLine(0, O.y, 600, O.y);
g.drawLine(O.x, 0, O.x, 400);
drawPoint(g, A);
drawPoint(g, B);
// 辺ABの長さ
double ab = B.x - A.x;
// 辺BPは辺APの1/2
double bp = ap / 2;
// 3辺の長さから面積を求める
double s = heron(ap, bp, ab);
// 面積から高さを求める
double h = s * 2 / ab;
h = dir ? h : -h;
// 高さから頂点の横位置を求める
double w = Math.sqrt(ap * ap - h * h);
// 頂点P
var p = new Point(A.x + w, h);
drawLine(g, A, p);
drawLine(g, B, p);
var COUNT = 70;
points.addFirst(p);
while (points.size() > COUNT) points.removeLast();
for (int i = 0; i < points.size(); ++i) {
var bright = (float)i / COUNT;
g.setColor(new Color(1, bright, bright));
drawPoint(g, points.get(i));
}
g.dispose();
label.repaint();
try {
Thread.sleep(50);
} catch(InterruptedException ex) {}
}
}
});
}
/**
* ヘロンの公式で3辺の長さから三角形の面積を求める
*/
double heron(double a, double b, double c) {
double s = (a + b + c) / 2;
return Math.sqrt(s * (s - a) * (s - b) * (s - c));
}
// 描画用補助メソッドたち
IntPoint globalPoint(Point p) {
return new IntPoint((int)(O.x + p.x * rate), (int)(O.y - p.y * rate));
}
void drawPoint(Graphics2D g, Point p) {
var ip = globalPoint(p);
g.fillOval(ip.x - 3, ip.y - 3, 6, 6);
}
void drawLine(Graphics2D g, Point a, Point b) {
var ia = globalPoint(a);
var ib = globalPoint(b);
g.drawLine(ia.x, ia.y, ib.x, ib.y);
}
@kishida
Copy link
Author

kishida commented Mar 7, 2024

bandicam.2024-03-07.09-20-59-941.mp4

@kishida
Copy link
Author

kishida commented Mar 7, 2024

bandicam.2024-03-07.23-31-44-348.mp4

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment