История изменений
Исправление
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);
}