PDA

View Full Version : Bài toán kt cắt nhau đoạn thẳng và tia vài vấn đề với fp



Mr.WhiteHack
16-10-2009, 18:17
Hôm nay tui làm bài này cho một đứa học 11(tui học 12) kt xem đoạn thẳng và tia có cắt nhau không, code đã đời chạy trên freepascal thì toàn báo sai nhưng chuyển qua borland pascal lại chạy đúng, mở cửa sổ watches lên kt thì mới thấy sao tự nhiên free tính 4*3,399999999999999999999999....=16,3(chẵn khó tin) >"< làm cho hàm kiểm tra điểm thuộc đường thẳng(thuocdt) bị sai
Ai biết vấn đề này không thì nói cho mình hiểu với, và ai có cách tối ưu hóa code thì nói lun thể ^^
Code đây:


program test;
const inputfile= 'data.inp';
outputfile= 'data.out';
type int= integer;
rea= real;
boo= boolean;
txt= text;
poi= record
x, y: rea;
end;
lin= record
a, b: poi;
a1, b1, c1: rea;
end;
var t1, t2: lin;
o: poi;

procedure doctep;
var fi: txt;
begin
assign(fi, inputfile); reset(fi);
readln(fi, t1.a.x, t1.a.y, t1.b.x, t1.b.y);
readln(fi, t2.a.x, t2.a.y, t2.b.x, t2.b.y);
close(fi);
end;

function max(a, b: real): real;
begin
if a>= b then max:= a
else max:= b;
end;

function min(a, b: real): real;
begin
if a<= b then min:= a
else min:= b;
end;

procedure heso(var t: lin);
begin
t.a1:= t.a.y- t.b.y;
t.b1:= t.b.x- t.a.x;
t.c1:= t.a.x*t.b.y-t.b.x*t.a.y;
end;

function thuocdt(m: poi; t: lin): boo;
begin
if t.a1*m.x+ t.b1*m.y+ t.c1=0 then
thuocdt:= true
else thuocdt:= false;
end;

function thuocdoan(m: poi; t: lin): boo;
begin
if thuocdt(m, t) and (m.x>= min(t.a.x, t.b.x)) and
(m.x<= max(t.a.x, t.b.x)) then thuocdoan:= true
else thuocdoan:= false;
end;

function thuoctia(m: poi; t: lin): boo;
begin
if thuocdt(m, t) and ((m.x- t.a.x)*(t.b.x- t.a.x)>= 0)
and ((m.y- t.a.y)*(t.b.y- t.a.x)>= 0) then thuoctia:= true
else thuoctia:= false;
end;

function vttd(var o: poi; t1, t2: lin): int;
var d, dx, dy: rea;
begin
heso(t1); heso(t2);
d:= t1.a1*t2.b1- t2.a1*t1.b1;
dx:= t1.b1*t2.c1- t2.b1*t1.c1;
dy:= t1.c1*t2.a1- t2.c1*t1.a1;
if d= 0 then
begin
if (dx<> 0) or (dy<> 0) then vttd:= 0;
if (dx= 0) and (dy= 0) then vttd:= 2;
end
else
begin
o.x:= dx/d;
o.y:= dy/d;
if not(thuocdoan(o, t1)) and thuocdoan(o, t2) then vttd:= 3
else vttd:= 1;
end;
end;

procedure xuli;
var fo: txt;
begin
assign(fo, outputfile); rewrite(fo);
if vttd(o, t1, t2)= 1 then
begin
if thuocdoan(o, t1) and thuoctia(o, t2) then
write(fo, 'Doan thang va tia cat nhau')
else write(fo, 'Doan thang va tia ko cat nhau');
end
else write(fo, 'Doan thang va tia ko cat nhau');
close(fo);
end;

BEGIN
doctep;
xuli;
END.

test


3 5 4 1
1 1 4 4