Last active
March 7, 2024 14:32
-
-
Save kishida/b9156d8f1632792e3bce8afb451474c2 to your computer and use it in GitHub Desktop.
2点 A(-4,0), B(2,0)からの距離の比が2:1である点Pの軌跡を求める
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /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); | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
bandicam.2024-03-07.23-31-44-348.mp4