是否可以围绕折线创建轮廓
Is it possible to create an outline around a PolyLine
本例绘制了一条简单的多段线。
是否可以用红色围绕这条多段线绘制轮廓。
不是一个大的红色方块,而是一个将原始多段线勾勒出距离所有区域 3-5 点的方块。
尝试了一些计算并针对固定值进行了计算,但是当折线值是随机的时,该算法并不总是有效,因为线的下一部分可能向右转而不是向左转,或者向上转而不是向下转。
你几乎必须向前看 2-3 个点才能知道你是要加还是减。
有更简单的方法吗?
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class PolyLine extends JPanel
{
public void paint(Graphics g) {
int[] xs = {25, 125, 85, 75, 25, 65, };
int[] ys = {50, 50, 100, 110, 150, 100};
BasicStroke traceStroke = new BasicStroke (1);
Graphics2D gc = (Graphics2D) g.create();
gc.setStroke(traceStroke);
gc.setColor(Color.BLUE);
gc.drawPolyline(xs, ys, 6);
}
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.add(new PolyLine());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setBounds(20,20, 1500,1500);
frame.setVisible(true);
}
}
首先,请注意:通常最好将几何基元作为 Shape
。 drawPolyline
函数(使用这些奇整数数组坐标)有些过时了。将折线创建为 Path2D
更加灵活。
对于您描述的任务,还需要将多段线坐标转换为 Path2D
(如果您无论如何都切换为 Path2D
,则可以省略此转换步骤)。
当您将多段线设为 Shape
时,任务相当简单:您可以创建此形状的描边版本,使用具有所需粗细的 BasicStroke
和 cap/join 特性,通过调用 BasicStroke#createStrokedShape
。这个形状基本上就是一个"thick line"的形状。为了避免连接处出现伪影,您可以从这个 Shape
创建一个 Area
,然后绘制这个区域。
所以最后用2行代码画出实际的轮廓,结果如下:
但是这里的 MCVE,为了完整起见:
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Area;
import java.awt.geom.Path2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class ShapeOutlineTest
{
public static void main(String[] args)
{
SwingUtilities.invokeLater(() -> createAndShowGUI());
}
private static void createAndShowGUI()
{
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.getContentPane().add(new ShapeOutlineTestPanel());
f.setSize(500, 500);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
}
class ShapeOutlineTestPanel extends JPanel
{
@Override
protected void paintComponent(Graphics gr)
{
super.paintComponent(gr);
Graphics2D g = (Graphics2D) gr;
int[] xs = { 25, 125, 85, 75, 25, 65, };
int[] ys = { 50, 50, 100, 110, 150, 100 };
BasicStroke traceStroke = new BasicStroke(1);
g.setStroke(traceStroke);
g.setColor(Color.BLUE);
g.drawPolyline(xs, ys, 6);
Path2D path = new Path2D.Double();
for (int i = 0; i < xs.length; i++)
{
if (i == 0)
{
path.moveTo(xs[i], ys[i]);
}
else
{
path.lineTo(xs[i], ys[i]);
}
}
g.setColor(Color.RED);
BasicStroke stroke = new BasicStroke(
10.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
g.draw(new Area(stroke.createStrokedShape(path)));
}
}
本例绘制了一条简单的多段线。
是否可以用红色围绕这条多段线绘制轮廓。 不是一个大的红色方块,而是一个将原始多段线勾勒出距离所有区域 3-5 点的方块。
尝试了一些计算并针对固定值进行了计算,但是当折线值是随机的时,该算法并不总是有效,因为线的下一部分可能向右转而不是向左转,或者向上转而不是向下转。
你几乎必须向前看 2-3 个点才能知道你是要加还是减。
有更简单的方法吗?
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class PolyLine extends JPanel
{
public void paint(Graphics g) {
int[] xs = {25, 125, 85, 75, 25, 65, };
int[] ys = {50, 50, 100, 110, 150, 100};
BasicStroke traceStroke = new BasicStroke (1);
Graphics2D gc = (Graphics2D) g.create();
gc.setStroke(traceStroke);
gc.setColor(Color.BLUE);
gc.drawPolyline(xs, ys, 6);
}
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.add(new PolyLine());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setBounds(20,20, 1500,1500);
frame.setVisible(true);
}
}
首先,请注意:通常最好将几何基元作为 Shape
。 drawPolyline
函数(使用这些奇整数数组坐标)有些过时了。将折线创建为 Path2D
更加灵活。
对于您描述的任务,还需要将多段线坐标转换为 Path2D
(如果您无论如何都切换为 Path2D
,则可以省略此转换步骤)。
当您将多段线设为 Shape
时,任务相当简单:您可以创建此形状的描边版本,使用具有所需粗细的 BasicStroke
和 cap/join 特性,通过调用 BasicStroke#createStrokedShape
。这个形状基本上就是一个"thick line"的形状。为了避免连接处出现伪影,您可以从这个 Shape
创建一个 Area
,然后绘制这个区域。
所以最后用2行代码画出实际的轮廓,结果如下:
但是这里的 MCVE,为了完整起见:
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Area;
import java.awt.geom.Path2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class ShapeOutlineTest
{
public static void main(String[] args)
{
SwingUtilities.invokeLater(() -> createAndShowGUI());
}
private static void createAndShowGUI()
{
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.getContentPane().add(new ShapeOutlineTestPanel());
f.setSize(500, 500);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
}
class ShapeOutlineTestPanel extends JPanel
{
@Override
protected void paintComponent(Graphics gr)
{
super.paintComponent(gr);
Graphics2D g = (Graphics2D) gr;
int[] xs = { 25, 125, 85, 75, 25, 65, };
int[] ys = { 50, 50, 100, 110, 150, 100 };
BasicStroke traceStroke = new BasicStroke(1);
g.setStroke(traceStroke);
g.setColor(Color.BLUE);
g.drawPolyline(xs, ys, 6);
Path2D path = new Path2D.Double();
for (int i = 0; i < xs.length; i++)
{
if (i == 0)
{
path.moveTo(xs[i], ys[i]);
}
else
{
path.lineTo(xs[i], ys[i]);
}
}
g.setColor(Color.RED);
BasicStroke stroke = new BasicStroke(
10.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
g.draw(new Area(stroke.createStrokedShape(path)));
}
}