我的小组和我正在尝试创建桥梁模拟。为此,我们需要计算一个大矩阵的逆。所以我们得到了一个开源算法,在用这个网站测试之后:http://www.arndt-bruenner.de/mathe/scripts/inversematrix.htm
似乎正常工作。但是当我们在程序中使用它时,它会返回奇怪的矩阵。问题似乎很明显。它必须是没有赋予功能权利的矩阵。所以我在函数中放了一些代码来打印到达那里的矩阵。这是绝对正确的,所以我们不知道问题是什么。然后我用一个非常大的矩阵再次测试了这个函数,而不是在我们的程序中再次正常工作,所以我觉得我们的程序和函数之间有一些奇怪的交互。
功能守则:
public static double[][] inverse_matrix(double[][]in){
int st_vrs=in.length, st_stolp=in[0].length;
double[][]out=new double[st_vrs][st_stolp];
double[][]old=new double[st_vrs][st_stolp*2];
double[][]neu=new double[st_vrs][st_stolp*2];
for (int v=0;v<st_vrs;v++){//ones vector
for (int s=0;s<st_stolp*2;s++){
if (s-v==st_vrs)
old[v][s]=1;
if(s<st_stolp)
old[v][s]=in[v][s];
}
}
//zeros below the diagonal
for (int v=0;v<st_vrs;v++){
for (int v1=0;v1<st_vrs;v1++){
for (int s=0;s<st_stolp*2;s++){
if (v==v1)
neu[v][s]=old[v][s]/old[v][v];
else
neu[v1][s]=old[v1][s];
}
}
old=prepisi(neu);
for (int v1=v+1;v1<st_vrs;v1++){
for (int s=0;s<st_stolp*2;s++){
neu[v1][s]=old[v1][s]-old[v][s]*old[v1][v];
}
}
old=prepisi(neu);
}
//zeros above the diagonal
for (int s=st_stolp-1;s>0;s--){
for (int v=s-1;v>=0;v--){
for (int s1=0;s1<st_stolp*2;s1++){
neu[v][s1]=old[v][s1]-old[s][s1]*old[v][s];
}
}
old=prepisi(neu);
}
for (int v=0;v<st_vrs;v++){//rigt part of matrix is invers
for (int s=st_stolp;s<st_stolp*2;s++){
out[v][s-st_stolp]=neu[v][s];
}
}
return out;
}
static double[][] prepisi(double[][]in){
double[][]out=new double[in.length][in[0].length];
for(int v=0;v<in.length;v++){
for (int s=0;s<in[0].length;s++){
out[v][s]=in[v][s];
}
}
return out;
}
我们使用它的代码:
public class SimulationFenster extends JFrame{
int fe_anzahl;
double brueckenlaenge;
double hoehe;
double breite;
double flaeche;
double material;
double[][] kraftvektor;
double[][] steifigkeitsmatrix;
double[][] gesamtsteifigkeitsmatrix;
double[][] ergebnisvektor;
double fe_laengepixel;
double fe_laengereal;
JButton einstellungen;
JButton zurueck;
Zeichnen zeich;
double[] xKoordinaten;
double[] yKoordinaten;
Schnittpunkt[] punkte;
double scale;
Icon hintergrund=new ImageIcon(getClass().getResource("hintergrund.png"));
public SimulationFenster(int fe_anzahl,double brueckenlaenge,double breite,double hoehe,double material,double[][] kvektor){
fe_anzahl++;
this.fe_anzahl=fe_anzahl;
this.brueckenlaenge=brueckenlaenge;
this.hoehe=hoehe;
this.breite=breite;
this.material=material;
this.kraftvektor=kvektor;
this.flaeche=hoehe*breite;
xKoordinaten=new double[this.fe_anzahl];
yKoordinaten=new double[this.fe_anzahl];
punkte=new Schnittpunkt[fe_anzahl];
for(int i=0;i<fe_anzahl;i++){
punkte[i]=new Schnittpunkt();
}
fe_laengepixel=410.0/(fe_anzahl-1);
fe_laengereal=brueckenlaenge/(fe_anzahl-1);
scale=1.0;
double E=material;
double A=breite*hoehe;
double I=breite*Math.pow(hoehe, 3)/12;
double L=fe_laengereal;
steifigkeitsmatrix=new double[][]{
{ E*A/L, 0, 0,-E*A/L, 0, 0},
{ 0, 12*E*I/Math.pow(L,3),-6*E*I/Math.pow(L,2), 0,-12*E*I/Math.pow(L,3),-6*E*I/Math.pow(L,2)},
{ 0, -6*E*I/Math.pow(L,2), 4*E*I/L, 0, 6*E*I/Math.pow(L,2), 2*E*I/L},
{-E*A/L, 0, 0, E*A/L, 0, 0},
{ 0,-12*E*I/Math.pow(L,3), 6*E*I/Math.pow(L,2), 0, 12*E*I/Math.pow(L,3), 6*E*I/Math.pow(L,2)},
{ 0, -6*E*I/Math.pow(L,2), 2*E*I/L, 0, 6*E*I/Math.pow(L,2), 4*E*I/L}};
gesamtsteifigkeitsmatrix=new double[3*fe_anzahl][3*fe_anzahl];
for(int i=0;i<fe_anzahl-1;i++){
for(int j=3*i;j<3*i+6;j++){
for(int k=3*i;k<3*i+6;k++){
gesamtsteifigkeitsmatrix[j][k]=gesamtsteifigkeitsmatrix[j][k]+steifigkeitsmatrix[j%6][k%6];
}
}
}
gesamtsteifigkeitsmatrix=streichen(gesamtsteifigkeitsmatrix,0);//FEHLER vermutet
gesamtsteifigkeitsmatrix=streichen(gesamtsteifigkeitsmatrix,0);//FEHLER vermutet
gesamtsteifigkeitsmatrix=streichen(gesamtsteifigkeitsmatrix,gesamtsteifigkeitsmatrix.length-2);//FEHLER vermutet
gesamtsteifigkeitsmatrix=streichen(gesamtsteifigkeitsmatrix,gesamtsteifigkeitsmatrix.length-2);//FEHLER vermutet
kraftvektor=streichen(kraftvektor,0);//FEHLER vermutet
kraftvektor=streichen(kraftvektor,0);//FEHLER vermutet
kraftvektor=streichen(kraftvektor,kraftvektor.length-2);//FEHLER vermutet
kraftvektor=streichen(kraftvektor,kraftvektor.length-2);//FEHLER vermutet
setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
setSize(500,500);
setLocationRelativeTo(null);
setTitle("Brückensimulation");
setResizable(false);
setVisible(true);
setLayout(null);
addWindowListener(new WindowHandler());
addMouseMotionListener(new MouseHandler());
addMouseListener(new MouseHandler());
zeich=new Zeichnen();
zeich.setBounds(0, 0, 500, 500);
add(zeich);
einstellungen=new JButton("Einstellungen ändern");
einstellungen.addActionListener(new ButtonHandler());
einstellungen.setBounds(40,437,190,30);
add(einstellungen);
zurueck=new JButton("Zurück");
zurueck.addActionListener(new ButtonHandler());
zurueck.setBounds(260,437,190,30);
add(zurueck);
}
double[][] streichen(double[][] m,int linie){
double[][] t;
if(m.length==1){
t=new double[m.length][m[0].length-1];
}else if(m[0].length==1){
t=new double[m.length-1][m[0].length];
}else{
t=new double[m.length-1][m[0].length-1];
}
for(int i=0;i<m.length;i++){
for(int j=0;j<m[0].length;j++){
if(i!=linie&&j!=linie){
int a=i,b=j;
if(i>linie){
a=i-1;
}
if(j>linie){
b=j-1;
}
t[a][b]=m[i][j];
}
}
}
return t;
}
private class Zeichnen extends JLabel{
/**
*
*/
private static final long serialVersionUID = -138735436009377046L;
@Override
protected void paintComponent(Graphics g){
Graphics2D graphics=(Graphics2D)g;
graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
hintergrund.paintIcon(this,graphics,-200,-50);
ergebnisvektor=Hauptprogramm.multiplyMatrices(Hauptprogramm.inverse_matrix(gesamtsteifigkeitsmatrix),kraftvektor);//FEHLER vermutet
for(int i=1;i<kraftvektor.length/3+1;i++){
punkte[i].setGewicht(ergebnisvektor[3*i-1][0]);
}
for(int i=0;i<fe_anzahl;i++){
xKoordinaten[i]=fe_laengepixel*i+40;
yKoordinaten[i]=punkte[i].getGewicht()*scale+200;
}
rescale();
for(int i=0;i<fe_anzahl;i++){
if(i>=1){
graphics.drawLine((int)xKoordinaten[i-1],(int)yKoordinaten[i-1],(int)xKoordinaten[i],(int)yKoordinaten[i]);
}
}
for(int i=0;i<fe_anzahl;i++){
if(i==0||i==fe_anzahl-1){
graphics.setColor(Color.GRAY);
}else{
graphics.setColor(Color.BLACK);
}
graphics.fillOval((int)xKoordinaten[i]-5,(int)yKoordinaten[i]-5,10,10);
}
graphics.setColor(Color.BLACK);
graphics.drawLine(0, 430, 500, 430);//Trennlinie
graphics.drawLine(450-(int)fe_laengepixel, 415, 450, 415);//Maßstab x
graphics.fillRect(450-(int)fe_laengepixel, 410, 2, 10);
graphics.fillRect(450, 410, 2, 10);
graphics.drawString(new Double(Math.round(fe_laengereal*1000)/1000.0).toString()+"m",450-(int)fe_laengepixel+10 , 410);
graphics.drawLine(475, 200, 475, 410);//Maßstab y
graphics.fillRect(470, 200, 10, 2);
graphics.fillRect(470, 410, 10, 2);
double k=Double.MIN_VALUE;
for(double i:yKoordinaten){
if(i>k){
k=i;
}
}
k-=200;
graphics.drawString(new Double(Math.round(k/scale*1000)/1000.0).toString()+"m",430 ,345);
}
public Point getPolylinePoint(int i){
return new Point((int)xKoordinaten[i]+2,(int)yKoordinaten[i]+26);
}
void rescale(){
double k=Double.MIN_VALUE;
for(double i:yKoordinaten){
if(i>k){
k=i;
}
}
k-=200;
for(int i=0;i<yKoordinaten.length;i++){
if(k!=0){
scale=200/k;
yKoordinaten[i]=(int)((yKoordinaten[i]-200)*scale+200);
}
}
}
}
private class ButtonHandler implements ActionListener{
@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource()==einstellungen){
new EinstellungenDialog(SimulationFenster.this);
}else if( e.getSource()==zurueck){
SimulationFenster.this.dispose();
new MenuFenster();
}
}
}
private class WindowHandler implements WindowListener{
@Override
public void windowActivated(WindowEvent e) {}
@Override
public void windowClosed(WindowEvent e) {}
@Override
public void windowClosing(WindowEvent e) {
SimulationFenster.this.dispose();
new MenuFenster();
}
@Override
public void windowDeactivated(WindowEvent e) {}
@Override
public void windowDeiconified(WindowEvent e) {}
@Override
public void windowIconified(WindowEvent e) {}
@Override
public void windowOpened(WindowEvent e) {}
}
private class MouseHandler implements MouseInputListener{
//MouseMotionListener
@Override
public void mouseDragged(MouseEvent e) {}
@Override
public void mouseMoved(MouseEvent e) {
boolean anyif=false;
for(int i=1;i<fe_anzahl-1;i++){
if(e.getPoint().distance(zeich.getPolylinePoint(i))<5){
setCursor(new Cursor(Cursor.HAND_CURSOR));
anyif=true;
}
}
if(!anyif){
setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
}
}
//MouseListener
@Override
public void mouseClicked(MouseEvent e) {}
@Override
public void mouseEntered(MouseEvent e) {}
@Override
public void mouseExited(MouseEvent e) {}
@Override
public void mousePressed(MouseEvent e) {
for(int i=1;i<fe_anzahl-1;i++){
if(e.getPoint().distance(zeich.getPolylinePoint(i))<5){
new FiniteElementeDialog(SimulationFenster.this,i,kraftvektor);
repaint();
break;
}
}
}
@Override
public void mouseReleased(MouseEvent e) {}
}
}
我希望有人有时间帮助我们。 //FEHLER vermutet
是一个注释,用于标记代码中可疑的部分。