阿基米德螺旋線極坐標方程:r = a + b·θ (a, b 為常數)。轉換為笛卡爾坐標:x = r·cosθ = (a + bθ)cosθy = r·sinθ = (a + bθ)sinθ
<dependency><groupId>org.jfree</groupId><artifactId>jfreechart</artifactId><version>1.5.4</version></dependency>import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.data.xy.DefaultXYDataset;
import org.jfree.data.xy.XYDataset;
import javax.swing.*;
import java.awt.*;
public class ArchimedeanSpiral extends JFrame {
public ArchimedeanSpiral() {
super("阿基米德螺旋線 r = a + bθ");
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(800, 600);
setLocationRelativeTo(null);
XYDataset dataset = createDataset();
JFreeChart chart = ChartFactory.createXYLineChart(
"阿基米德螺旋線 (a=0, b=0.2)", // 標題
"X", "Y", // 軸標籤
dataset, // 數據集
PlotOrientation.VERTICAL,
true, true, false // 圖例、工具提示、URL
);
// 美化繪圖區
chart.getXYPlot().setDomainGridlinesVisible(true);
chart.getXYPlot().setRangeGridlinesVisible(true);
chart.getXYPlot().setBackgroundPaint(Color.WHITE);
add(new ChartPanel(chart));
}
private XYDataset createDataset() {
DefaultXYDataset dataset = new DefaultXYDataset();
double[][] data = new double[2][1000]; // [x[]][y[]]
double a = 0, b = 0.2;
for (int i = 0; i < 1000; i++) {
double theta = i * 0.1; // θ 從 0 到 100
double r = a + b * theta;
data[0][i] = r * Math.cos(theta); // x
data[1][i] = r * Math.sin(theta); // y
}
dataset.addSeries("螺旋線", data);
return dataset;
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> new ArchimedeanSpiral().setVisible(true));
}
}
// 多條螺旋線 (不同 b 值)
for (double b : new double[]{0.1, 0.2, 0.3, 0.5}) {
double[][] data = new double[2][500];
for (int i = 0; i < 500; i++) {
double theta = i * 0.2;
double r = b * theta;
data[0][i] = r * Math.cos(theta);
data[1][i] = r * Math.sin(theta);
}
dataset.addSeries("b=" + b, data);
}
// 自定義渲染器:漸變色、線寬
XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer();
renderer.setSeriesPaint(0, Color.RED);
renderer.setSeriesStroke(0, new BasicStroke(2.0f));
chart.getXYPlot().setRenderer(renderer);
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
public class SpiralFX extends Application {
@Override
public void start(Stage stage) {
Canvas canvas = new Canvas(600, 600);
GraphicsContext gc = canvas.getGraphicsContext2D();
drawSpiral(gc, 300, 300, 0, 0.2, 50, Color.BLUE);
stage.setScene(new Scene(new StackPane(canvas)));
stage.setTitle("JavaFX Canvas 螺旋線");
stage.show();
}
void drawSpiral(GraphicsContext gc, double cx, double cy, double a, double b, int turns, Color color) {
gc.setStroke(color);
gc.setLineWidth(1.5);
gc.beginPath();
for (double theta = 0; theta < turns * 2 * Math.PI; theta += 0.01) {
double r = a + b * theta;
double x = cx + r * Math.cos(theta);
double y = cy + r * Math.sin(theta);
if (theta == 0) gc.moveTo(x, y);
else gc.lineTo(x, y);
}
gc.stroke();
}
public static void main(String[] args) { launch(); }
}