arrays3doctavehyperbolic-function

How can I wrap data points around an object in Octave


I'm trying to wrap a signal around a hyperbolic cone (the cone looks like this http://www.sectioaurea.com/sectioaurea/the_golden_angle.htm) I've found away to wrap data around a cylinder.

See cylinder with wrapped data around it below.

%% // Generate sample data
x = linspace(0,10*pi) ;
y2 = cos(x) ;
y1 = 10*cos(x/10) ;
y = y1+y2 ; y = y-min(y) ;
figure, 
plot(x,y,'-o') ;

%% // Basic cylinder (just for background)
[Xc,Yc,Zc] = cylinder(1*ones(1,50),50);
Zc = Zc * max(y) ;
surf(Xc,Yc,Zc) ;
hold on 

%% // Fold the points around the cylinder
Number_of_turn = 2 ;
xrange = [min(x),max(x)] ;
xspan = xrange(2)-xrange(1) ;
xc = x / xspan * 2*pi * Number_of_turn ;

Xp = cos(xc) ;
Zp = y ;
Yp = sin(xc) ;

plot3(Xp,Yp,Zp,'-ok') ;

Image

But I'm not sure how to get it to wrap data around a hyperbolic cone (the cone looks like this http://www.sectioaurea.com/sectioaurea/the_golden_angle.htm)

I'm using Octave 4.2.2 in Ubuntu 18.04 64bit


Solution

  • Here's an example

    % plot surface
    [X,Y] = ndgrid( -0.1:0.001:0.1, -0.1:0.001:0.1 );
    Z = 1 ./ sqrt(X.^2 + Y.^2);   % The height at each X,Y grid point is
                                  % the inverse of its norm
    
    surf(X,Y,Z, 'edgecolor', 'none');
    colormap cool
    camlight
    
    %plot spiral
    Theta = [1:0.1:500];
    Z = Theta;    % height increases same as angle
    Norm = 1 ./ Z;   % the definition of the hyperbolic cone
    X = cos(Theta) .* Norm;
    Y = sin(Theta) .* Norm;
    
    hold on
    plot3(X,Y,Z, 'r', 'linewidth', 1.5 )
    hold off
    
    axis([-0.1, 0.1, -0.1, 0.1, 0, 500])
    

    UPDATE

    Here is another example, wrapping a specific function; hopefully it demonstrates what you had in mind. Note I had to offset the height a little bit, otherwise a hyperbolic cone at close-to-zero heights is very close to infinity, which is difficult to graph.

    %% Generate a hyperbolic cone surface, and 'wrap' an arbitrary 1D function to it, by
    %% treating the function's x-coordinate as an angle, and for each such
    %% angle, projecting the corresponding height onto the surface of the cone at the same
    %% height.
    
    %%%%%%%%%%%%%%%%%%%%%%
    % Generate sample data
    %%%%%%%%%%%%%%%%%%%%%%
    
       x = linspace( 0, 10 * pi );   % Generate 100 points (default) from 0 to 10π
       h = cos(x) + 10 * cos( x / 10 );   h = h - min(h);
       h = 30 * h + 30;   % make it a bit taller, and small offset so that low values
                          % don't end up near infinity when mapped onto the hyperbolic
                          % cone surface
    
    %%%%%%%%%%%%%%%%%%
    % Generate Surface
    %%%%%%%%%%%%%%%%%%
    
     % Generate a suitable XY grid
       [GridX, GridY] = ndgrid( -0.1:0.0005:0.1, -0.1:0.0005:0.1 );
    
     % For each point on the grid, calculate a distance Δ from the (0,0) origin.
       Delta = sqrt( GridX .^ 2  +  GridY .^ 2 );
    
     % According to the definition of the hyperbolic cone, the height Z at each gridpoint
     % is equal to 1 over Δ
       Z = 1 ./ Delta;
    
     % Plot the resulting surface with height Z at each gridpoint X,Y
       surf( GridX, GridY, Z, 'edgecolor', 'none' );
    
     % Give the surface a nicer appearance
       colormap( 'ocean' ); caxis([0, 25]); camlight;
    
    
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    % Wrap data around generated surface
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    
       NumberOfTurns = 2;
       XRange  = [ min( x ), max( x ) ];
       XSpan   = XRange(2) - XRange(1);
       XOffset = XRange(1)
    
     % Convert x inputs to angles Theta ('xc' in previous example code)
       Theta  = (NumberOfTurns * 2 * pi / XSpan) * (x - XOffset);
    
      % Since, according to the hyperbolic cone equation, 'H = 1 / Δ' (where H denotes
      % Height, and Δ denotes distance from the [0,0] origin), it follows that for a
      % given H, we can find the corresponding Δ as Δ = 1 / H. Therefore, for each
      % [θ, h] pair, we can find a distance Δ, such that the cartesian point
      % [ Δcos(θ), Δsin(θ), h ] sits on the cone. We use this fact to 'wrap' the
      % trajectory function around the cone.
    
      Delta = 1 ./ h;   % overwriting old Delta definition for notational convenience.
    
      WrappedX = Delta .* cos( Theta );
      WrappedY = Delta .* sin( Theta );
      WrappedZ = h;
    
     % Plot the wrapped datapoints over the previous surface graph
       hold on
       plot3( WrappedX, WrappedY, WrappedZ, '-or', 'linewidth', 1.5, 'markersize', 4, 'markerfacecolor', [0.5,0,0], 'markeredgecolor', [0.25,0,0]);
       hold off
    
     % Set appropriate axis limits to visualise relevant range
       axis([-0.1, 0.1, -0.1, 0.1, 0, 1000]);
       set(gca, 'color', [0.5,0.5,0.5]);