java 纹理_java – 纹理变形,4分

好的,我们走了.实现为一个小的,自包含的示例,您可以使用鼠标拖动角落:

1到……

这是代码:

import java.awt.Color;

import java.awt.Graphics;

import java.awt.GridLayout;

import java.awt.Point;

import java.awt.event.MouseEvent;

import java.awt.event.MouseListener;

import java.awt.event.MouseMotionListener;

import java.awt.geom.Point2D;

import java.awt.image.BufferedImage;

import java.io.File;

import java.io.IOException;

import javax.imageio.ImageIO;

import javax.swing.ImageIcon;

import javax.swing.JFrame;

import javax.swing.JLabel;

import javax.swing.JPanel;

import javax.swing.SwingUtilities;

public class Pseudo3DTest

{

public static void main(String[] args)

{

SwingUtilities.invokeLater(new Runnable()

{

@Override

public void run()

{

createAndShowGUI();

}

});

}

private static void createAndShowGUI()

{

JFrame f = new JFrame();

f.setDefaultCloSEOperation(JFrame.EXIT_ON_CLOSE);

BufferedImage image = null;

try

{

image = ImageIO.read(new File("lena512color.png"));

}

catch (IOException e)

{

e.printStackTrace();

return;

}

f.getContentPane().setLayout(new GridLayout(1,2));

f.getContentPane().add(new JLabel(new ImageIcon(image)));

f.getContentPane().add(new Pseudo3DImagePanel(image));

f.pack();

f.setLocationRelativeTo(null);

f.setVisible(true);

}

}

class Pseudo3DImagePanel extends JPanel

implements MouseListener,MouseMotionListener

{

private final BufferedImage inputImage;

private final Point2D p0;

private final Point2D p1;

private final Point2D p2;

private final Point2D p3;

private Point2D draggedPoint;

Pseudo3DImagePanel(BufferedImage inputImage)

{

this.inputImage = inputImage;

this.p0 = new Point2D.Double(30,20);

this.p1 = new Point2D.Double(50,400);

this.p2 = new Point2D.Double(450,300);

this.p3 = new Point2D.Double(430,100);

addMouseListener(this);

addMouseMotionListener(this);

}

@Override

protected void paintComponent(Graphics g)

{

super.paintComponent(g);

BufferedImage image = Pseudo3D.computeImage(inputImage,p0,p1,p2,p3);

g.drawImage(image,null);

int r = 8;

g.setColor(Color.RED);

g.fillOval((int)p0.getX()-r,(int)p0.getY()-r,r+r,r+r);

g.fillOval((int)p1.getX()-r,(int)p1.getY()-r,r+r);

g.fillOval((int)p2.getX()-r,(int)p2.getY()-r,r+r);

g.fillOval((int)p3.getX()-r,(int)p3.getY()-r,r+r);

}

@Override

public void mousePressed(MouseEvent e)

{

Point p = e.getPoint();

int r = 8;

if (p.distance(p0) < r) draggedPoint = p0;

if (p.distance(p1) < r) draggedPoint = p1;

if (p.distance(p2) < r) draggedPoint = p2;

if (p.distance(p3) < r) draggedPoint = p3;

}

@Override

public void mouseDragged(MouseEvent e)

{

if (draggedPoint != null)

{

draggedPoint.setLocation(e.getX(),e.getY());

repaint();

}

}

@Override

public void mouseReleased(MouseEvent e)

{

draggedPoint = null;

}

@Override

public void mouseMoved(MouseEvent e) {}

@Override

public void mouseClicked(MouseEvent e) {}

@Override

public void mouseEntered(MouseEvent e) {}

@Override

public void mouseExited(MouseEvent e) {}

}

class Pseudo3D

{

static BufferedImage computeImage(

BufferedImage image,Point2D p0,Point2D p1,Point2D p2,Point2D p3)

{

int w = image.getWidth();

int h = image.getHeight();

BufferedImage result =

new BufferedImage(w,h,BufferedImage.TYPE_INT_ARGB);

Point2D ip0 = new Point2D.Double(0,0);

Point2D ip1 = new Point2D.Double(0,h);

Point2D ip2 = new Point2D.Double(w,h);

Point2D ip3 = new Point2D.Double(w,0);

Matrix3D m = computeProjectionMatrix(

new Point2D[] { p0,p3 },new Point2D[] { ip0,ip1,ip2,ip3 });

Matrix3D mInv = new Matrix3D(m);

mInv.invert();

for (int y = 0; y < h; y++)

{

for (int x = 0; x < w; x++)

{

Point2D p = new Point2D.Double(x,y);

mInv.transform(p);

int ix = (int)p.getX();

int iy = (int)p.getY();

if (ix >= 0 && ix < w && iy >= 0 && iy < h)

{

int rgb = image.getRGB(ix,iy);

result.setRGB(x,y,rgb);

}

}

}

return result;

}

// From https://math.stackexchange.com/questions/296794

private static Matrix3D computeProjectionMatrix(Point2D p0[],Point2D p1[])

{

Matrix3D m0 = computeProjectionMatrix(p0);

Matrix3D m1 = computeProjectionMatrix(p1);

m1.invert();

m0.mul(m1);

return m0;

}

// From https://math.stackexchange.com/questions/296794

private static Matrix3D computeProjectionMatrix(Point2D p[])

{

Matrix3D m = new Matrix3D(

p[0].getX(),p[1].getX(),p[2].getX(),p[0].getY(),p[1].getY(),p[2].getY(),1,1);

Point3D p3 = new Point3D(p[3].getX(),p[3].getY(),1);

Matrix3D mInv = new Matrix3D(m);

mInv.invert();

mInv.transform(p3);

m.m00 *= p3.x;

m.m01 *= p3.y;

m.m02 *= p3.z;

m.m10 *= p3.x;

m.m11 *= p3.y;

m.m12 *= p3.z;

m.m20 *= p3.x;

m.m21 *= p3.y;

m.m22 *= p3.z;

return m;

}

private static class Point3D

{

double x;

double y;

double z;

Point3D(double x,double y,double z)

{

this.x = x;

this.y = y;

this.z = z;

}

}

private static class Matrix3D

{

double m00;

double m01;

double m02;

double m10;

double m11;

double m12;

double m20;

double m21;

double m22;

Matrix3D(

double m00,double m01,double m02,double m10,double m11,double m12,double m20,double m21,double m22)

{

this.m00 = m00;

this.m01 = m01;

this.m02 = m02;

this.m10 = m10;

this.m11 = m11;

this.m12 = m12;

this.m20 = m20;

this.m21 = m21;

this.m22 = m22;

}

Matrix3D(Matrix3D m)

{

this.m00 = m.m00;

this.m01 = m.m01;

this.m02 = m.m02;

this.m10 = m.m10;

this.m11 = m.m11;

this.m12 = m.m12;

this.m20 = m.m20;

this.m21 = m.m21;

this.m22 = m.m22;

}

// From http://www.dr-lex.be/random/matrix_inv.html

void invert()

{

double invDet = 1.0 / determinant();

double nm00 = m22 * m11 - m21 * m12;

double nm01 = -(m22 * m01 - m21 * m02);

double nm02 = m12 * m01 - m11 * m02;

double nm10 = -(m22 * m10 - m20 * m12);

double nm11 = m22 * m00 - m20 * m02;

double nm12 = -(m12 * m00 - m10 * m02);

double nm20 = m21 * m10 - m20 * m11;

double nm21 = -(m21 * m00 - m20 * m01);

double nm22 = m11 * m00 - m10 * m01;

m00 = nm00 * invDet;

m01 = nm01 * invDet;

m02 = nm02 * invDet;

m10 = nm10 * invDet;

m11 = nm11 * invDet;

m12 = nm12 * invDet;

m20 = nm20 * invDet;

m21 = nm21 * invDet;

m22 = nm22 * invDet;

}

// From http://www.dr-lex.be/random/matrix_inv.html

double determinant()

{

return

m00 * (m11 * m22 - m12 * m21) +

m01 * (m12 * m20 - m10 * m22) +

m02 * (m10 * m21 - m11 * m20);

}

final void mul(double factor)

{

m00 *= factor;

m01 *= factor;

m02 *= factor;

m10 *= factor;

m11 *= factor;

m12 *= factor;

m20 *= factor;

m21 *= factor;

m22 *= factor;

}

void transform(Point3D p)

{

double x = m00 * p.x + m01 * p.y + m02 * p.z;

double y = m10 * p.x + m11 * p.y + m12 * p.z;

double z = m20 * p.x + m21 * p.y + m22 * p.z;

p.x = x;

p.y = y;

p.z = z;

}

void transform(Point2D pp)

{

Point3D p = new Point3D(pp.getX(),pp.getY(),1.0);

transform(p);

pp.setLocation(p.x / p.z,p.y / p.z);

}

void mul(Matrix3D m)

{

double nm00 = m00 * m.m00 + m01 * m.m10 + m02 * m.m20;

double nm01 = m00 * m.m01 + m01 * m.m11 + m02 * m.m21;

double nm02 = m00 * m.m02 + m01 * m.m12 + m02 * m.m22;

double nm10 = m10 * m.m00 + m11 * m.m10 + m12 * m.m20;

double nm11 = m10 * m.m01 + m11 * m.m11 + m12 * m.m21;

double nm12 = m10 * m.m02 + m11 * m.m12 + m12 * m.m22;

double nm20 = m20 * m.m00 + m21 * m.m10 + m22 * m.m20;

double nm21 = m20 * m.m01 + m21 * m.m11 + m22 * m.m21;

double nm22 = m20 * m.m02 + m21 * m.m12 + m22 * m.m22;

m00 = nm00;

m01 = nm01;

m02 = nm02;

m10 = nm10;

m11 = nm11;

m12 = nm12;

m20 = nm20;

m21 = nm21;

m22 = nm22;

}

}

}

@H_502_4@

@H_502_4@

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值