Search code examples
matlablight

Surface intensity for a moving light source


I’m trying to write a simulation that will move a light source over the surface of an object, on each step measure the intensity of reflected light back to the light source.

Then plot the intensity from each point of the surface. With each step adding to the first plot. Thus building up a picture of the surface topography.

It is a bit messy if you can suggest a way to tidy up.

x = -10:0.25:10;
y = -10:0.25:10;
xlength=length(x);
ylength=length(y);
ymin=min(y);
ymax=max(y);
xmin=min(x);
xmax=max(x);
D=zeros(xlength);


[X,Y] = meshgrid(x,y);
z = 10-(X.^2)-(Y.^2)+5*sin(X);
rnd=rand(xlength);

c=randi(xlength);
d=randi(xlength); 
s=1;
t=0;


for i=1:ylength
    t=t+1;
    for j=1:xlength
        if s==c
            if t==d 
                D(s,t)=z(s,t);
            elseif t==d+1
                D(s,t)=z(s,t);
            elseif t==d+2
                D(s,t)=z(s,t);
            elseif t==d+3
                D(s,t)=z(s,t);
            elseif t==d+4
                D(s,t)=z(s,t);
            elseif t==d+5
                D(s,t)=z(s,t);
            else
                D(s,t)=0;
            end
        elseif s==c+1
            if t==d
                D(s,t)=z(s,t);
            elseif t==d+1
                D(s,t)=z(s,t);
            elseif t==d+2
                D(s,t)=z(s,t);
            elseif t==d+3
                D(s,t)=z(s,t);
            elseif t==d+4
                D(s,t)=z(s,t);
            elseif t==d+5
                D(s,t)=z(s,t);
            else
                D(s,t)=0;
            end
        elseif s==c+2
            if t==d
                D(s,t)=z(s,t);
            elseif t==d+1
                D(s,t)=z(s,t);
            elseif t==d+2
                D(s,t)=z(s,t);
            elseif t==d+3
                D(s,t)=z(s,t);
            elseif t==d+4
                D(s,t)=z(s,t);
            elseif t==d+5
                D(s,t)=z(s,t);
            else
                D(s,t)=0;
            end
        elseif s==c+3
            if t==d
                D(s,t)=z(s,t);
            elseif t==d+1
                D(s,t)=z(s,t);
            elseif t==d+2
                D(s,t)=z(s,t);
            elseif t==d+3
                D(s,t)=z(s,t);
            elseif t==d+4
                D(s,t)=z(s,t);
            elseif t==d+5
                D(s,t)=z(s,t);
            else
                D(s,t)=0;
            end
        elseif s==(c+4)
            if t==d
                D(s,t)=z(s,t);
            elseif t==d+1
                D(s,t)=z(s,t);
            elseif t==d+2
                D(s,t)=z(s,t);
            elseif t==d+3
                D(s,t)=z(s,t);
            elseif t==d+4
                D(s,t)=z(s,t);
            elseif t==d+5
                D(s,t)=z(s,t);
             else
                D(s,t)=0;
            end
        else
            D(s,t)=0;
        end
        s=s+1;
    end
    s=1;
end       

z1=z -(D/20);
z2=z1-z;

s=0;

figure
surf(X,Y,z)
axis([xmin xmax ymin ymax])

xlabel('X')
ylabel('Y')
zlabel('Z')
    for i=-10:2.5:10
        hold on

        light('position',[i,0,50])
        surf(X,Y,z,'EdgeColor', 'none')
        axis([xmin xmax ymin ymax])

        drawnow

        pause (1)
        delete(findall(gcf,'Type','light'))

        hold off
    end

This is as far as I have got .


Solution

  • A code that does exactly what yours does: (thanks @Hoki for the help in simplifying the code even more)

    clear;clc
    x = -10:0.25:10;
    y = -10:0.25:10;
    xlength=length(x);
    ylength=length(y);
    ymin=min(y);
    ymax=max(y);
    xmin=min(x);
    xmax=max(x);
    [X,Y] = meshgrid(x,y);
    z = 10-(X.^2)-(Y.^2)+5*sin(X);
    
    %% plot!
    
    figure
    surf(X,Y,z,'EdgeColor', 'none','lineStyle','none') % taken out the linestyle because it looks cooler
    axis([xmin xmax ymin ymax])
    
    xlabel('X')
    ylabel('Y')
    zlabel('Z')
    % Added repetitions and decreased step size, plus making it go forward and backward.
    repetitions=4;
    for jj=1:repetitions
    
       hl = light('position',[-10,0,50]) ;     %// create the light source
       for i=-10:2.5:10
           set(hl,'position',[i,0,50]) ;       %// set the new light position
           drawnow                             %// flush graphic pipeline
           pause (0.1)                         %// let human user see something
       end
       delete(hl)   %// delete the light source
    end
    

    This gives the following gif:

    http://i.imgur.com/42ffYll.gifv

    About the rest part of the code....

    Remember that

    if t==d
       D(s,t)=z(s,t);
    elseif t==d+1
       D(s,t)=z(s,t);
    elseif t==d+2
       D(s,t)=z(s,t);
    elseif t==d+3
       D(s,t)=z(s,t);
    elseif t==d+4
       D(s,t)=z(s,t);
    elseif t==d+5
       D(s,t)=z(s,t);
    else
       D(s,t)=0;
    end
    

    is literally the same as:

    if (t>=d && t<=d+5)
       D(s,t)=z(s,t);
    else
        D(s,t)=0;
    end
    

    This should help you reduce the code. There is also vectorization.

    you can do

    D(s,(t>=d && t<=d+5))=z(s,(t>=d && t<=d+5)));
    

    for all values of s... etc etc. Hope this gets you going ;)