Nhờ dò lỗi code hướng đối tượng

Mình không học về lập trình nhưng trong quá trình giải bài tập nảy sinh chút vấn đề và mình nghĩ giải quyết bằng lập trình sẽ tốt hơn nên mình vừa học C++ trong 1 tuần và viết chương trình sau nhưng chạy không ra kết quả.

Mình hi vọng các bạn có thể giúp mình tìm lỗi sai trong thuật toán ở chương trình sau, mình chưa hoàn thiện hoàn toàn chương trình, chỉ đang chạy thử xem thuật toán có chính xác hay không, chương trình không báo lỗi nhưng không cho ra kết quả. Xin chân thành cảm ơn!

#include <iostream>
#include <cmath>
#define PI 3.14159
using namespace std;

struct Point{
   double x = 0.0;
   double y = 0.0; 
} A, B, C, D, E, F, G;
struct Normal{
       double xn;
       double yn;
    } n, n1;
struct Line{
   double a;
   double b;
   double c; 
} AB, BC, AC, EF, DF;

void prisma(double L, double l, double beta, double alpha){
   A.x = 0.0;
   A.y = L*tan(beta);
   B.x = -L;
   B.y = 0.0;
   C.x = L;
   C.y = 0.0;
   D.x = -l;
   D.y = 0.0;
   E.x = l;
   E.y = 0.0;
   F.x = 0.0;
   F.y = l*tan(alpha);
}

void Equa(Line t, Point X, Point Y){//phương trình đt
    n.xn = -(Y.y - X.y);
    n.yn = Y.x - X.x;
    
    t.a = n.xn;
    t.b = n.yn;
    t.c = -(n.xn*X.x + n.yn*X.y);
}

double Length(Point X, Point Y){ // độ dài đoạn th
   return sqrt(pow(X.x-Y.x,2)+pow(X.y-Y.y,2));
}

void PofInters(Line t, Line k){ //tìm điểm phản xạ
    double d, dx, dy;
    d = t.a*k.b - k.a*t.b;
    dx = t.c*k.b - k.c*t.b;
    dy = t.a*k.c - k.a*t.c;
    G.x = dx/d;
    G.y = dy/d;
}

bool Middle(Point X, Point Y, Point G){// kiểm tra 
 //nằm giữa
   if ((Length(X, G) + Length(Y, G)) == length(Point X, diem Y)) 
   return true;
}

void Angle(Line t, Line k){ //tính góc phản xạ
   double gamma = acos(abs(t.a*k.a + t.b*k.b)/(sqrt(t.a*t.a + t.b*t.b)*sqrt(k.a*k.a + k.b*k.b)));
   if (gamma < PI/2) gamma = PI/2 - gamma;
   else gamma = gamma - PI/2;
}

void Normal1(double Angle1, Line t){ //pháp tuyến //mới
    n1.xn = sqrt(t.a*t.a + t.b*t.b)*cos(Angle1 + atan(t.a/t.b));
    n1.yn = sqrt(t.a*t.a + t.b*t.b)*sin(Angle1 + atan(t.a/t.b));
}

void equaNorm(Line t, Normal n1, Point G){//pt tia //phản xạ
   t.a = n1.xn;
   t.b = n1.yn;
   t.c = -(n1.xn*G.x + n1.yn*G.y);
}

double Distan(Point G){// khoảng cách từ điểm //thoát của tia laser đến cạnh đáy BC
   return abs(BC.a*G.x + BC.b*G.y + BC.c)/sqrt(BC.a*BC.a + BC.b*BC.b);
}

int main() {
    double L, l;
    int m = 0, j = 0;
    cout <<"Вводите значение L: ";
    cin >> L; cout << endl;
    cout <<"Вводите значение l: ";
    cin >> l; cout << endl;
    for(double beta = (PI/2)*1/9; beta <= (PI/2)*7/9; beta =+ PI/1800){
       for(double alpha = 0; alpha <= PI/2; alpha =+ PI/1800) {
          Prisma(L,l,beta,alpha);
          Equa(AB,A,B);
          Equa(BC,B,C);
          Equa(AC,A,C);
          Equa(EF,E,F);
          Equa(DF,D,F);
          Line t;
          t.a=5.0;
          t.b = t.c = 0.0;
          Pofinters(t, EF);
          double r = asin(sin(alpha)/1.5);
          Normal1((alpha - r), t);
          equaNorm(t, n1, G);
          PofInters(t, AC);
          double gamma = 0.0, teta = 0.0;
          if (Middle(A, C, G) == true){
             Angle(t, AC);
             m++;
          }
          while(abs(1.5*sin(gamma) - sin(PI/2 - beta)) > 0.001){
             if((G.x =! 0) && (G.y =! 0) && (gamma < asin(1/1.5))){
                teta = asin(1.5*sin(gamma));
             }
             Norml1(gamma*2, t);
             equaNorm(t, n1, G);
             PofInters(t,AB);
             if(Middle(A,B,G) == true){
                Angle(t,AB);
                m++;
             }
             else {
                PofInters(t,BC);
                if((Middle(B,D,G) == true) && (Middle(E,C,G) == true)){
                   Angle(t,BC);
                   m++;
                }
                else{
                   PofInters(t,AC);
                   if(Middle(A,C,G) == true){
                      Angle(t,AC);
                      m++;
                   }
                }
             }
          }
          if(abs(1.5*sin(gamma) == sin(PI/2 - beta)) < 0.001) j++;
       }
    }
    cout<<j;
    return 0;
}

Dùng tag đi bạn chứ code dài mà ko tag sao đọc nổi :smiley:

2 Likes

Hi Trần Đức HiếuTr_n_D_c_Hi_u.
Tất cả các hàm của bạn truyên theo tham trị nên gọi hàm không có tác dụng.
Nếu bạn không yêu cầu tối ưu thời gian chạy hay bắt buộc dùng C/C++ thì mình khuyên bạn nên dùng python.

1 Like

Mình không hiểu lắm, nếu hàm mình gọi như vậy giá trị sẽ gán vào biến đúng không ạ? Không có tác dụng nghĩa là sao ạ?

Hi Trần Đức HiếuTr_n_D_c_Hi_u.
Bạn có thể tìm đọc về biến tham chiếu tham trị con trỏ trong C++.
Viết hàm swap giá trị 2 biến để hiểu thêm về cách chuyền đối vào hàm.
Hãy thử python.

Cảm ơn bạn! Mình đang bắt đầu học Python.
Về vấn đề với bài mình viết trên thì có phải là do mình sử dụng tham trị trong hàm không trả về nên sau khi gọi hàm giá trị của các biến trong chương trình chính không thay đổi?

1 Like

Mình có đọc qua tài liệu và hiểu được bản chất lỗi sai. Nhưng sau khi khai báo theo tham chiếu thỉ chương trình vẫn chạy không đưa ra kết quả. Vậy có thể là có lỗi thuật toán ở vòng lặp khiến nó chạy không có kết thúc?

Hi Trần Đức HiếuTr_n_D_c_Hi_u.
Bạn up lai code coi. @_@!

Lâu nay mình bận quá. Xin lỗi bạn!
Code mình sửa lại như sau, nhưng mình không hiểu tại sao khi chạy nó không in tất cả giá trị thỏa mãn ra màn hình, ví dụ ở vòng lặp đầu tiên, với L = 150, l = 15, beta bắt đầu từ (PI/2)*2/9 thì không hiện bất cứ giá trị nào. Thử cho beta bắt đầu từ (PI/2)*4.3/9 thì có kết quả nhưng không đầy đủ. Mong bạn chỉ giúp mình!

#include
#include
#include
#define PI 3.14159
using namespace std;

struct Point{
double x = 0.0;
double y = 0.0;
} A, B, C, D, E, F, G, H;
struct Line{
double a = 0.0;
double b = 0.0;
double c = 0.0;
} AB, BC, AC, EF, DF, BD, EC, DE;
struct Normal{
double xn = 0.0;
double yn = 0.0;
} n, n1;

void Equa(Line& t, Point X, Point Y);
void EquaIn(Point H, Point G, Line& t, Line k, double& gamma);
void PofInters(Line t, Line k);
void Prisma(double L, double l, double beta, double alpha);
bool Middle (Point X, Point Y, Point G);
double Length(Point A, Point B);
bool Trung(Point G, Point H);
double Distan(Point G);
void Normal1(double Angle1, Line t);
void equaNorm(Line& t, Normal n1, Point G);
bool KiemTra(Line t, Line k, Point G);

int main(){
int r;
ofstream outfile;
outfile.open(“tranhieu1.txt”);
double L, l;
double gamma = 0.0;
int j =0;
bool ktra = false ;
cout <<"Aaiaeoa cia?aiea L: ";
cin >> L;
cout << endl;
cout <<"Aaiaeoa cia?aiea l: ";
cin >> l;
cout << endl;
int m= 0;
for (double beta = (PI/2)*2/9; beta < (PI/2)*6/9; beta += PI/180){
for(double alpha = 0; alpha <= (PI/2)*7/9; alpha += PI/180){
Prisma(L, l, beta, alpha);
Equa(AB, A, B);
Equa(BC, B, C);
Equa(AC, A, C);
Equa(EF, E, F);
Equa(DF, D, F);
Equa(BD, B, D);
Equa(EC, E, C);
Line t;
t.a = 1.0;
t.b = 0;
t.c = -5.0;
int m= 0;
PofInters(t, EF);
H = G;
Line k, q;
double r = asin(sin(alpha)/1.5);
double alpha1 = r - alpha;
Normal1(alpha1, t);
equaNorm(t, n1, G);
PofInters(t, AC);
if (Middle(A, C, G) == true){
k = AC;
q = t;
m++;
EquaIn(H, G, t, AC, gamma);
}

		while(KiemTra(q, k, G) == false || abs(asin(1.5*sin(gamma)) - (PI/2 - beta))> 0.16  || (gamma >= asin(1/1.5))|| (G.y == 0)) {
			H = G;				
			PofInters(t, AB); 
			if (Middle(A, B, G) == true && Trung(G, H) == false){
				k = AB;
				q = t;
				m++;
				EquaIn(H, G, t, AB, gamma);
			}
			else {
				PofInters(t, DF);
				Point G1 = G;
				PofInters(t, EF);
				if ((Middle(F, D, G1) == true && Trung(G,H) == false) || (Middle(E, F, G) == true && Trung(G, H) == false )){
					ktra = true;				
				}
				else{
				PofInters(t, BC);	
				if(Middle(B, C, G) == true && Trung(G, H) == false){
					k = BC;
					q = t;
					m++;
					EquaIn(H, G, t, BC, gamma);
					}
				else{
					PofInters(t, AC);
					if(Middle(A, C, G) == true && Trung(G, H) == false){
						k = AC;
						q = t;
						m++;
						EquaIn(H, G, t, AC, gamma);
						}
					}
				}
			
		}
			
			if (ktra == true) break;
			
		}
			if (ktra == true) continue;
		cout << "Goc: " << (abs(asin(1.5*sin(gamma)) - (PI/2 - beta))/PI)*180 << endl;

// if (abs(asin(1.5*sin(gamma)) - (PI/2 - beta) <= 0.16)) {
++j;
outfile << G.x <<" "<< G.y << endl;
outfile << "m: " << m << endl;
outfile << “D: " << Distan(G) << endl;
outfile << “H: " << A.y << endl;
outfile << “beta: " << (beta/PI)*180;
outfile << " alpha: " << (alpha/PI)*180 << endl;
outfile <<”----------------------------” << endl;
cout << G.x <<” “<< G.y << endl;
cout << H.x <<” "<< H.y << endl;
cout <<"m: " << m << endl;
cout << "D: " << Distan(G) << endl;
cout << "H: " << A.y << endl;
cout << " beta: " << (beta/PI)*180;
cout << " alpha: " << (alpha/PI)180 << endl;
cout <<"-------------------------------" << endl;
// }
}
}
cout << j;
outfile << j;
return 0;
}
void Prisma(double L, double l, double beta, double alpha){ // xac dinh toa do cac diem chinh cua prisma
A.x = 0.0;
A.y = L
tan(beta);
B.x = -L;
B.y = 0.0;
C.x = L;
C.y = 0.0;

E.x = l;
E.y = 0.0;
D.x = -l;
D.y = 0;
F.x = 0.0;
F.y = l*tan(alpha);
return;

}

void Equa(Line& t, Point X, Point Y){ //Viet phuong trinh cua mot duong thang khi biet hai diem
n.xn = -(Y.y - X.y);
n.yn = Y.x - X.x;
t.a = n.xn;
t.b = n.yn;
t.c = -(n.xnX.x + n.ynX.y);
return;
}
void EquaIn(Point X, Point Y, Line& t, Line k, double& gamma){
Point H0, H1;
H0.x = (k.ak.aX.x + k.bk.bY.x + k.ak.b(X.y - Y.y))/(k.ak.a + k.bk.b);
H0.y = (k.aX.x + k.bX.y)/k.b - H0.xk.a/k.b;
H1.x = 2
H0.x - X.x;
H1.y = 2*H0.y - X.y;
gamma = asin(Length(H1, H0)/Length(H1, Y));
Equa(t, H1, G);
return;
}

void PofInters(Line t, Line k){ //Tim toa do diem giao giua hai duong thang
double d, dx, dy;
d = t.ak.b - k.at.b;
dx = -t.ck.b + k.ct.b;
dy = -t.ak.c + k.at.c;
G.x = dx/d;
G.y = dy/d;
return;
}

bool Middle (Point X, Point Y, Point G){ // Xac dinh diem giao nam o giua doan thang gioi han boi hai diem hay khong
if (abs(Length(X, G)+Length(Y, G) - Length(X, Y)) < 0.00001)
return true;
}

double Length(Point A, Point B){ //Tinh do dai giua doan thang gioi han boi hai diem A, B
return sqrt(pow(A.x-B.x,2)+pow(A.y-B.y,2));
}

bool Trung(Point G, Point H){
if (abs( H.x - G.x) < 0.00001 && abs(H.y - G.y) < 0.00001)
return true;
}

double Distan(Point G){
return abs(BC.aG.x +BC.bG.y + BC.c)/sqrt(BC.aBC.a + BC.bBC.b);
}

void Normal1(double Angle1, Line t){ //Tim phap tuyen cua duong thang phan xa
n1.xn = t.acos(Angle1) - t.bsin(Angle1);
n1.yn = t.asin(Angle1) + t.bcos(Angle1);
return;
}

void equaNorm(Line& t, Normal n1, Point G){ //Viet phuong trinh cua mot duong thang khi biet mot diem va phap tuyen
t.a = n1.xn;
t.b = n1.yn;
t.c = -(n1.xnG.x + n1.ynG.y);
return;
}

bool KiemTra(Line t, Line k, Point G){
if (/((-t.c/t.b) < G.y) &&/ ((-t.c/t.b) > (k.aG.y - k.bG.x)/k.a))
return true;
}

83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?