展开/展开截头圆锥

时间:2015-02-13 07:58:36

标签: matlab math

我想要打开一个锥形的柱子(截锥形)。我怎么能这样做。

下半径= 1.8506米(红色图片) 上半径= 1.6849米(绿色图)

我支柱的坐标

中心: 底部圆圈:xyz:0,0,0 顶部圆圈:xyz:0,0,24.6 请参见附图。

Cone apex:0,0,275(我刚刚算过) 角度(一半)enter image description here:0.38 投影半径= 1.84(我应该给出什么)enter image description here

圆柱的坐标,我可以得到

r=sqrt(x^2+y^2)
theta=atan(y,x)
z=z

如何在飞机上投影。

2 个答案:

答案 0 :(得分:4)

fileexchange上可能有很多代码,或者网上有高度优化的解决方案(例如用于纹理投影),无论如何,这是我的解决方案:

我假设支柱数据是一个大小为[tcount x zcount]的矩阵,其中tcount是沿角度轴的扫描位置数,zcount是沿高度轴的扫描位置数。

所以这是代码:

%
% PURPOSE:
%
%   Project cone data to plane data
%
% INPUT:
%
%   thetaValues: Angular-scan values (in radians !!)
%   zValues: z-scan values (whathever unit)
%   coneData: Scanned data of size thetaCount-by-zCount
%   zminRadius: Radius at zmin position (same unit as zValues)
%   zmaxRadius: Radius at zmax position (same unit as zValues)
%   xvalues: Values to have along x-axis (by default biggestRadius * thetaValues centered around theta = 0)
%
% OUTPUT:
%
%   xvalues: Positions along x-axis (same unit as zValues)
%   zvalues: Positions along z-axis (same values/unit as input)
%   planeData: Plane data of size xcount-by-zcount 
%
function [xvalues, zValues, planeData] = Cone2Plane(thetaValues, zValues, coneData, zminRadius, zmaxRadius, xvalues)
%[
    % Default arguments
    if (nargin < 6), xvalues = []; end

    % Init
    zmin = min(zValues);
    zmax = max(zValues);    
    smallestRadius = min(zminRadius, zmaxRadius);
    biggestRadius = max(zminRadius, zmaxRadius);

    % Ensure thetaValues range in -pi;+pi;
    thetaValues = mod(thetaValues + pi, 2*pi) - pi;
    [thetaValues, si] = sort(thetaValues);
    coneData = coneData(si, :);

    % Intercept theorem (Thales)
    %
    %      A-------+-------\
    %     /|       |        \
    %    / |       |         \
    %   D--E-------+----------\
    %  /   |       |           \
    % B----C-------+------------\
    BC = biggestRadius - smallestRadius; 
    AE = zmax - zValues(:);
    AC = (zmax - zmin);
    DE = (BC * AE) / AC;
    radiuses = smallestRadius + DE;

    % Projection
    if (isempty(xvalues)), xvalues = biggestRadius * thetaValues; end
    xcount = length(xvalues);
    zcount = length(zValues);
    planeData = zeros(xcount, zcount);        
    for zi = 1:zcount,
        localX = radiuses(zi) * thetaValues;
        localValues = coneData(:, zi);
        planeData(:, zi) = interp1(localX, localValues, xvalues, 'linear', 0);
    end
%]
end
  • 我不会为每个z位置输入Thales theorem计算radiuses的详细信息。

  • 我将角位置重新排列在[-180°; + 180°],以便具有对称的x位置(即xLocal = radiusLocal * angularPos)。

  • 棘手的部分是将xLocal重新插入某些xGlobal位置(我假设为xLocal = biggestRadius * angularPos,但您当然可以提供自己的值作为Cone2Plane例程的论证。

这里有一些测试用例:

function [] = TestCone2Plane()
%[
    % Scanning info
    zminRadius = 1.8506;
    zmaxRadius = 1.6849;
    zValues = linspace(0.0, 24.6, 100); 
    thetaValues = linspace(0, 359, 360) * pi / 180;

    % Build dummy cone data
    tcount = length(thetaValues);
    zcount = length(zValues);    
    coneData = rand(tcount, zcount);

    % Convert to plane data
    xvalues = []; % Means automatic x-positions
    [xvalues, zValues, planeData] = Cone2Plane(thetaValues, zValues, coneData, zminRadius, zmaxRadius, xvalues);

    % Display
    [X, Z] = ndgrid(xvalues, zValues);
    pcolor(X, Z, planeData);  
    shading flat;
%]
end

修改

目前还不清楚你有什么确切的输入数据,但如果柱子是一组(x,y,z,强度)点,你可以将数据集减少到coneData,如下所示:

thetas = atan2(y(:), x(:));
thetaValues = unique(thetas); tcount = length(thetaValues);
zValues = unique(z); zcount = length(zValues);    
coneData = zeros(tcount, zcount);
for ti = 1:tcount,
  logict = (thetas == thetaValues(ti));
  for zi = 1:zcount,
     logicz = (z == zValues(zi));
     coneData(ti, zi) = mean(intensity(logict & logicz));
  end
end

注意:在实际操作中,您可能需要使用一些unique with tolerance(+ logic = abs(val-pos) < tol)来进一步减少数据,同时考虑扫描位置的噪声。

答案 1 :(得分:2)

  1. 所以你想得到(x,y,z)=f(u,v)

    • u=<0.0,1.0> ...角度坐标
    • v=<0.0,1.0> ...身高坐标让v = 0.0为底部
    • 你沿着周边有|sin|波的24个周期
    • 幅度:a0位于底部,a1位于顶部
    • 支柱底部为r0,顶部为r1
    • 支柱有高度h
    • pillar
  2. 第一个基本圆柱体

    x=r*cos(2.0*M_PI*u)
    y=r*sin(2.0*M_PI*u)
    z=h*v
    
  3. now cone

    r=r0+(r1-r0)*v
    x=r*cos(2.0*M_PI*u)
    y=r*sin(2.0*M_PI*u)
    z=h*v
    
    • 添加半径的线性插值
  4. 现在是|sin| wave

    r=r0+(r1-r0)*v
    a=a0+(a1-a0)*v
    r-=a*fabs(sin(2.0*M_PI*12.0*u))
    x=r*cos(2.0*M_PI*u)
    y=r*sin(2.0*M_PI*u)
    z=h*v
    
    • 添加|sin|波幅度的线性插值
    • 然后将|sin| wave应用于radius
  5. 现在u,v坐标是飞机内的坐标(例如纹理)