Add atan2 to math2

This commit is contained in:
Keim, Stefan 2021-06-18 11:14:02 +02:00
parent 3c0bfdf74c
commit f75f698ab4
6 changed files with 143 additions and 2 deletions

View File

@ -1468,6 +1468,35 @@ public:
return( math2_const( VIPS_OPERATION_MATH2_WOP,
other, options ) );
}
/**
* Calculate atan2 of each pixel.
*/
VImage
atan2( VImage other, VOption *options = 0 ) const
{
return( math2( other, VIPS_OPERATION_MATH2_ATAN2, options ) );
}
/**
* Calculate atan2 of each pixel.
*/
VImage
atan2( double other, VOption *options = 0 ) const
{
return( math2_const( VIPS_OPERATION_MATH2_ATAN2,
to_vector( other ), options ) );
}
/**
* Calculate atan2 of each pixel.
*/
VImage
atan2( std::vector<double> other, VOption *options = 0 ) const
{
return( math2_const( VIPS_OPERATION_MATH2_ATAN2,
other, options ) );
}
/**
* Use self as a conditional image (not zero meaning TRUE) to pick

View File

@ -949,7 +949,7 @@
<row>
<entry>math2</entry>
<entry>Binary math operations</entry>
<entry>vips_math2(), vips_pow(), vips_wop()</entry>
<entry>vips_math2(), vips_pow(), vips_wop(), vips_atan2()</entry>
</row>
<row>
<entry>math2_const</entry>

View File

@ -83,7 +83,7 @@ def gen_function_list():
'extract_area': ['crop'],
'linear': ['linear1'],
'math': ['sin', 'cos', 'tan', 'asin', 'acos', 'atan', 'exp', 'exp10', 'log', 'log10'],
'math2': ['pow', 'wop'],
'math2': ['pow', 'wop', 'atan2'],
'rank': ['median'],
'relational': ['equal', 'notequal', 'less', 'lesseq', 'more', 'moreeq'],
'remainder_const': ['remainder_const1'],

View File

@ -146,6 +146,25 @@ vips_math2_build( VipsObject *object )
#define WOP( Y, X, E ) POW( Y, E, X )
#ifdef HAVE_ATAN2
#define ATAN2( Y, L, R ) { \
double left = (double) (L); \
double right = (double) (R); \
\
(Y) = VIPS_DEG( atan2( left, right ) ); \
if( (Y) < 0.0 ) \
(Y) += 360; \
}
#else
#define ATAN2( Y, L, R ) { \
double left = (double) (L); \
double right = (double) (R); \
\
(Y) = vips_col_ab2h( left, right ); \
}
#endif
static void
vips_math2_buffer( VipsArithmetic *arithmetic,
VipsPel *out, VipsPel **in, int width )
@ -159,6 +178,7 @@ vips_math2_buffer( VipsArithmetic *arithmetic,
switch( math2->math2 ) {
case VIPS_OPERATION_MATH2_POW: SWITCH( LOOP, POW ); break;
case VIPS_OPERATION_MATH2_WOP: SWITCH( LOOP, WOP ); break;
case VIPS_OPERATION_MATH2_ATAN2: SWITCH( LOOP, ATAN2 ); break;
default:
g_assert_not_reached();
@ -320,6 +340,31 @@ vips_wop( VipsImage *left, VipsImage *right, VipsImage **out, ... )
return( result );
}
/**
* vips_atan2:
* @left: left-hand input #VipsImage
* @right: right-hand input #VipsImage
* @out: (out): output #VipsImage
* @...: %NULL-terminated list of optional named arguments
*
* Perform #VIPS_OPERATION_MATH2_ATAN2 on a pair of images. See
* vips_math2().
*
* Returns: 0 on success, -1 on error
*/
int
vips_atan2( VipsImage *left, VipsImage *right, VipsImage **out, ... )
{
va_list ap;
int result;
va_start( ap, out );
result = vips_math2v( left, right, out, VIPS_OPERATION_MATH2_ATAN2, ap );
va_end( ap );
return( result );
}
typedef struct _VipsMath2Const {
VipsUnaryConst parent_instance;
@ -380,6 +425,10 @@ vips_math2_const_buffer( VipsArithmetic *arithmetic,
SWITCH( LOOPC, WOP );
break;
case VIPS_OPERATION_MATH2_ATAN2:
SWITCH( LOOPC, ATAN2 );
break;
default:
g_assert_not_reached();
break;
@ -536,6 +585,33 @@ vips_wop_const( VipsImage *in, VipsImage **out, const double *c, int n, ... )
return( result );
}
/**
* vips_atan2_const: (method)
* @in: left-hand input #VipsImage
* @out: (out): output #VipsImage
* @c: (array length=n): array of constants
* @n: number of constants in @c
* @...: %NULL-terminated list of optional named arguments
*
* Perform #VIPS_OPERATION_MATH2_ATAN2 on an image and a constant. See
* vips_math2_const().
*
* Returns: 0 on success, -1 on error
*/
int
vips_atan2_const( VipsImage *in, VipsImage **out, const double *c, int n, ... )
{
va_list ap;
int result;
va_start( ap, n );
result = vips_math2_constv( in, out,
VIPS_OPERATION_MATH2_ATAN2, c, n, ap );
va_end( ap );
return( result );
}
/**
* vips_math2_const1: (method)
* @in: input image
@ -614,3 +690,29 @@ vips_wop_const1( VipsImage *in, VipsImage **out, double c, ... )
return( result );
}
/**
* vips_atan2_const1: (method)
* @in: left-hand input #VipsImage
* @out: (out): output #VipsImage
* @c: constant
* @...: %NULL-terminated list of optional named arguments
*
* Perform #VIPS_OPERATION_MATH2_ATAN2 on an image and a constant. See
* vips_math2_const().
*
* Returns: 0 on success, -1 on error
*/
int
vips_atan2_const1( VipsImage *in, VipsImage **out, double c, ... )
{
va_list ap;
int result;
va_start( ap, c );
result = vips_math2_constv( in, out,
VIPS_OPERATION_MATH2_ATAN2, &c, 1, ap );
va_end( ap );
return( result );
}

View File

@ -71,12 +71,14 @@ typedef enum {
* VipsOperationMath2:
* @VIPS_OPERATION_MATH2_POW: pow( left, right )
* @VIPS_OPERATION_MATH2_WOP: pow( right, left )
* @VIPS_OPERATION_MATH2_ATAN2: pow( left, right )
*
* See also: vips_math().
*/
typedef enum {
VIPS_OPERATION_MATH2_POW,
VIPS_OPERATION_MATH2_WOP,
VIPS_OPERATION_MATH2_ATAN2,
VIPS_OPERATION_MATH2_LAST
} VipsOperationMath2;
@ -368,6 +370,8 @@ int vips_pow( VipsImage *left, VipsImage *right, VipsImage **out, ... )
__attribute__((sentinel));
int vips_wop( VipsImage *left, VipsImage *right, VipsImage **out, ... )
__attribute__((sentinel));
int vips_atan2( VipsImage *left, VipsImage *right, VipsImage **out, ... )
__attribute__((sentinel));
int vips_math2_const( VipsImage *in, VipsImage **out,
VipsOperationMath2 math2, const double *c, int n, ... )
__attribute__((sentinel));
@ -377,6 +381,9 @@ int vips_pow_const( VipsImage *in, VipsImage **out,
int vips_wop_const( VipsImage *in, VipsImage **out,
const double *c, int n, ... )
__attribute__((sentinel));
int vips_atan2_const( VipsImage *in, VipsImage **out,
const double *c, int n, ... )
__attribute__((sentinel));
int vips_math2_const1( VipsImage *in, VipsImage **out,
VipsOperationMath2 math2, double c, ... )
__attribute__((sentinel));
@ -384,6 +391,8 @@ int vips_pow_const1( VipsImage *in, VipsImage **out, double c, ... )
__attribute__((sentinel));
int vips_wop_const1( VipsImage *in, VipsImage **out, double c, ... )
__attribute__((sentinel));
int vips_atan2_const1( VipsImage *in, VipsImage **out, double c, ... )
__attribute__((sentinel));
int vips_avg( VipsImage *in, double *out, ... )
__attribute__((sentinel));

View File

@ -40,6 +40,7 @@ vips_operation_math2_get_type( void )
static const GEnumValue values[] = {
{VIPS_OPERATION_MATH2_POW, "VIPS_OPERATION_MATH2_POW", "pow"},
{VIPS_OPERATION_MATH2_WOP, "VIPS_OPERATION_MATH2_WOP", "wop"},
{VIPS_OPERATION_MATH2_ATAN2, "VIPS_OPERATION_MATH2_ATAN2", "atan2"},
{VIPS_OPERATION_MATH2_LAST, "VIPS_OPERATION_MATH2_LAST", "last"},
{0, NULL, NULL}
};