第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問題,去搜搜看,總會(huì)有你想問的

建立一個(gè)匹配3點(diǎn)變換的AffineTransform對象

建立一個(gè)匹配3點(diǎn)變換的AffineTransform對象

至尊寶的傳說 2023-06-04 11:23:22
我知道仿射變換前后 3 個(gè)點(diǎn)(p0、p1、p2)的位置(X 和 Y)。我想構(gòu)建匹配此轉(zhuǎn)換的 AffineTransformation 對象。換句話說,我想找到將已知點(diǎn) p0、p1、p2 移動(dòng)到它們已知目的地的仿射變換。這是我到目前為止所做的:package image_transformation;import java.awt.geom.AffineTransform;import java.awt.image.AffineTransformOp;import java.awt.image.BufferedImage;import java.io.File;import java.io.IOException;import javax.imageio.ImageIO;import math.Vector2d;public class ImageTransformation {    public static void main(String[] args) throws IOException {        // the position of the points before the transformation        Vector2d[] src = new Vector2d[] {                new Vector2d(486, 191),                new Vector2d(456, 565),                new Vector2d(149, 353)        };        // the position of the points after the transformation        Vector2d[] dest = new Vector2d[] {                new Vector2d(0, 0),                new Vector2d(0, 600),                new Vector2d(600, 600)        };        // the transformation that we are building        AffineTransform at = new AffineTransform();        // the translation to move the p0 to its destination        Vector2d translationVec = dest[0].sub(src[0]);        at.translate(translationVec.x, translationVec.y);        // the rotation around p0 (it will not move) to align p0, p1 and p1's destination        Vector2d vec0 = src[1].sub(src[0]);        Vector2d vec1 = dest[1].sub(dest[0]);        double angle = orientedAngle(vec0, vec1);        at.rotate(angle, src[0].x, src[0].y);    }Vector2d 類做一些關(guān)于向量的基本數(shù)學(xué)運(yùn)算,它的每個(gè)方法都通過它們的名稱(sub[stract]、mult[iply]、length、normalize 等)不言自明。我不知道如何終止這個(gè)算法。此外,如果已經(jīng)存在可以完成所有這些操作的方法,我會(huì)非常樂意使用它。
查看完整描述

1 回答

?
波斯汪

TA貢獻(xiàn)1811條經(jīng)驗(yàn) 獲得超4個(gè)贊

這至少與Texture deforming密切相關(guān),4分,但我不會(huì)說它可以被認(rèn)為是重復(fù)的。

你在那里做了很多數(shù)學(xué)工作。但也許這不是必需的。使用正確的方法,問題本身是相當(dāng)微不足道的??紤]二維仿射變換的含義:它將一個(gè)空間變換到另一個(gè)空間。這里的關(guān)鍵點(diǎn)是:

矩陣列是將矩陣應(yīng)用于單位向量的結(jié)果

現(xiàn)在,當(dāng)你有 3 個(gè)點(diǎn)時(shí),你可以從它們計(jì)算向量:

double dx1 = p1.getX() - p0.getX();

double dy1 = p1.getY() - p0.getY();


double dx2 = p2.getX() - p0.getX();

double dy2 = p2.getY() - p0.getY();

然后您可以簡單地將這些值插入AffineTransform.?最后一列AffineTransform包含由 給出的翻譯p0。結(jié)果是AffineTransform將點(diǎn) (0,0)、(1,0) 和 (0,1) 分別轉(zhuǎn)換為點(diǎn)p0、p1p2。當(dāng)您反轉(zhuǎn)此變換時(shí),它會(huì)將點(diǎn)p0、p1和轉(zhuǎn)換p2為點(diǎn) (0,0)、(1,0) 和 (0,1)。

所以你所要做的就是

  • 創(chuàng)建將源點(diǎn)轉(zhuǎn)換為單位向量的變換

  • 創(chuàng)建將單位向量轉(zhuǎn)換為目標(biāo)點(diǎn)的變換

  • 將兩者連接起來

偽代碼 (!) 真的很簡單

? ? AffineTransform unitToSrc = computeTransform(src[0], src[1], src[2]);

? ? AffineTransform unitToDst = computeTransform(dst[0], dst[1], dst[2]);

? ? AffineTransform at = new AffineTransform();

? ? at.concatenate(unitToDst);

? ? at.concatenate(unitToSrc.inverted());

整個(gè)事情都在這里實(shí)現(xiàn),作為 MCVE。紅色點(diǎn)是“源”點(diǎn),綠色點(diǎn)是“目的地”點(diǎn)。你可以用鼠標(biāo)拖動(dòng)它們:

http://img3.sycdn.imooc.com/647c03e00001305202740287.jpg

藍(lán)色圓圈表示將變換應(yīng)用于源點(diǎn)的結(jié)果,您可以看到它們最終到達(dá)了所需的目標(biāo)位置。


實(shí)際計(jì)算是通過computeTransform方法完成的。請注意,這是基于java.awt.geom.Point2D類(而不是Vector2d您省略的類)實(shí)現(xiàn)的,但這應(yīng)該很容易更改:點(diǎn)或矢量類唯一使用的是 x/y 坐標(biāo)。除此之外,實(shí)現(xiàn)中根本不涉及(自定義)數(shù)學(xué)。唯一的數(shù)學(xué)是反轉(zhuǎn)仿射變換,但有一個(gè)內(nèi)置的功能。


import java.awt.BorderLayout;

import java.awt.Color;

import java.awt.Graphics;

import java.awt.Graphics2D;

import java.awt.RenderingHints;

import java.awt.event.MouseEvent;

import java.awt.event.MouseListener;

import java.awt.event.MouseMotionListener;

import java.awt.geom.AffineTransform;

import java.awt.geom.Ellipse2D;

import java.awt.geom.NoninvertibleTransformException;

import java.awt.geom.Point2D;

import java.util.Arrays;


import javax.swing.JFrame;

import javax.swing.JPanel;

import javax.swing.SwingUtilities;


public class AffineTransformFromPoints

{

? ? public static void main(String[] args)

? ? {

? ? ? ? SwingUtilities.invokeLater(() -> createAndShowGUI());

? ? }


? ? private static void createAndShowGUI()

? ? {

? ? ? ? JFrame f = new JFrame();

? ? ? ? f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

? ? ? ? AffineTransformFromPointsPanel panel =?

? ? ? ? ? ? new AffineTransformFromPointsPanel();

? ? ? ? f.getContentPane().setLayout(new BorderLayout());

? ? ? ? f.getContentPane().add(panel, BorderLayout.CENTER);

? ? ? ? f.setSize(1200,900);

? ? ? ? f.setLocationRelativeTo(null);

? ? ? ? f.setVisible(true);

? ? }


}


class AffineTransformFromPointsPanel extends JPanel?

? ? implements MouseListener, MouseMotionListener

{

? ? private Point2D draggedPoint;


? ? // the position of the points before the transformation

? ? Point2D[] src = new Point2D[] {

? ? ? ? new Point2D.Double(486, 191),

? ? ? ? new Point2D.Double(456, 565),

? ? ? ? new Point2D.Double(149, 353)

? ? };


? ? // the position of the points after the transformation

? ? Point2D[] dst = new Point2D[] {

? ? ? ? new Point2D.Double(0, 0),

? ? ? ? new Point2D.Double(0, 600),

? ? ? ? new Point2D.Double(600, 600)

? ? };



? ? public AffineTransformFromPointsPanel()

? ? {

? ? ? ? addMouseListener(this);

? ? ? ? addMouseMotionListener(this);

? ? }


? ? @Override

? ? protected void paintComponent(Graphics gr)

? ? {

? ? ? ? super.paintComponent(gr);

? ? ? ? Graphics2D g = (Graphics2D)gr;

? ? ? ? g.setColor(Color.WHITE);

? ? ? ? g.fillRect(0, 0, getWidth(), getHeight());


? ? ? ? g.setRenderingHint(

? ? ? ? ? ? RenderingHints.KEY_ANTIALIASING,?

? ? ? ? ? ? RenderingHints.VALUE_ANTIALIAS_ON);


? ? ? ? g.setColor(Color.RED);

? ? ? ? for (Point2D v : src)

? ? ? ? {

? ? ? ? ? ? paint(g, v);

? ? ? ? }


? ? ? ? g.setColor(Color.GREEN);

? ? ? ? for (Point2D v : dst)

? ? ? ? {

? ? ? ? ? ? paint(g, v);

? ? ? ? }


? ? ? ? g.setColor(Color.BLUE);

? ? ? ? AffineTransform at = computeTransform(src, dst);

? ? ? ? for (Point2D v : src)

? ? ? ? {

? ? ? ? ? ? draw(g, v, at);

? ? ? ? }

? ? }


? ? private static AffineTransform computeTransform(

? ? ? ? Point2D src[], Point2D dst[])

? ? {

? ? ? ? AffineTransform unitToSrc = computeTransform(src[0], src[1], src[2]);

? ? ? ? AffineTransform unitToDst = computeTransform(dst[0], dst[1], dst[2]);

? ? ? ? AffineTransform srcToUnit = null;

? ? ? ? try

? ? ? ? {

? ? ? ? ? ? srcToUnit = unitToSrc.createInverse();

? ? ? ? }

? ? ? ? catch (NoninvertibleTransformException e)

? ? ? ? {

? ? ? ? ? ? System.out.println(e.getMessage());

? ? ? ? ? ? return new AffineTransform();

? ? ? ? }

? ? ? ? AffineTransform at = new AffineTransform();

? ? ? ? at.concatenate(unitToDst);

? ? ? ? at.concatenate(srcToUnit);

? ? ? ? return at;

? ? }


? ? private static AffineTransform computeTransform(

? ? ? ? Point2D p0, Point2D p1, Point2D p2)

? ? {

? ? ? ? AffineTransform at = new AffineTransform();

? ? ? ? double dx1 = p1.getX() - p0.getX();

? ? ? ? double dy1 = p1.getY() - p0.getY();

? ? ? ? double dx2 = p2.getX() - p0.getX();

? ? ? ? double dy2 = p2.getY() - p0.getY();

? ? ? ? at.setTransform(dx1, dy1, dx2, dy2, p0.getX(), p0.getY());

? ? ? ? return at;

? ? }


? ? private static void paint(Graphics2D g, Point2D p)

? ? {

? ? ? ? double r = 6;

? ? ? ? g.fill(new Ellipse2D.Double(

? ? ? ? ? ? p.getX() - r, p.getY() - r, r + r, r + r));

? ? }


? ? private static void draw(Graphics2D g, Point2D v, AffineTransform at)

? ? {

? ? ? ? double r = 8;

? ? ? ? Point2D p = new Point2D.Double(v.getX(), v.getY());

? ? ? ? at.transform(p, p);

? ? ? ? g.draw(new Ellipse2D.Double(

? ? ? ? ? ? p.getX() - r, p.getY() - r, r + r, r + r));

? ? }


? ? @Override

? ? public void mouseDragged(MouseEvent e)

? ? {

? ? ? ? if (draggedPoint != null)

? ? ? ? {

? ? ? ? ? ? draggedPoint.setLocation(e.getPoint());

? ? ? ? ? ? repaint();

? ? ? ? }

? ? }



? ? @Override

? ? public void mousePressed(MouseEvent e)

? ? {

? ? ? ? draggedPoint = closest(e.getPoint(), Arrays.asList(src));

? ? ? ? if (draggedPoint == null)

? ? ? ? {

? ? ? ? ? ? draggedPoint = closest(e.getPoint(), Arrays.asList(dst));

? ? ? ? }

? ? }


? ? private static Point2D closest(

? ? ? ? Point2D p, Iterable<? extends Point2D> points)

? ? {

? ? ? ? final double threshold = 10;

? ? ? ? Point2D closestPoint = null;

? ? ? ? double minDistance = Double.MAX_VALUE;


? ? ? ? for (Point2D point : points)

? ? ? ? {

? ? ? ? ? ? double dd = point.distance(p);

? ? ? ? ? ? if (dd < threshold && dd < minDistance)

? ? ? ? ? ? {

? ? ? ? ? ? ? ? minDistance = dd;

? ? ? ? ? ? ? ? closestPoint = point;

? ? ? ? ? ? }

? ? ? ? }

? ? ? ? return closestPoint;

? ? }


? ? @Override

? ? public void mouseReleased(MouseEvent e)

? ? {

? ? ? ? draggedPoint = null;

? ? }


? ? @Override

? ? public void mouseMoved(MouseEvent e)

? ? {

? ? ? ? // Nothing to do here

? ? }


? ? @Override

? ? public void mouseClicked(MouseEvent e)

? ? {

? ? ? ? // Nothing to do here

? ? }


? ? @Override

? ? public void mouseEntered(MouseEvent e)

? ? {

? ? ? ? // Nothing to do here

? ? }


? ? @Override

? ? public void mouseExited(MouseEvent e)

? ? {

? ? ? ? // Nothing to do here

? ? }


}



查看完整回答
反對 回復(fù) 2023-06-04
  • 1 回答
  • 0 關(guān)注
  • 164 瀏覽

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)