File: ef230-2023-08/www/examples/vector_drawing.m Download
%! Example of a generalized function for drawing a vector
%! Uses a structure for specifying parameters
% University of Tennessee : EF 230 Fall, 2009 : Will Schleter

function main
clear all; close all; clc;

figure(1);
hold on;
axis equal;
axis([0 10 0 10]);
title('Vector Drawing Demo');

% simple example
v=init_vector();
v.x=[1,2];
v.y=[1,9];
draw_vector(v);

% segmented vector
v=init_vector();
v.x=[4 5 6 7];
v.y=[6 9 7 8];
v.color='b';
v.label='segmented';
draw_vector(v);

% a curved vector
v=init_vector();
t=linspace(0,pi/4,20);
v.x=-1.25+4*cos(t);
v.y=1+4*sin(t);
v.label='Curved';
v.label_end=1;
v.arrow_end=3;
draw_vector(v);

% several vectors to test arrow drawing routine
v=init_vector();
v.color='g';
v.end=2;
for t=0:30:330;
    v.x=[6 6+2*cosd(t)];
    v.y=[3 3+2*sind(t)];
    v.arrow_size=.5*t/360;
    v.label=sprintf('%.0f',t);
    draw_vector(v);
end


function vs=init_vector()
% create a structure with default values for a vector
vs.x=[];            % x values for the vector
vs.y=[];            % y values for the vector
vs.arrow_size=.5;   % length of the arrowhead
vs.arrow_aspect=.6; % arrow thick/size ratio
vs.color='k';       % color
vs.label='';        % text label
vs.label_end=2;     % 1 start, 2 end
vs.arrow_end=2;     % 1 start, 2 end, 3 both
return

function draw_vector(vs)
% see the init_vector function for a description of the vs structure

if length(vs.x)<2 | length(vs.y)<2 | size(vs.x)~=size(vs.y)
    error('Invalid x,y values in draw_vector function');
end;

% draw the vector body
line(vs.x,vs.y,'color',vs.color);

% draw the vector arrows
if vs.arrow_end==1 || vs.arrow_end==3, draw_arrow(vs,1); end;
if vs.arrow_end==2 || vs.arrow_end==3, draw_arrow(vs,length(vs.x)); end;

% draw the vector label
if length(vs.label)>0
    i=1;
    if vs.label_end==2, i=length(vs.x); end;
    text(vs.x(i),vs.y(i),vs.label);
end
return;

function draw_arrow(vs,ie)
% draws an arrow on one end of a vector
% see init_vector for a description of vs
% ie is the index into the x and y lists for the top of the arrow

% dx,dy will be a unit vector starting at the specified end
% and pointing away from the arrow tip along the vector body
dir=1; if ie>1, dir=-1;, end; % direction of the arrow
dx=vs.x(ie+dir)-vs.x(ie);
dy=vs.y(ie+dir)-vs.y(ie);
dd=sqrt(dx.*dx+dy.*dy);
dx=dx/dd;
dy=dy/dd;

% compute points for the corners of the arrow triangle
w=vs.arrow_size;
t=w*vs.arrow_aspect/2;
ax(1)=vs.x(ie);
ay(1)=vs.y(ie);
ax(2)=ax(1)+dx*w+dy*t;
ay(2)=ay(1)+dy*w-dx*t;
ax(3)=ax(1)+dx*w*.9;
ay(3)=ay(1)+dy*w*.9;
ax(4)=ax(1)+dx*w-dy*t;
ay(4)=ay(1)+dy*w+dx*t;

% draw the arrow
patch(ax,ay,vs.color,'edgecolor',vs.color);
return