2016-03-21 90 views
1

关于附加图像,我需要一个计算算法将轴A向下移动n英寸,而轴B从左向右移动m英寸,以便组件圆D跟随抛物线的曲线;圆D不总是10英寸,可以更小。我不是数学专业,所以这对我来说有点复杂。我知道我在轴A上有一个弧长,它必须被计算出来(我不知道该怎么做),然后我在轴B上也有一个弧长,并且弧正在参照位置轴A,与圆D的直径相关的该弧长将决定抛物线上圆D和抛物线之间的交点的位置。为了跟随抛物线的曲线从左到右,反之亦然 - 我需要一个公式来跟随抛物线。考虑D改变大小。有人可以提供一些如何做到这一点的答案;一个带有一些解释性信息的好公式 - 至少有足够的细节,我可以在这些部分和位上进行搜索,以了解要做什么。使用2轴运动计算抛物线路径的算法

2 Axis With Circle to follow Path of Parabola

I have looked and found some information that may be helpful to me but does not answer my question at all: https://stackoverflow.com/questions/4039039/fastest-way-to-fit-a-parabola-to-set-of-points

回答

2

看来你需要计算作为抛物线偏移量的曲线。

在接下来的C++程序中,我将展示如何首先找到抛物线的公式,然后如何计算该曲线的偏移量,最后如何找到两个轴互相形成的角度。

我认为点(0,0)作为抛物线的左端,该(顶点)的底部将位于坐标(12,-8.75),而右端位于(24,0)。以此图片作为参考(抛物线是蓝色的,圆的中心的轨迹是橙色):

enter image description here

注意,如果圈太大,而它的一侧切线它可以在另一侧与抛物线相交。我不知道,如果12" 是抛物线的总宽度或只有一半,但在后者的情况下,10" 工具将过大:

enter image description here

该程序将打印出一些样品(25)表示刀具的圆与抛物线相切的点的坐标,圆的中心的对应坐标(刀具的位置)以及两个轴的角度(α和β)。

#include <iostream> 
#include <iomanip> 
#include <vector> 
#include <cmath> 

using std::cout; 
using std::setw; 
using std::vector; 

int main() { 

    // set number of steps or points of approximation 
    int n_steps = 25; 

    // declare vectors to store coordinates into 
    vector<double> x2(n_steps), y2(n_steps); 

    // calculate the parameters of the parabola expressed by the formula 
    // y = ax^2 + bx + c 
    // Knowing 2 points, one of which is the vertex. 
    // xv = -b/2a    | b = -2axv 
    // y0 = ax0^2 + bx0 + c => | yv - y0 = a(xv^2 - x0^2) + b(xv - x0) 
    // yv = axv^2 + bxv + c  | yv - y0 = a(xv - x0)(xv + x0) + b(xv - x0) 
    // 
    // a ((xv - x0)*(xv + x0) - 2xv(xv - x0)) = yv - y0 
    // a (xv - x0)*(xv + x0 - 2xv) = yv - y0 

    // Known coordinates 
    double xv = 12.0, 
      yv = -8.75, 
      x0 = 0.0, 
      y0 = 0.0; 

    double dx = xv - x0, 
      a = (y0 - yv)/(dx * dx), 
      b = - 2.0 * a * xv, 
      c = y0 - x0 * (a * x0 + b); 

    cout << "Parabola formula:\n" 
     << "y = " << a << "x^2 + " << b << "x + " << c << "\n\n" 
     << "max acceptable diameter: " << 1.0/a << "\n\n"; 

    // Coordinates of rotating axes, extrapolated from your drawing 
    double r1 = 13, 
      r2 = 9, 
      x1 = xv - r1, 
      y1 = r2; 
    // some helper values (constant) I'll use later 
    double rad_to_deg = 180.0/M_PI, 
      r1quad = r1 * r1, 
      r2quad = r2 * r2, 
      rdif = r1quad - r2quad, 
      rsum = r1quad + r2quad, 
      rden = 1.0/(2.0 * r1 * r2); 

    // radius of the circle (tool) 
    double diameter = 10, 
      radius = diameter/2.0; 
    cout << "Diameter of tool (circle): " << diameter << "\n\n"; 


    // calculate parabola points 
    cout << "\t\t\tTangent\t\t\t\tCenter of circle\t\t alpha\t\tbeta\n"; 
    // xt[0] = x0 xt[n_steps] = x0 + 2*(xv - x0) 
    double step = 2.0 * dx/(n_steps - 1); 
    for (int i = 0; i < n_steps; ++i) { 
     // calculate the tangent points which lies on the parabola 
     double xt = x0 + i * step, 
       yt = xt * (a * xt + b) + c; 

     // calculate the offset points, coordinates of the center of the circle 
     // first derivative of the parabola 
     double delta = 2.0 * a * xt + b; 

     // point perpendicular to the tangent at distance equal to radius 
     double k = radius/sqrt(delta * delta + 1.0); 
     x2[i] = xt - k * delta; 
     y2[i] = yt + k; 

     // distance from x,y to x1,y1 
     double dx1 = x2[i] - x1, 
       dy1 = y2[i] - y1, 
       r3quad = dx1 * dx1 + dy1 * dy1, 
       r3 = sqrt(r3quad); 

     // Now that I know the coordinates of the vertices of the triangle 
     // and the lengths of its sides I can calculate the inner angles 
     // using Carnot teorem, for example: a^2 = b^2 + c^2 - 2bc*cos(alpha) 
     double alpha_Carnot = acos((rdif + r3quad)/(2.0 * r1 * r3)), 
       beta_Carnot = acos((rsum - r3quad) * rden); 

     // angle to the orizzontal of line from x1,y1 to x,y in radians 
     double gamma = atan2(dy1,dx1); 
     // angle of Axis A to the orizzontal in degrees 
     double alpha = (gamma + alpha_Carnot) * rad_to_deg; 
     // angle of Axis B to Axis A. beta = 0 if parallel 
     double beta = beta_Carnot * rad_to_deg - 180.0; 

     // output the coordinates 
     cout << std::fixed << setw(4) << i << setw(10) << xt << setw(10) << yt 
      << setw(15) << x2[i] << setw(10) << y2[i] 
      << setw(15) << alpha << setw(12) << beta << '\n'; 
    } 

    return 0; 
} 

这是输出:

Parabola formula: 
y = 0.0607639x^2 + -1.45833x + 0 

max acceptable diameter: 16.4571 

Diameter of tool (circle): 10 

      Tangent    Center of circle   alpha  beta 
    0 0.000000 0.000000  4.123644 2.827642  -7.228866 -142.502245 
    1 1.000000 -1.397569  5.003741 1.597437  -7.151211 -132.856051 
    2 2.000000 -2.673611  5.860925 0.503378  -7.962144 -123.965745 
    3 3.000000 -3.828125  6.690144 -0.454279  -9.159057 -115.700562 
    4 4.000000 -4.861111  7.485392 -1.276137  -10.496232 -108.022957 
    5 5.000000 -5.772569  8.239777 -1.964178  -11.833367 -100.941141 
    6 6.000000 -6.562500  8.945861 -2.522462  -13.081185 -94.488527 
    7 7.000000 -7.230903  9.596439 -2.957906  -14.180211 -88.708034 
    8 8.000000 -7.777778  10.185964 -3.280939  -15.093523 -83.633631 
    9 9.000000 -8.203125  10.712644 -3.505588  -15.805504 -79.267662 
    10 10.000000 -8.506944  11.180897 -3.648397  -16.321003 -75.558850 
    11 11.000000 -8.689236  11.603201 -3.725755  -16.659970 -72.392050 
    12 12.000000 -8.750000  12.000000 -3.750000  -16.845543 -69.600878 
    13 13.000000 -8.689236  12.396799 -3.725755  -16.889440 -67.003199 
    14 14.000000 -8.506944  12.819103 -3.648397  -16.782985 -64.443028 
    15 15.000000 -8.203125  13.287356 -3.505588  -16.499460 -61.816277 
    16 16.000000 -7.777778  13.814036 -3.280939  -16.005878 -59.069041 
    17 17.000000 -7.230903  14.403561 -2.957906  -15.277444 -56.174060 
    18 18.000000 -6.562500  15.054139 -2.522462  -14.309495 -53.098717 
    19 19.000000 -5.772569  15.760223 -1.964178  -13.126180 -49.773973 
    20 20.000000 -4.861111  16.514608 -1.276137  -11.788732 -46.064496 
    21 21.000000 -3.828125  17.309856 -0.454279  -10.409278 -41.729113 
    22 22.000000 -2.673611  18.139075 0.503378  -9.184425 -36.337384 
    23 23.000000 -1.397569  18.996259 1.597437  -8.503984 -29.006402 
    24 24.000000 0.000000  19.876356 2.827642  -9.577076 -16.878208 

这些都是一些图片(感谢EXCELL)在不同的位置:左

enter image description here enter image description here enter image description here

+0

你点{0, 0},顶点,右边{24,0}匹配我所做的。 12英寸是抛物线的最大宽度,我需要将轴A向下旋转,然后轴B沿着抛物线的路径旋转。假定圆的直径可以从最大10英寸变化到最小7英寸。 delta [Axis A],delta [Axis B] +(10 - delta [Circle Diameter])=抛物线路径上的点。由于没有足够的空间在此完成,请参阅第二个回复。 – Ken

+0

圆圈中心的两个数字我不确定表示是什么;沿着一条与切线相距一英寸的线?在你的方程中,看起来我应该做的是将切点的1/2圆直径的中心定位;你的答案帮助我更好地解决问题,并更好地定义如何达到预期的结果;即旋转A轴和B轴,将圆的中心定位到圆的1/2直径。这对我来说不再是黑色,更像是满月;也许我可以开始看到太阳在这里升起。 :-) – Ken

+0

@StixO添加角度计算,附带一些描述性图片。告诉我,如果没关系。 –

0

抛物线ax^2+bx+c的斜率是2ax+b

要找到圆的某个斜率值(s),您有y/x = s。再加上方程x^2+y^2=r^2(您可能需要圆的下半部分,顺便说一句),您可以看到相对于圆的中心,圆的边将触及抛物线。

因此,如果圆心与抛物线点之间的距离与圆心与切点之间的距离不同,则需要移动轴。