Игла Буффона в MATLAB - PullRequest
       23

Игла Буффона в MATLAB

2 голосов
/ 06 марта 2019

В настоящее время я работаю над проектом для моего класса химической инженерии, который называется игла Буффона.Цель этого проекта - использовать MATLAB для получения оценки числа пи, а затем создать «карикатуру», которая будет отображать иглы на графике 10x10 с линиями через каждые 1 единицу, с иглами, пересекающими линию одного цвета, и игламине переходя, будучи другим.Я нашел оценку числа пи и создал график, но мои линии имеют длину не одну единицу, как это должно быть, а все иглы разной длины.если бы кто-нибудь мог помочь мне с этой проблемой, это было бы очень ценно.мои два сценария ниже

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');

Это ниже моя функция 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];

1 Ответ

2 голосов
/ 06 марта 2019

Вы сделали ошибку индексации. Ваша функция возвращает endpoints:

endpoints = [ r2(1)-S, r2(2)+V; ...
              r2(1)+S, r2(2)-V ];

упрощенный,

endpoints = [ start_x, start_y; ...
              end_x,   end_y   ];

Они собраны в трехмерную матрицу, которую вы затем строите:

p2 = plot( endpointsHitList(:,1,i), endpointsHitList(1,:,i), ['-','b'] );
%          ^ x-coordinates          ^ y-coordinates

Таким образом, здесь вы строите линию с координатами x [start_x,end_x] и координатами y [start_x,start_y]! Этот последний должен был быть [start_y,end_y].

Это должно было быть:

p2 = plot( endpointsHitList(:,1,i), endpointsHitList(:,2,i), ['-','b'] );
%                                                    ^^^ get second column

Та же ошибка происходит при построении endpointsNotHitList.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...