LINUX.ORG.RU

История изменений

Исправление sambist, (текущая версия) :

Ну в общем ситуация такая:

В основном приложении:


SmlPoint p1 = (SmlPoint){500, 500};
SmlPoint p2 = (SmlPoint){  0,   0};

void test2()
{
    int32_t i;
    SmlLine line = (SmlLine){p1, p2};
    uint16_t val;
    for (i = 0; i < 1000; i++)
    {
        val += SmlGradientRadialValue(line, (SmlPoint){i, 250});
    }
}

///
SML_PROFILER_INIT;
SML_PROFILER_MEAS(100000, test2(), "expec");

В библиотеке
uint16_t SmlGradientRadialValue(SmlLine line, SmlPoint target)
{
  /*                          ┌──────┐
                         ┌────┘      └────┐
                       ┌─┘                └─┐
                     ┌─┘                    └─┐
                   ┌─┘                        └─┐
                   │                            │
                   │   __ Gradient line         │
                 ┌─┘  /                         └─┐
                 │   /             A(x1, y1)      │
                 │───────────────()               │
                 │                                │
                 └─┐                            ┌─┘
                   │                            │
                   │                T(tx, ty)   │
                   └─┐            ()          ┌─┘
                     └─┐                    ┌─┘
                       └─┐   B(x2, y2)    ┌─┘
                         └─()─┐      ┌────┘
                              └──────┘
   * Returns gradient value [SML_GRAD_MIN..SML_GRAD_MAX] from A to B relative
     to the point T.
   Solution:
   I.  If the target point is equal to A, return SML_GRAD_MIN
   II. Calculate the AB & AT distances.
   III. If AT is bigger than AB, return the SML_GRAD_MAX
   IV. Return the of the AT length to AB length and normalise it. */

   if ((target.x == line.p1.x) && (target.y == line.p1.y))
       return SML_GRAD_MIN;
   uint32_t AB = (SML_SQR(line.p1.x - line.p2.x) +
                  SML_SQR(line.p1.y - line.p2.y));
   uint32_t AT = (SML_SQR(line.p1.x - target.x) +
                  SML_SQR(line.p1.y - target.y));
   if (AT > AB)
       return SML_GRAD_MAX;
   return sqrti(SML_SQR((uint32_t)SML_GRAD_MAX) / AB * AT);
}

профайлер:
/* E+ */
#define SML_PROFILER_INIT            \
    clock_t sml_prof_time_start = 0; \
    clock_t sml_prof_time_stop  = 0; \
    int32_t sml_prof_counter

/// @optimize use system getclock (phone note).
#define SML_PROFILER_MEAS(COUNT, FUNC, MESSAGE)   \
    sml_prof_time_start = clock();                \
    for (sml_prof_counter = 0;                    \
         sml_prof_counter < (COUNT);              \
         sml_prof_counter++)                      \
        (FUNC);                                   \
    sml_prof_time_stop  = clock();                \
    printf(MESSAGE ": %d cycles took %f s\n",     \
        (int32_t)(COUNT),                         \
        (float)(sml_prof_time_stop -              \
                sml_prof_time_start) /            \
               CLOCKS_PER_SEC)
/* E- */

Исходная версия sambist, :

Ну в общем ситуация такая:

В основном приложении:


SmlPoint p1 = (SmlPoint){500, 500};
SmlPoint p2 = (SmlPoint){  0,   0};

void test2()
{
    int32_t i;
    SmlLine line = (SmlLine){p1, p2};
    uint16_t val;
    for (i = 0; i < 1000; i++)
    {
        val += SmlGradientRadialValue(line, (SmlPoint){i, 250});
    }
}

///
SML_PROFILER_INIT;
SML_PROFILER_MEAS(100000, test2(), "expec");

В библиотеке
uint16_t SmlGradientRadialValue(SmlLine line, SmlPoint target)
{
  /*                          ┌──────┐
                         ┌────┘      └────┐
                       ┌─┘                └─┐
                     ┌─┘                    └─┐
                   ┌─┘                        └─┐
                   │                            │
                   │   __ Gradient line         │
                 ┌─┘  /                         └─┐
                 │   /             A(x1, y1)      │
                 │───────────────()               │
                 │                                │
                 └─┐                            ┌─┘
                   │                            │
                   │                T(tx, ty)   │
                   └─┐            ()          ┌─┘
                     └─┐                    ┌─┘
                       └─┐   B(x2, y2)    ┌─┘
                         └─()─┐      ┌────┘
                              └──────┘
   * Returns gradient value [SML_GRAD_MIN..SML_GRAD_MAX] from A to B relative
     to the point T.
   Solution:
   I.  If the target point is equal to A, return SML_GRAD_MIN
   II. Calculate the AB & AT distances.
   III. If AT is bigger than AB, return the SML_GRAD_MAX
   IV. Return the of the AT length to AB length and normalise it. */

   if ((target.x == line.p1.x) && (target.y == line.p1.y))
       return SML_GRAD_MIN;
   uint32_t AB = (SML_SQR(line.p1.x - line.p2.x) +
                  SML_SQR(line.p1.y - line.p2.y));
   uint32_t AT = (SML_SQR(line.p1.x - target.x) +
                  SML_SQR(line.p1.y - target.y));
   if (AT > AB)
       return SML_GRAD_MAX;
   return sqrti(SML_SQR((uint32_t)SML_GRAD_MAX) / AB * AT);
}