Forum - Algoritmi
- Texture e trasformazioni affini
Bonnox (Member )
Pro
Messaggi: 85
Iscritto: 23/08/2014
Buongiorno, ho cercato ovunque su internet ma non ho trovato molto.
Sto cercando di replicare l'effetto "mode 7" dello SNES e del GBA in software, sul computer, senza usare API. Infatti so che in java esiste una classe per le trasformazioni affini, che si possono applicare ad un'immagine per poi disegnarla. Finchè si tratta di un insieme di punti mi va anche bene, basta semplicemente moltiplicare il vettore del punto per la matrice. Ma io vorrei farlo per le immagini (leggi: texture), ma non riesco a capire che algoritmo devo usare. posso utilizzare un singolo pixel come se fosse un punto? Non verrebbe un po' "bruttino"?
E poi, domanda dal quadro più ampio:
se io avessi un piano normalissimo, e una "faccia" (un poligono giacente su un altro piano), come posso calcolare la matrice di trasformazione per la texture considerando la proiezione della faccia sul piano iniziale?
Spero di essere stato abbastanza chiaro. grazie.
Ultima modifica effettuata da Bonnox il 12/08/2016 alle 14:41
Bonnox (Member )
Pro
Messaggi: 85
Iscritto: 23/08/2014
up, mi servirebbe soltanto sapere un algoritmo per fare in software il texture mapping...
Bonnox (Member )
Pro
Messaggi: 85
Iscritto: 23/08/2014
ho provato a fare qualcosa, ma al momento ho un paio di problemi.
Codice sorgente - presumibilmente Java
package testmapping ;
import java.awt.Color ;
public class Texel
{
public int x;
public int y;
public Texel
( int i,
int j,
Color c
) {
x = i;
y = j;
clr = c;
}
}
Codice sorgente - presumibilmente Java
package testmapping ;
import java.awt.Color ;
import java.awt.Graphics ;
import java.awt.Graphics2D ;
import java.awt.Point ;
import java.util.ArrayList ;
import javax.swing.JComponent ;
{
boolean trans = true ;
ArrayList< Texel[ ] > immagini = new ArrayList< Texel[ ] > ( ) ;
ArrayList< double[ ] [ ] > matrici = new ArrayList< double[ ] [ ] > ( ) ;
@Override
protected void paintComponent
( Graphics g
) {
// Auto-generated method stub
super .paintComponent ( g) ;
int xglob = getSize( ) .width ;
int yglob = getSize( ) .height ;
// Point origin = new Point(xglob / 2, yglob / 2);
if ( ! trans) paintNorm( g2) ;
else
paintAffine( g2) ;
}
{
for ( int h = 0 ; h < immagini.size ( ) ; h++ )
{
for ( int i = 0 ; i < immagini.get ( h) .length ; i++ )
{
try
{
int vect[ ] = { immagini.get ( h) [ i] .x , immagini.get ( h) [ i] .y , 1 } ;
double fin[ ] = new double [ 3] ;
fin[ 0] = vect[ 0] * matrici.get ( h) [ 0] [ 0] + vect[ 1] * matrici.get ( h) [ 0] [ 1] + vect[ 2] * matrici.get ( h) [ 0] [ 2] ;
fin[ 1] = vect[ 0] * matrici.get ( h) [ 1] [ 0] + vect[ 1] * matrici.get ( h) [ 1] [ 1] + vect[ 2] * matrici.get ( h) [ 1] [ 1] ;
fin[ 2] = vect[ 0] * matrici.get ( h) [ 2] [ 0] + vect[ 1] * matrici.get ( h) [ 2] [ 1] + vect[ 2] * matrici.get ( h) [ 2] [ 1] ;
// fin[0] /= fin[2];
// fin[1] /= fin[2];
g2.setColor ( immagini.get ( h) [ i] .clr ) ;
int x1
= ( int ) Math .
round ( fin
[ 0
] ) ; int y1
= ( int ) Math .
round ( fin
[ 1
] ) ; g2.drawLine ( x1, y1, x1, y1) ;
{
// System.err.println(i);
}
}
}
}
{
for ( int h = 0 ; h < immagini.size ( ) ; h++ )
{
for ( int i = 0 ; i < immagini.get ( h) .length ; i++ )
{
try
{
g2.setColor ( immagini.get ( h) [ i] .clr ) ;
int x = immagini.get ( h) [ i] .x ; // % mappingmain.DIM;
int y = immagini.get ( h) [ i] .y ; // mappingmain.DIM;
g2.drawLine ( x, y, x, y) ;
{
}
}
}
}
public DrawingPlane ( Texel[ ] img, double [ ] [ ] mtr)
{
immagini.add ( img) ;
matrici.add ( mtr) ;
}
public void addImage( Texel[ ] img, double [ ] [ ] mtr)
{
immagini.add ( img) ;
matrici.add ( mtr) ;
}
}
Codice sorgente - presumibilmente Java
package testmapping ;
import java.awt.BorderLayout ;
import java.awt.Color ;
import java.awt.EventQueue ;
import java.awt.image.BufferedImage ;
import java.awt.image.DataBufferInt ;
import java.io.File ;
import java.io.IOException ;
import javax.imageio.ImageIO ;
import javax.swing.JFrame ;
public class mappingmain
{
private static final double matrix1[ ] [ ] = { { 0.56826, - 0.33442, 131 } , { 0.19429, 0.65218, + 38 } , { - 0.00018, 0, 0 } } ;
// private static final double matrix2[][] = { { 1.5, -0.866, 200 }, {
// 0.866, 1.5, 200 }, { 0, 0, 1 } };
/**
* @Deprecated
*/
// public static final int DIM = 200;
/**
* Launch the application.
*/
public static void main
( String [ ] args
) {
{
public void run( )
{
try
{
mappingmain window = new mappingmain( ) ;
window.frame .setVisible ( true ) ;
{
e.printStackTrace ( ) ;
}
}
} ) ;
}
/**
* Create the application.
*/
{
initialize( ) ;
}
{
int my = bi.getHeight ( ) ;
int mx = bi.getWidth ( ) ;
int npix = mx * my;
Texel[ ] immagine = new Texel[ npix] ;
// int[] data = ((DataBufferInt)
// bi.getRaster().getDataBuffer()).getData();
for ( int i = 0 ; i < npix; i++ )
{
try
{
immagine
[ i
] = new Texel
( i
/ mx, i
% mx,
new Color ( bi.
getRGB ( i
/ mx, i
% mx
) ) ) ; {
}
}
// for (int i = 0; i < mx; i++)
// {
// for (int j = 0; j < my; j++)
// {
// immagine[i] = new Texel(i, j, new Color(bi.getRGB(i, j)));
// }
// }
//
return immagine;
}
/**
* Initialize the contents of the frame.
*/
{
frame.setBounds ( 100, 100, 800, 800) ;
frame.
setDefaultCloseOperation ( JFrame .
EXIT_ON_CLOSE ) ; DrawingPlane dp = new DrawingPlane( readimg( "D:/jpg_file_37138.jpg" ) , mappingmain.matrix1 ) ;
frame.add ( dp) ;
// dp.addImage(initimg2(), matrix2);
}
/*
* private Texel[] initimg()
* {
* Texel[] immagine = new Texel[DIM * DIM];
*
* for (int i = 0; i < immagine.length / 2; i++)
* {
* if (i % DIM < DIM / 2) immagine[i] = new Texel(i % DIM, i / DIM,
* Color.RED);
* else
* immagine[i] = new Texel(i % DIM, i / DIM, Color.YELLOW);
*
* }
* for (int i = immagine.length / 2; i < immagine.length; i++)
* {
*
* if (i % DIM < DIM / 2) immagine[i] = new Texel(i % DIM, i / DIM,
* Color.GREEN);
* else
* immagine[i] = new Texel(i % DIM, i / DIM, Color.BLUE);
*
* }
* return immagine;
* }
*/
/*
* private Texel[] initimg1()
* {
* Texel[] immagine = new Texel[DIM * DIM];
*
* for (int i = 0; i < immagine.length / 2; i++)
* {
* if (i % DIM < DIM / 2) immagine[i] = new Texel(i % DIM, i / DIM,
* Color.RED);
* else
* immagine[i] = new Texel(i % DIM, i / DIM, Color.YELLOW);
*
* }
* for (int i = immagine.length / 2; i < immagine.length; i++)
* {
*
* if (i % DIM < DIM / 2) immagine[i] = new Texel(i % DIM, i / DIM,
* Color.GREEN);
* else
* immagine[i] = new Texel(i % DIM, i / DIM, Color.BLUE);
*
* }
* for (int i = 0; i < immagine.length; i++)
* {
* int riga = i / DIM;
* int colonna = i % DIM;
*
* if (riga + colonna > DIM) immagine[i] = new Texel(immagine[i].x,
* immagine[i].y, new Color(238, 238, 238));
*
* }
*
* return immagine;
* }
*/
/*
* private Texel[] initimg2()
* {
* Texel[] immagine = new Texel[DIM * DIM];
*
* for (int i = 0; i < immagine.length / 2; i++)
* {
* if (i % DIM < DIM / 2) immagine[i] = new Texel(i % DIM, i / DIM,
* Color.RED);
* else
* immagine[i] = new Texel(i % DIM, i / DIM, Color.YELLOW);
*
* }
* for (int i = immagine.length / 2; i < immagine.length; i++)
* {
*
* if (i % DIM < DIM / 2) immagine[i] = new Texel(i % DIM, i / DIM,
* Color.GREEN);
* else
* immagine[i] = new Texel(i % DIM, i / DIM, Color.BLUE);
*
* }
* for (int i = 0; i < immagine.length; i++)
* {
* int riga = i / DIM;
* int colonna = i % DIM;
*
* if (riga + colonna <= DIM) immagine[i] = new Texel(immagine[i].x,
* immagine[i].y, new Color(238, 238, 238));
*
* }
*
* return immagine;
* }
*
*/
}
/*
*
* */
screenshot:
normale:
https://s4.postimg.org/o42em3wgd/Cattura.png
rotazione 45 gradi:
https://s3.postimg.org/pao9lkrr7/Cattura.png
(va be non è interpolato non mi interessa al momento)
i problemi sono che se l'immagine non è perfettamente quadrata, dei pixel del lato lungo vengono tagliati. Ma credo che questo dipenda dal mio algoritmo.
Mentre invece per quanto riguarda la trasformazione va bene. cioè se metto una matrice affine funziona (scalatura trasposizione e rotazione). il problema è che non mi fa la trasformazione prospettica. E sì che la matrice l'ho presa da GIMP! l'ho aperto, ho applicato lo strumento prospettiva ad una immagine e ho copiato la matrice. finchè i 4 lati rimangono paralleli a coppie funziona. se muovo i vertici in modo che sembra proiettato, no. talvolta non va neanche.
in particolare, sto cercando un effetto del genere:
http://i.stack.imgur.com/5Cceq.gif
Ma si svolge in maniera diversa questo effetto?
Secondo voi è alta la difficoltà di reperire questo comportamento nel sorgente di GIMP??
qualcuno ne sa di più in merito? grazie.
Ultima modifica effettuata da Bonnox il 21/08/2016 alle 10:30
Bonnox (Member )
Pro
Messaggi: 85
Iscritto: 23/08/2014
ok ora va già meglio. ho corretto già il secondo bug relativo alla parte più importante, la moltiplicazione riga * colonna !!
Ora se copio una matrice di GIMP e la metto dentro, si assomigliano, ovvero "c'è un barlume di prospettiva", ma ancora i lati rimangono paralleli. ecco un paragone di esempio.
https://s10.postimg.org/6i02qx7fd/Immagine.png
(hpo usato la prima immagine disponibile, uno screenshot del VBA )