使用Java将多边形拉伸到其他多边形
我的问题是,我用一个小透视图呈现了一个矩形,我想把它拉回,再次呈现为一个矩形 为了直观地表示它,我目前在我的图像中有一些类似于红色形状的东西,我有4个使用Java将多边形拉伸到其他多边形,java,graphics,java-2d,Java,Graphics,Java 2d,我的问题是,我用一个小透视图呈现了一个矩形,我想把它拉回,再次呈现为一个矩形 为了直观地表示它,我目前在我的图像中有一些类似于红色形状的东西,我有4个点(此形状的每个角)。因此,我想要一个类似蓝色的形状,我已经为它准备了矩形对象 我想知道是否有一种方法可以复制一个多边形并将其绘制为另一个拉伸的多边形。我为Android(SetPolytoply)找到了一些东西,但在java中找不到类似的东西 是否有执行此操作的参考或代码示例,或者是否知道如何解决此问题?以下是一些代码,可以将具有四个点的多边形
点
(此形状的每个角)。因此,我想要一个类似蓝色的形状,我已经为它准备了矩形
对象
我想知道是否有一种方法可以复制一个多边形并将其绘制为另一个拉伸的多边形。我为Android(SetPolytoply)找到了一些东西,但在java中找不到类似的东西
是否有执行此操作的参考或代码示例,或者是否知道如何解决此问题?以下是一些代码,可以将具有四个点的多边形拉伸为矩形
public static Rectangle2D polyToRect(Polygon polygon) {
if (polygon.xpoints.length != 4 || polygon.ypoints.length != 4)
throw new IllegalArgumentException(
"More than four points, this cannot be fitted to a rectangle");
Rectangle2D rect = new Rectangle2D.Double();
for (int i = 0; i < 4; i++) {
Point2D point = new Point2D.Double(polygon.xpoints[i],
polygon.ypoints[i]);
rect.add(point);
}
return rect;
}
public static Polygon rectangleToPolygon(Rectangle2D rect) {
Polygon poly = new Polygon();
poly.addPoint((int) rect.getX(), (int) rect.getY());
poly.addPoint((int) (rect.getX() + rect.getWidth()), (int) rect.getY());
poly.addPoint((int) (rect.getX() + rect.getWidth()),
(int) (rect.getY() + rect.getHeight()));
poly.addPoint((int) rect.getX(), (int) (rect.getY() + rect.getHeight()));
return poly;
}
public static class drawPolyAndRect extends JPanel {
Polygon poly = new Polygon();
public drawPolyAndRect() {
poly.addPoint(0, 0);
poly.addPoint(400, 40);
poly.addPoint(400, 250);
poly.addPoint(0, 400);
}
@Override
@Transient
public Dimension getPreferredSize() {
return new Dimension(1000, 1000);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setColor(Color.green);
g2d.fill(poly);
Composite c = AlphaComposite.getInstance(AlphaComposite.SRC_OVER,
0.5f);
g2d.setColor(Color.blue);
g2d.setComposite(c);
Rectangle2D polyToRect = polyToRect(poly);
g2d.fill(polyToRect);
// displace for drawing
polyToRect.setFrame(polyToRect.getX() + 100,
polyToRect.getY() + 100, polyToRect.getWidth(),
polyToRect.getHeight());
Polygon polyToRectToPoly = rectangleToPolygon(polyToRect);
g2d.fill(polyToRectToPoly);
g2d.dispose();
}
}
public static void main(String[] args) {
JFrame frame = new JFrame("Poly to rect");
frame.getContentPane().add(new drawPolyAndRect());
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
公共静态矩形2D多边形透视(多边形){
if(polygon.xpoints.length!=4 | | polygon.ypoints.length!=4)
抛出新的IllegalArgumentException(
“超过四个点,不能将其拟合到矩形”);
Rectangle2D rect=新的Rectangle2D.Double();
对于(int i=0;i<4;i++){
Point2D point=新的Point2D.Double(polygon.xpoints[i],
多边形点[i];
直接加(点);
}
返回矩形;
}
公共静态多边形矩形拓扑多边形(矩形2D矩形){
多边形多边形=新多边形();
poly.addPoint((int)rect.getX(),(int)rect.getY());
poly.addPoint((int)(rect.getX()+rect.getWidth(),(int)rect.getY());
poly.addPoint((int)(rect.getX()+rect.getWidth()),
(int)(rect.getY()+rect.getHeight());
poly.addPoint((int)rect.getX(),(int)(rect.getY()+rect.getHeight());
返回多边形;
}
公共静态类drawPolyAndRect扩展了JPanel{
多边形多边形=新多边形();
公共部门{
poly.addPoint(0,0);
poly.addPoint(400,40);
poly.addPoint(400250);
poly.addPoint(0400);
}
@凌驾
@短暂的
公共维度getPreferredSize(){
返回新维度(10001000);
}
@凌驾
受保护组件(图形g){
超级组件(g);
Graphics2D g2d=(Graphics2D)g.create();
g2d.setColor(Color.green);
g2d.填充(poly);
Composite c=AlphaComposite.getInstance(AlphaComposite.SRC_超过,
0.5f);
g2d.setColor(Color.blue);
g2d.setComposite(c);
矩形2D多边形切割=多边形切割(多边形);
g2d.填充(polyToRect);
//为绘图而替换
polyToRect.setFrame(polyToRect.getX()+100,
polyToRect.getY()+100,polyToRect.getWidth(),
polyToRect.getHeight());
多边形polyToRectToPoly=矩形拓扑多边形(polyToRect);
g2d.填充(polyToRectToPoly);
g2d.dispose();
}
}
公共静态void main(字符串[]args){
JFrame=新JFrame(“多边形到矩形”);
frame.getContentPane().add(新的drawPolyAndRect());
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
从本质上讲,这使用了向空矩形添加点的方式。2D构造包含所有四个点的最小矩形,拉伸多边形。如果希望返回的矩形为多边形,请选中第二个静态方法。图片:
我想我了解您需要什么:可以应用于图像的所谓透视变换。Java有内置的,但是仿射变换总是保持线的“平行性”,所以不能使用它
现在,如果您在web上搜索“java透视图转换”,您将发现许多选项,如JavaFX、JAI。如果您只需要拉伸图像,您也可以使用JHLAB,还有其他选项。我不知道这是否能帮助您,但让我告诉您我所了解的内容:
import javax.swing.*;
import java.awt.*;
public class PolyToRectangle extends JPanel {
public static final int SPEED = 50; //less = more fast.
private int ax = 0, bx = 800, cx = 800, dx = 0,
ay = 0, by = 40, cy = 250, dy = 400;
private Polygon poly;
public PolyToRectangle() {
setPreferredSize(new Dimension(1200, 720));
poly = new Polygon(new int[]{ax, bx, cx, dx}, new int[]{ay, by, cy, dy}, 4);
}
@Override
public void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
g2d.draw(poly);
g2d.fill(poly);
}
public void polyToRectangle() throws InterruptedException {
int flag = 0;
for (int i = 0; i < 150; i++) {
flag++;
poly.addPoint(ax, ay);
poly.addPoint(bx, (by = flag % 3 == 0 ? --by : by));
poly.addPoint(cx, cy++);
poly.addPoint(dx, dy);
Thread.sleep(SPEED);
repaint();
}
}
protected void clear(Graphics g) {
super.paintComponent(g);
}
public static void main(String[] args) throws InterruptedException {
Frame frame = new JFrame();
PolyToRectangle se = new PolyToRectangle();
frame.add(se);
frame.pack();
frame.setVisible(true);
se.polyToRectangle();
}
}
import javax.swing.*;
导入java.awt.*;
公共类PolyToRectangle扩展了JPanel{
公共静态最终整型速度=50;//更少=更快。
私有整数ax=0,bx=800,cx=800,dx=0,
ay=0,by=40,cy=250,dy=400;
私有多边形多边形;
公共PolyToRectangle(){
设置首选尺寸(新尺寸(1200720));
多边形=新多边形(新int[]{ax,bx,cx,dx},新int[]{ay,by,cy,dy},4);
}
@凌驾
公共组件(图形g){
Graphics2D g2d=(Graphics2D)g;
g2d.draw(poly);
g2d.填充(poly);
}
public void polyToRectangle()引发中断异常{
int标志=0;
对于(int i=0;i<150;i++){
flag++;
多边形添加点(ax,ay);
poly.addPoint(bx,(by=flag%3==0?--by:by));
poly.addPoint(cx,cy++);
poly.addPoint(dx,dy);
线程。睡眠(速度);
重新油漆();
}
}
保护空隙清除(图g){
超级组件(g);
}
公共静态void main(字符串[]args)引发InterruptedException{
框架=新的JFrame();
PolyToRectangle se=新的PolyToRectangle();
帧。添加(se);
frame.pack();
frame.setVisible(true);
se.polyToRectangle();
}
}
好的,正如你所看到的,这段代码更像是一个“PolyToSquare”,而不是一个polytostangle,但主要是为了显示使用线程重新绘制的“效果”。在for中睡眠,也许这就是你所说的“视觉拉伸”,请注意,for上的迭代次数取决于从点1和点2到“拉伸”的像素数从多边形到矩形,这是一个“手工制作”的效果,也许@lbalazscs建议的是最好的解决方案,希望对您有所帮助
编辑:编辑代码,使其更清晰,并以更具体的方式遵循您的目标
(现在更像是一个PolyToRectangle,修复了bx和cx值)。一个基于JavaFX的解决方案,使用了
切换透视图
import javafx.animation.*; import javafx.application.*; import javafx.beans.value.*; import javafx.geometry.Pos; import javafx.scene.*; import javafx.scene.control.ToggleButton; import javafx.scene.effect.PerspectiveTransform; import javafx.scene.image.*; import javafx.scene.layout.VBox; import javafx.scene.paint.Color; import javafx.scene.shape.Rectangle; import javafx.scene.text.*; import javafx.stage.Stage; import javafx.util.Duration; public class PerspectiveMovement extends Application { // perspective transformed group width and height. private final int W = 280; private final int H = 96; // upper right and lower right co-ordinates of perspective transformed group. private final int URY = 35; private final int LRY = 65; @Override public void start(Stage stage) { final PerspectiveTransform perspectiveTransform = createPerspectiveTransform(); final Group group = new Group(); group.setCache(true); setContent(group); final ToggleButton perspectiveToggle = createToggle( group, perspectiveTransform ); VBox layout = new VBox(10); layout.setAlignment(Pos.CENTER); layout.getChildren().setAll( perspectiveToggle, createMorph(perspectiveToggle, group, perspectiveTransform), group ); layout.setStyle("-fx-padding: 10px; -fx-background-color: rgb(17, 20, 25);"); stage.setScene(new Scene(layout)); stage.show(); } private void setContent(Group group) { Rectangle rect = new Rectangle(0, 5, W, 80); rect.setFill(Color.web("0x3b596d")); Text text = new Text(); text.setX(4.0); text.setY(60.0); text.setText("A long time ago"); text.setFill(Color.ALICEBLUE); text.setFont(Font.font(null, FontWeight.BOLD, 36)); Image image = new Image( "http://icons.iconarchive.com/icons/danrabbit/elementary/96/Star-icon.png" ); ImageView imageView = new ImageView(image); imageView.setX(50); group.getChildren().addAll(rect, imageView, text); } private PerspectiveTransform createPerspectiveTransform() { PerspectiveTransform perspectiveTransform = new PerspectiveTransform(); perspectiveTransform.setUlx(0.0); perspectiveTransform.setUly(0.0); perspectiveTransform.setUrx(W); perspectiveTransform.setUry(URY); perspectiveTransform.setLrx(W); perspectiveTransform.setLry(LRY); perspectiveTransform.setLlx(0.0); perspectiveTransform.setLly(H); return perspectiveTransform; } private ToggleButton createToggle(final Group group, final PerspectiveTransform perspectiveTransform) { final ToggleButton toggle = new ToggleButton("Toggle Perspective"); toggle.selectedProperty().addListener(new ChangeListener<Boolean>() { @Override public void changed(ObservableValue<? extends Boolean> observable, Boolean wasSelected, Boolean selected) { if (selected) { perspectiveTransform.setUry(URY); perspectiveTransform.setLry(LRY); group.setEffect(perspectiveTransform); } else { group.setEffect(null); } } }); return toggle; } private ToggleButton createMorph(final ToggleButton perspectiveToggle, final Group group, final PerspectiveTransform perspectiveTransform) { final Timeline distorter = new Timeline( new KeyFrame( Duration.seconds(0), new KeyValue(perspectiveTransform.uryProperty(), 0, Interpolator.LINEAR), new KeyValue(perspectiveTransform.lryProperty(), H, Interpolator.LINEAR) ), new KeyFrame( Duration.seconds(3), new KeyValue(perspectiveTransform.uryProperty(), URY, Interpolator.LINEAR), new KeyValue(perspectiveTransform.lryProperty(), LRY, Interpolator.LINEAR) ) ); final ToggleButton morphToggle = new ToggleButton("Morph Perspective"); morphToggle.selectedProperty().addListener(new ChangeListener<Boolean>() { @Override public void changed(ObservableValue<? extends Boolean> observable, Boolean wasSelected, Boolean selected) { if (!perspectiveToggle.isSelected()) { perspectiveToggle.fire(); } if (selected) { distorter.setRate(1); distorter.play(); } else { distorter.setRate(-1); distorter.play(); } } }); return morphToggle; } }