I am currently working on a project for my Chemical Engineering class called Buffon's needle. The purpose of this project is to use MATLAB to get an estimate for pi and then to make a "cartoon" which will show the needles on a 10x10 graph with lines every 1 unit apart, with needles crossing the line being one color, and needles not crossing being another. I have found the pi estimate and i have created the graph, but my lines are not the one unit in length like they should be, instead the needles are all different lengths. if anyone could help me with this problem it would be much appreciated. my two scripts are below
clear all;
close all;
clc;
format compact
% Script to illustrate the estimation of pi value by using Buffon's needle
% experiment
% set number of separate experiments
nExperiments = 1000;
% set number of separate trials
nTrials = 3;
% total number of dropped needles is directly based on number of trials and
% number of experiments
ndropped=nTrials.*nExperiments;
% spacing between the parallel lines
spacing = 1;
% length of the needle
L = spacing;
% the lower bound of x coordinate.
a = 10;
totalhits = 0;
for i = 1:nTrials
% keeps track of the number of hits
hits = 0;
% keeps track of the number of times the needle doesn't hit the
% any of the lines
nothits = 0;
for j = 1:nExperiments
[outcome,endpoints,angle] = needle_drop(spacing,L);
if outcome
hits = hits + 1;
endpointsHitList(:,:,hits) = endpoints;
else
nothits = nothits + 1;
endpointsNotHitList(:,:,nothits) = endpoints;
end
angleList(j) = angle;
end
scatter(1:nExperiments,angleList);
xlabel('Experiments');
ylabel('Angles');
piestimate(i) = (2*L/spacing)/(hits/nExperiments);
end
fprintf('The average value of pi is %f plus or minus %f after %d trials of %d experiments with %d total number of dropped needle.\n',mean(piestimate),std(piestimate),nTrials,nExperiments,ndropped);
figure
hold on
% plot the vertical separations
for i = 0:spacing:a
p1 = plot([i,i],[0 11],'k','LineWidth',2);
end
% plot the needles that hit the vertical separation
for i = 1:hits
p2 = plot(endpointsHitList(:,1,i),endpointsHitList(1,:,i),['-','b']);
end
% plot the needles that don't hit the vertical separation
for i = 1:nothits
p3 = plot(endpointsNotHitList(:,1,i),endpointsNotHitList(1,:,i),['-','r']);
end
axis([-2,12 -2 12]);
legend([p1 p2 p3],'Vertical Separations','Hits','Not Hits')
title('Buffon Needle Experiment');
xlabel('x-axis');
ylabel('y-axis');
figure
histogram(piestimate)
title('Histogram of pi estimate');
This below is my function needle_drop
:
function [outcome,endpoints,theta] = needle_drop(spacing,L)
% spacing = spacing between the parallel lines spacing
% L = length of the needle
% spacing = 1;
% % In the special case where the length of the needle is equal to the grid spacing
% % between the parallel lines
% L = spacing;
% a is the lower bound of x coordinate. b is the upper bound.
% the needle position will be randomly between 0 and 10.
a = 0;
b = 10;
% generate random number r1 in [0,1]
r1 = rand;
% sample a value of the angle uniformly distributed over the interval
% from zero to ninety degrees
theta = (pi/2)*r1;
% the projection of half the length of the needle horizontally: S
S = (L/2)*cos(theta);
% Another random number r2 is generated
% this corresponds to x,y coordinate
r2 = a + (b-a).*rand(1,2);
% we need to take care of the offset.
% if the x coordinate is between 0 and d then offset is 0 if xcord is
% between d and 2d then offset is d and likewise for other values.
offset = floor(r2(1));
% The sampled position T of the center of the needle is next compared to the
% sampled projection of half the length of the needle
if r2(1)-S <=0+offset || r2(1)+S >=spacing+offset
outcome = 1;
else
outcome = 0;
end
% the projection of half the length of the needle vertically: V
V = L/2*sin(theta);
endpoints = [r2(1)-S,r2(2)+V;r2(1)+S,r2(2)-V];
You made an indexing mistake. Your function returns
endpoints
:Simplified,
These are collected in a 3D matrix, which you then plot:
Thus, here you are plotting a line with x-coordinates
[start_x,end_x]
, and y-coordinates[start_x,start_y]
! This latter should have been[start_y,end_y]
.This should have been:
The same mistake happens when plotting
endpointsNotHitList
.