我正在尝试在Swing / JPanel中创建一些代码来获取一些(可变的)变量并绘制如下图形:
我不知道从哪里开始。想法是六边形上有关键点,每个变量一个,每个点之间画一条线,然后自定义形状内的空间将被遮蔽。任何想法?
代码原型
import java.awt.*;
import javax.swing.*;
public class DrawPolygon extends JPanel {
int xOffset = 0;
int yOffset = 0;
int sizeModifer = 50;
int numOfPoints = 8;
int linePosition = 80;
double sizeMultiplier = 1;
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Polygon[] polygons = new Polygon[5];
for (int i = 0; i < polygons.length; i++){
polygons[i] = new Polygon();
for (int q = 0; q < numOfPoints; q++) {
polygons[i].addPoint(
xOffset + (int) (linePosition + (sizeModifer*sizeMultiplier)
* Math.cos(q * 2 * Math.PI / numOfPoints)),
yOffset + (int) ((linePosition - 10) + (sizeModifer*sizeMultiplier)
* Math.sin(q * 2 * Math.PI / numOfPoints)));
}//built points
sizeMultiplier = sizeMultiplier - 0.2;
}//build polygon arrays
Polygon innerPolygon = new Polygon();
for (int i = 0; i < numOfPoints; i++) {
int randomRange = 5 + (int) (Math.random() * ((sizeModifer - 5) + 1));
innerPolygon.addPoint(
xOffset + (int) (linePosition + randomRange
* Math.cos(i * 2 * Math.PI / numOfPoints)),
yOffset + (int) ((linePosition - 10) + randomRange
* Math.sin(i * 2 * Math.PI / numOfPoints)));
}
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setStroke(new BasicStroke(1));
for (int i = 0; i < polygons.length; i++){
g2d.setColor(Color.green);
g2d.fill(polygons[i]);
g2d.setColor(Color.black);
g2d.draw(polygons[i]);
}//draw polygons from arrays
double distanceModifier = 1;
for (int i = 0; i < numOfPoints; i++) {
g2d.drawString("test"+(i+1),
xOffset + (int) (linePosition + (sizeModifer*distanceModifier)
* Math.cos(i * 2 * Math.PI / numOfPoints)),
yOffset + (int) ((linePosition - 10) + (sizeModifer*distanceModifier)
* Math.sin(i * 2 * Math.PI / numOfPoints)));
distanceModifier = distanceModifier +.01;
}
g2d.setColor(new Color(255,213,200,90));
g2d.fill(innerPolygon);
g2d.setColor(Color.red);
g2d.draw(innerPolygon);
}
@Override
public Dimension getPreferredSize() {
// TODO calculate size based on geometry
return new Dimension(160, 160);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setTitle("Show Different Polygons");
frame.add(new DrawPolygon());
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
});
}
}
答案 0 :(得分:5)
JFreeChart
包含SpiderWebPlot
,如{em>其他下的demo所示,并讨论了here。虽然SpiderWebChartDemo1
包含五个类别,但您的图片似乎包含六个类别。
答案 1 :(得分:3)
不确定。我敢肯定必须有Java库才能做到这一点;例如,Sonar显示与此类似的图表。通常最好使用别人的组件,而不是尽可能自己编写。通常我会使用JFreeChart,但看起来它没有这样的组件。
如果你想自己编写,你只需要对网上每个点的位置做一些简单的计算。从中心开始,您将从0度开始画线。然后每个后续的径向线将旋转2*pi/n
弧度。您可以应用一些简单的三角法来计算每个六边形的角度和半径的笛卡尔坐标(x,y)。最后,您将覆盖填充区域。所以算法可能是这样的。在下面的伪代码中,参数values
是一个小的正整数列表,表示多边形上的每个点作为距图中心的偏移量。因此,对于六边形,此列表中将包含六个值。
function drawGraph(values):
steps = maximum value from values
lines = number of values
webWidth = min(width, height)
centerX = width / 2
centerY = height / 2
// Draw lines
for radialLineNumber in 0..lines:
angle = radialLineNumber * 2 * pi / lines;
draw line from (centerX, centerY) to (centerX + cos(angle)*webWidth, centerY + sin(angle) * webWidth))
edgePolygon = blank polygon
for edgeNumber in 1..steps:
x = centerX + cos(angle) * webWidth * edgeNumber / steps
y = centerY + sin(angle) * webWidth * edgeNumber / steps
add (x, y) to edgePolygon
stroke polygon edgePolygon
// Draw polygon
areaPolygon = blank polygon
radialLineNumber = 0
for value in values:
angle = radialLineNumber * 2 * pi / lines;
x = centerX + cos(angle) * value * webWidth / steps
y = centerY + sin(angle) * value * webWidth / steps
add (x, y) to areaPolygon
fill polygon areaPolygon
我会留给你把这个伪代码翻译成真正的JComponent
。我使用的所有功能都在Math
或Graphics2D
上。您可能希望在绘制之前设置区域多边形的不透明度。
答案 2 :(得分:2)
关于你的例子的几点说明:
使用Graphics2D
的功能呈现实现Polygon
的{{1}}。
覆盖Shape
,正如here所述。
应在event dispatch thread上仅构建和操作Swing GUI对象。
getPreferredSize()
附录:根据评论,此修订版会恢复原始import java.awt.*;
import javax.swing.*;
public class DrawPolygon extends JPanel {
int xOffset = 0;
int yOffset = 0;
int sizeModifer = 50;
int numOfPoints = 8;
int linePosition = 80;
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Polygon outerPolygon = new Polygon();
for (int i = 0; i < numOfPoints; i++) {
outerPolygon.addPoint(
xOffset + (int) (linePosition + sizeModifer
* Math.cos(i * 2 * Math.PI / numOfPoints)),
yOffset + (int) ((linePosition - 10) + sizeModifer
* Math.sin(i * 2 * Math.PI / numOfPoints)));
}
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setColor(Color.cyan);
g2d.fill(outerPolygon);
g2d.setStroke(new BasicStroke(2));
g2d.setColor(Color.red);
g2d.draw(outerPolygon);
}
@Override
public Dimension getPreferredSize() {
// TODO calculate size based on geometry
return new Dimension(160, 160);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setTitle("Show Different Polygons");
frame.add(new DrawPolygon());
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
});
}
}
。
innerPolygon