evl := t -> convert(evalm(t), list): arrow3d := proc(base::{list,vector},vect::{list,vector,`+`}) local b1,v1,stem,r,hbase,hpoint,v2,v3,head,opts, scopts; b1 := evalf(evl(base)); v1 := evalf(evl(vect)); if not type(v1,list) or nops(b1) <> 3 or nops(v1) <> 3 then ERROR(`points need three dimensions`) fi; if not (type(b1,[realcons,realcons,realcons]) and type(v1,[realcons,realcons,realcons])) then ERROR(`coordinates must evaluate to real constants`) fi; opts := args[3 .. nargs]; scopts := indets({opts}, identical('scalefactor')=realcons); if scopts <> {} then v1:= evalf(op(2,scopts[1])) * v1; opts:= op({opts} minus scopts); fi; hbase := evl(b1+.8*v1); hpoint := evl(b1+v1); if not has({opts},{color,colour}) then opts := opts,colour = red fi; if not has({opts},thickness) then opts:= opts, thickness=3 fi; stem := plots[spacecurve]([b1,hbase],opts); if v1 = [0,0,0] then RETURN(stem) fi; r := sqrt(linalg[norm](v1,2)); v2 := evl(linalg[crossprod]([1,0,0],v1)); if linalg[dotprod](v2,v2) < .01*linalg[dotprod](v1,v1) then v2 := evl(linalg[crossprod]([0,1,0],v1)) fi; v2 := evl(.05*r*v2/linalg[norm](v2,2)); v3 := linalg[crossprod](v1,v2); v3 := evl(.05*r*v3/linalg[norm](v3,2)); head := plots[polygonplot3d]([hpoint,evl(hbase+v2), evl(hbase+v3), evl(hbase-v2), evl(hbase-v3), evl(hbase+v2)] ,style = patchnogrid,opts); plots[display]({stem,head}) end;