double Vektor::winkel(Vektor vektor) const { if (m_Zeilen != vektor.m_Zeilen || m_Spalten != vektor.m_Spalten) { return std::numeric_limits<float>::quiet_NaN(); } return acos(skalarprodukt(vektor) / (betrag() * vektor.betrag())) / M_PI * 180; }
bool SPIELFELD::setzeSchiff(POSITION* positionAnfang, POSITION* positionEnde, int tmpSchiffnummer)//evtl. später noch durch differenzierte fehlermeldungen ersetzen { int tmpSchifflaenge = gesetzteSchiffe[tmpSchiffnummer]->holeSchifflaenge(); ERWEITERTE_POSITION *xy = new ERWEITERTE_POSITION(tmpSchifflaenge); bool senkrecht=false; for(int i=0; i<2; i++) { if(positionAnfang->holePosition(i)<0 || positionEnde->holePosition(i)<0) return false; } //überprüfen: passt die Länge, ist es eine reihe //setze einzelne Positionen //senkrecht if( (positionAnfang->holeX()==positionEnde->holeX() && betrag(positionAnfang->holeY()-positionEnde->holeY())+1==tmpSchifflaenge) ) { for(int i=0; i<tmpSchifflaenge; i++) { xy->setzePositionX(i,positionAnfang->holeX()); xy->setzePositionY(i,kleineres(positionAnfang->holeY(),positionEnde->holeY())+i); } senkrecht=true; } //waagrecht else if( (positionAnfang->holeY()==positionEnde->holeY() && betrag(positionAnfang->holeX()-positionEnde->holeX())+1==tmpSchifflaenge) ) { for(int i=0; i<tmpSchifflaenge; i++) { xy->setzePositionY(i,positionAnfang->holeY()); xy->setzePositionX(i,kleineres(positionAnfang->holeX(),positionEnde->holeX())+i); } } else return false; if(istdaeinSchiff(xy)) return false; if(!gesetzteSchiffe[tmpSchiffnummer]->setzeaufSpielfeld(xy,senkrecht)) return false; delete xy; return true; }
void Matrix_Inverse (double M[2][2], double R[2][2]){ // M,R 2x2 double Array // Computes Inverse of M and saves it to R double s = Determinante_2D(M); if (betrag(s) < 0.001) s = sign(s) * 0.001; R[0][0] = M[1][1]/s; R[0][1] = -M[0][1]/s; R[1][0] = -M[1][0]/s; R[1][1] = M[0][0]/s; }
//Erwartet mit y geeignete 3D-Anfangsbedingungen und erstellt Plots für Energie und Drehimpuls void A3b(std::vector<double> y, std::string name, double h) { int N = ceil(100/h); //100 ist die Gesamtzeit double E_kin, E_pot, E_ges; double _L; //int size_y = y.size(); std::ofstream a3_r(("./" + name + "_r.dat").c_str()); std::ofstream a3_ekin(("./" + name + "_ekin.dat").c_str()); std::ofstream a3_epot(("./" + name + "_epot.dat").c_str()); std::ofstream a3_eges(("./" + name + "_eges.dat").c_str()); std::ofstream a3_L(("./" + name + "_L.dat").c_str()); for (int i = 0; i < N; i++) { y = Runge_Kutta(&F2,y,h,h*i); E_kin = 0.5*(y[3]*y[3]+y[4]*y[4]+y[5]*y[5]); E_pot = -1/sqrt(y[0]*y[0]+y[1]*y[1]+y[2]*y[2]); E_ges = E_kin + E_pot; _L = betrag(L(y)); a3_r << y[0] << " " << y[1] << " " << y[2] << std::endl; a3_ekin << h*i << " " << E_kin << std::endl; a3_epot << h*i << " " << E_pot << std::endl; a3_eges << h*i << " " << E_ges << std::endl; a3_L << h*i << " " << _L << std::endl; } a3_r.close(); a3_ekin.close(); a3_epot.close(); a3_eges.close(); a3_L.close(); plot3d("./",name+"_r"); plot("./",name+"_ekin"); plot("./",name+"_epot"); plot("./",name+"_eges"); plot("./",name+"_L"); }
/* Beschreibung: * prueft, ob ein Robutton mit einer Tischkante (eckiger Tisch) * kollidieren wuerde und behandelt die Kollision * Eingabewerte: * 1. Argument: Zeiger auf die Simulationsstruktur * 2. Argument: Index des zu untersuchenden Robuttons * Rueckgabewerte: * 0, wenn der Robutton nicht kollidiert ist * 1, wenn der Robutton kollidiert ist */ char pruefe_kollision_tischkante_eckig(struct simulation *s, int i) { int j; double d, m, delta_x, z, l; struct strecke st, kante; struct vektor u, a, f; struct vektor *schnittpunkt; /* alle Tischkanten durchlaufen */ for (j = 0; j < s->tisch->anzahl_ecken - 1; j++) { /* Strecke des Robuttons */ st.anfang = s->robuttons[i].position; st.ende = s->neue_positionen[i]; /* Strecke der Tischkante */ kante.anfang = s->tisch->ecken[j]; kante.ende = s->tisch->ecken[j + 1]; /* Bedingungen fuer eine Kollision */ if ((d = abstand_punkt_gerade(s->neue_positionen[i], s->tisch->ecken[j], s->tisch->ecken[j + 1])) <= 1.0 && (schnittpunkt = schnittpunkt_strecken(kante, st)) != NULL) { delta_x = s->tisch->ecken[j + 1].x - s->tisch->ecken[j].x; /* vertikale Gerade */ if (delta_x == 0) { /* x-Richtung wird umgekehrt */ s->robuttons[i].richtung.x *= (-1); /* neue Position berechnen */ if (s->robuttons[i].richtung.x > 0.0) s->neue_positionen[i].x = s->tisch->ecken[j].x + s->robuttons[i].richtung.x - d; else s->neue_positionen[i].x = s->tisch->ecken[j].x + s->robuttons[i].richtung.x + d; } else { /* Anstieg der Gerade bestimmen */ m = (s->tisch->ecken[j + 1].y - s->tisch->ecken[j].y) / delta_x; /* horizontale Gerade */ if (m == 0.0) { /* y-Richtung wird umgekehrt */ s->robuttons[i].richtung.y *= (-1.0); /* neue Position berechnen */ if (s->robuttons[i].richtung.y > 0.0) s->neue_positionen[i].y = s->tisch->ecken[j].y + s->robuttons[i].richtung.y - d; else s->neue_positionen[i].y = s->tisch->ecken[j].y + s->robuttons[i].richtung.y + d; } else { /* diagonale/schraege Gerade */ /* Punkt ausserhalb der Tischflaeche wird * an der Tischkante gespiegelt */ u.x = kante.ende.x - kante.anfang.x; u.y = kante.ende.y - kante.anfang.y; a.x = s->neue_positionen[i].x - kante.anfang.x; a.y = s->neue_positionen[i].y - kante.anfang.y; l = skalarprodukt(a, u) / skalarprodukt(u, u); f.x = kante.anfang.x + l * u.x; f.y = kante.anfang.y + l * u.y; /* neue Position berechnen */ s->neue_positionen[i].x = (-1.0) * s->neue_positionen[i].x + 2.0 * f.x; s->neue_positionen[i].y = (-1.0) * s->neue_positionen[i].y + 2.0 * f.y; /* neue Richtung berechnen */ s->robuttons[i].richtung.x = s->neue_positionen[i].x - schnittpunkt->x; s->robuttons[i].richtung.y = s->neue_positionen[i].y - schnittpunkt->y; /* Richtungsvektor zum Einheitsvektor machen */ z = betrag(s->robuttons[i].richtung); s->robuttons[i].richtung.x /= z; s->robuttons[i].richtung.y /= z; } } /* Speicher freigeben */ free(schnittpunkt); return (1); } } return (0); }
/* Beschreibung: * prueft, ob ein Robutton mit einer Tischkante (runder Tisch) * kollidieren wuerde und behandelt die Kollision * Eingabewerte: * 1. Argument: Zeiger auf die Simulationsstruktur * 2. Argument: Index des zu untersuchenden Robuttons * Rueckgabewerte: * 0, wenn der Robutton nicht kollidiert ist * 1, wenn der Robutton kollidiert ist */ char pruefe_kollision_tischkante_rund(struct simulation *s, int i) { double m, m2, n2, r, delta_x, l, z, d; struct vektor v, a, b, u, f; struct vektor *schnittpunkt; struct strecke st; /* Mittelpunkt */ v.x = s->tisch->ecken[0].x; v.y = s->tisch->ecken[0].y; /* Radius */ r = s->tisch->ecken[1].x; /* Strecke des Robuttons */ st.anfang = s->robuttons[i].position; st.ende = s->neue_positionen[i]; /* Bedingungen fuer die Kollision */ if (!ist_tischflaeche(s->tisch, s->neue_positionen[i].x, s->neue_positionen[i].y) && (schnittpunkt = schnittpunkt_strecke_kreis(st, v, r)) != NULL) { /* Tangente im Schnittpunkt ermitteln */ delta_x = schnittpunkt->x - v.x; /* horizontale Tangente */ if (delta_x == 0.0) { /* y-Richtung umkehren */ s->robuttons[i].richtung.y *= (-1.0); /* zwei Punkte der Tangente bestimmen */ a.x = schnittpunkt->x; a.y = schnittpunkt->y; b.x = schnittpunkt->x + 1.0; b.y = schnittpunkt->y; /* Abstand des Robuttons zur Tangente berechnen */ d = abstand_punkt_gerade(s->neue_positionen[i], a, b); /* neue Position berechnen */ if (s->robuttons[i].richtung.y > 0.0) s->neue_positionen[i].y = schnittpunkt->y + s->robuttons[i].richtung.y - d; else s->neue_positionen[i].y = schnittpunkt->y + s->robuttons[i].richtung.y + d; } else { /* Anstieg der Geraden vom Mittelpunkt * zum Schnittpunkt bestimmen */ m = (schnittpunkt->y - v.y) / delta_x; /* vertikale Tangente */ if (m == 0.0) { /* x-Richtung umkehren */ s->robuttons[i].richtung.x *= (-1); /* zwei Punkte der Tangente bestimmen */ a.x = schnittpunkt->x; a.y = schnittpunkt->y; b.x = schnittpunkt->x; b.y = schnittpunkt->y + 1.0; /* Abstand des Robuttons zur Tangente berechnen */ d = abstand_punkt_gerade(s->neue_positionen[i], a, b); /* neue Position berechnen */ if (s->robuttons[i].richtung.x > 0.0) s->neue_positionen[i].x = schnittpunkt->x + s->robuttons[i].richtung.x - d; else s->neue_positionen[i].x = schnittpunkt->x + s->robuttons[i].richtung.x + d; } else { /* Gleichung der Tangenten ermitteln */ m2 = (-1.0) / m; n2 = schnittpunkt->y - m2 * schnittpunkt->x; /* Punkt ausserhalb der Tischflaeche wird * an der Tangente gespiegelt */ u.x = 2.0 - 1.0; u.y = (m2 * 2.0 + n2) - (m2 * 1.0 + n2); a.x = s->neue_positionen[i].x - 1.0; a.y = s->neue_positionen[i].y - (m2 * 1.0 + n2); l = skalarprodukt(a, u) / skalarprodukt(u, u); f.x = 1.0 + l * u.x; f.y = (m2 * 1.0 + n2) + l * u.y; /* neue Position berechnen */ s->neue_positionen[i].x = (-1.0) * s->neue_positionen[i].x + 2.0 * f.x; s->neue_positionen[i].y = (-1.0) * s->neue_positionen[i].y + 2.0 * f.y; /* neue Richtung berechnen */ s->robuttons[i].richtung.x = s->neue_positionen[i].x - schnittpunkt->x; s->robuttons[i].richtung.y = s->neue_positionen[i].y - schnittpunkt->y; /* Richtungsvektor des Robuttons zum Einheitsvektor machen */ z = betrag(s->robuttons[i].richtung); s->robuttons[i].richtung.x /= z; s->robuttons[i].richtung.y /= z; } } free(schnittpunkt); return (1); } return (0); }
float Vektor::winkel(Vektor* v) { return acos((skalarprodukt(v))/((betrag()) * (v->betrag()))); }