mirror of
https://github.com/mcneel/opennurbs.git
synced 2026-03-23 19:01:03 +08:00
Sync changes from upstream repository
Co-authored-by: Alain <alain@mcneel.com> Co-authored-by: Andrew Le Bihan <andy@mcneel.com> Co-authored-by: Bozo <bozo@mcneel.com> Co-authored-by: chuck <chuck@mcneel.com> Co-authored-by: Dale Fugier <dale@mcneel.com> Co-authored-by: Giulio Piacentino <giulio@mcneel.com> Co-authored-by: John Croudy <croudyj@gmail.com> Co-authored-by: Mikko Oksanen <mikko@mcneel.com> Co-authored-by: Pierre Cuvilliers <pierre@mcneel.com> Co-authored-by: Steve Baer <steve@mcneel.com>
This commit is contained in:
@@ -1,212 +1,212 @@
|
||||
/* $NoKeywords: $ */
|
||||
/*
|
||||
//
|
||||
// Copyright (c) 1993-2012 Robert McNeel & Associates. All rights reserved.
|
||||
// OpenNURBS, Rhinoceros, and Rhino3D are registered trademarks of Robert
|
||||
// McNeel & Associates.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY.
|
||||
// ALL IMPLIED WARRANTIES OF FITNESS FOR ANY PARTICULAR PURPOSE AND OF
|
||||
// MERCHANTABILITY ARE HEREBY DISCLAIMED.
|
||||
//
|
||||
// For complete openNURBS copyright information see <http://www.opennurbs.org>.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////
|
||||
*/
|
||||
|
||||
#include "opennurbs.h"
|
||||
|
||||
#if !defined(ON_COMPILING_OPENNURBS)
|
||||
// This check is included in all opennurbs source .c and .cpp files to insure
|
||||
// ON_COMPILING_OPENNURBS is defined when opennurbs source is compiled.
|
||||
// When opennurbs source is being compiled, ON_COMPILING_OPENNURBS is defined
|
||||
// and the opennurbs .h files alter what is declared and how it is declared.
|
||||
#error ON_COMPILING_OPENNURBS must be defined when compiling opennurbs
|
||||
#endif
|
||||
|
||||
ON_Sum::ON_Sum()
|
||||
{
|
||||
Begin(0.0);
|
||||
}
|
||||
|
||||
int ON_Sum::SummandCount() const
|
||||
{
|
||||
return m_pos_count + m_neg_count + m_zero_count;
|
||||
}
|
||||
|
||||
void ON_Sum::Begin( double starting_value )
|
||||
{
|
||||
m_sum_err = 0.0;
|
||||
m_pos_sum = 0.0;
|
||||
m_neg_sum = 0.0;
|
||||
m_pos_sum1_count = 0;
|
||||
m_pos_sum2_count = 0;
|
||||
m_pos_sum3_count = 0;
|
||||
m_neg_sum1_count = 0;
|
||||
m_neg_sum2_count = 0;
|
||||
m_neg_sum3_count = 0;
|
||||
m_pos_count = 0;
|
||||
m_neg_count = 0;
|
||||
m_zero_count = 0;
|
||||
|
||||
if ( starting_value > 0.0 )
|
||||
{
|
||||
m_pos_sum = starting_value;
|
||||
}
|
||||
else if ( starting_value < 0.0 )
|
||||
{
|
||||
m_neg_sum = starting_value;
|
||||
}
|
||||
}
|
||||
|
||||
double ON_Sum::SortAndSum( int count, double* a )
|
||||
{
|
||||
// note that the arrays passed to ON_Sum::SortAndSum() are all
|
||||
// homogeneous in sign
|
||||
double s = 0.0;
|
||||
if ( count > 0 )
|
||||
{
|
||||
if ( count >= 2 )
|
||||
{
|
||||
ON_SortDoubleArray( ON::sort_algorithm::quick_sort, a, count );
|
||||
//double a0 = fabs(a[0]);
|
||||
//double a1 = fabs(a[count-1]);
|
||||
m_sum_err += ON_EPSILON*( fabs(a[count-1]) + count*fabs(a[0]) );
|
||||
}
|
||||
if ( a[count] < 0.0 )
|
||||
{
|
||||
a += count-1;
|
||||
while (count--)
|
||||
s += *a--;
|
||||
}
|
||||
else
|
||||
{
|
||||
while (count--)
|
||||
s += *a++;
|
||||
}
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
void ON_Sum::Plus( double x, double dx )
|
||||
{
|
||||
Plus(x);
|
||||
if ( ON_IsValid(dx) )
|
||||
m_sum_err += fabs(dx);
|
||||
}
|
||||
|
||||
void ON_Sum::Plus( double x )
|
||||
{
|
||||
if (x > 0.0)
|
||||
{
|
||||
m_pos_count++;
|
||||
m_pos_sum1[m_pos_sum1_count++] = x;
|
||||
if ( m_pos_sum1_count == sum1_max_count )
|
||||
{
|
||||
m_pos_sum2[m_pos_sum2_count++] = SortAndSum( m_pos_sum1_count, m_pos_sum1 );
|
||||
m_pos_sum1_count = 0;
|
||||
if ( m_pos_sum2_count == sum2_max_count )
|
||||
{
|
||||
m_pos_sum3[m_pos_sum3_count++] = SortAndSum( m_pos_sum2_count, m_pos_sum2 );
|
||||
m_pos_sum2_count = 0;
|
||||
if ( m_pos_sum3_count == sum3_max_count )
|
||||
{
|
||||
x = SortAndSum( m_pos_sum3_count, m_pos_sum3 );
|
||||
m_sum_err += ON_EPSILON*( fabs(x) + fabs(m_pos_sum) );
|
||||
m_pos_sum += x;
|
||||
m_pos_sum3_count = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( x < 0.0 )
|
||||
{
|
||||
m_neg_count++;
|
||||
m_neg_sum1[m_neg_sum1_count++] = x;
|
||||
if ( m_neg_sum1_count == sum1_max_count )
|
||||
{
|
||||
m_neg_sum2[m_neg_sum2_count++] = SortAndSum( m_neg_sum1_count, m_neg_sum1 );
|
||||
m_neg_sum1_count = 0;
|
||||
if ( m_neg_sum2_count == sum2_max_count )
|
||||
{
|
||||
m_neg_sum3[m_neg_sum3_count++] = SortAndSum( m_neg_sum2_count, m_neg_sum2 );
|
||||
m_neg_sum2_count = 0;
|
||||
if ( m_neg_sum3_count == sum3_max_count )
|
||||
{
|
||||
x = SortAndSum( m_neg_sum3_count, m_neg_sum3 );
|
||||
m_sum_err += ON_EPSILON*( fabs(x) + fabs(m_neg_sum) );
|
||||
m_neg_sum += x;
|
||||
m_neg_sum3_count = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
m_zero_count++;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ON_Sum::operator=(double x)
|
||||
{
|
||||
Begin(x);
|
||||
}
|
||||
|
||||
void ON_Sum::operator+=(double x)
|
||||
{
|
||||
Plus(x);
|
||||
}
|
||||
|
||||
void ON_Sum::operator-=(double x)
|
||||
{
|
||||
Plus(-x);
|
||||
}
|
||||
|
||||
|
||||
|
||||
double ON_Sum::Total( double* error_estimate )
|
||||
{
|
||||
double x;
|
||||
if ( m_pos_sum1_count > 0 )
|
||||
{
|
||||
m_pos_sum2[m_pos_sum2_count++] = SortAndSum( m_pos_sum1_count, m_pos_sum1 );
|
||||
m_pos_sum1_count = 0;
|
||||
}
|
||||
if ( m_pos_sum2_count > 0 )
|
||||
{
|
||||
m_pos_sum3[m_pos_sum3_count++] = SortAndSum( m_pos_sum2_count, m_pos_sum2 );
|
||||
m_pos_sum2_count = 0;
|
||||
}
|
||||
if ( m_pos_sum3_count > 0 )
|
||||
{
|
||||
x = SortAndSum( m_pos_sum3_count, m_pos_sum3 );
|
||||
m_sum_err += ON_EPSILON*( fabs(x) + fabs(m_pos_sum) );
|
||||
m_pos_sum += x;
|
||||
m_pos_sum3_count = 0;
|
||||
}
|
||||
|
||||
if ( m_neg_sum1_count > 0 )
|
||||
{
|
||||
m_neg_sum2[m_neg_sum2_count++] = SortAndSum( m_neg_sum1_count, m_neg_sum1 );
|
||||
m_neg_sum1_count = 0;
|
||||
}
|
||||
if ( m_neg_sum2_count > 0 )
|
||||
{
|
||||
m_neg_sum3[m_neg_sum3_count++] = SortAndSum( m_neg_sum2_count, m_neg_sum2 );
|
||||
m_neg_sum2_count = 0;
|
||||
}
|
||||
if ( m_neg_sum3_count > 0 )
|
||||
{
|
||||
x = SortAndSum( m_neg_sum3_count, m_neg_sum3 );
|
||||
m_sum_err += ON_EPSILON*( fabs(x) + fabs(m_neg_sum) );
|
||||
m_neg_sum += x;
|
||||
m_neg_sum3_count = 0;
|
||||
}
|
||||
|
||||
if ( error_estimate )
|
||||
{
|
||||
*error_estimate = m_sum_err + ON_EPSILON*(fabs(m_pos_sum) + fabs(m_neg_sum));
|
||||
}
|
||||
|
||||
return m_pos_sum + m_neg_sum;
|
||||
}
|
||||
/* $NoKeywords: $ */
|
||||
/*
|
||||
//
|
||||
// Copyright (c) 1993-2012 Robert McNeel & Associates. All rights reserved.
|
||||
// OpenNURBS, Rhinoceros, and Rhino3D are registered trademarks of Robert
|
||||
// McNeel & Associates.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY.
|
||||
// ALL IMPLIED WARRANTIES OF FITNESS FOR ANY PARTICULAR PURPOSE AND OF
|
||||
// MERCHANTABILITY ARE HEREBY DISCLAIMED.
|
||||
//
|
||||
// For complete openNURBS copyright information see <http://www.opennurbs.org>.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////
|
||||
*/
|
||||
|
||||
#include "opennurbs.h"
|
||||
|
||||
#if !defined(ON_COMPILING_OPENNURBS)
|
||||
// This check is included in all opennurbs source .c and .cpp files to insure
|
||||
// ON_COMPILING_OPENNURBS is defined when opennurbs source is compiled.
|
||||
// When opennurbs source is being compiled, ON_COMPILING_OPENNURBS is defined
|
||||
// and the opennurbs .h files alter what is declared and how it is declared.
|
||||
#error ON_COMPILING_OPENNURBS must be defined when compiling opennurbs
|
||||
#endif
|
||||
|
||||
ON_Sum::ON_Sum()
|
||||
{
|
||||
Begin(0.0);
|
||||
}
|
||||
|
||||
int ON_Sum::SummandCount() const
|
||||
{
|
||||
return m_pos_count + m_neg_count + m_zero_count;
|
||||
}
|
||||
|
||||
void ON_Sum::Begin( double starting_value )
|
||||
{
|
||||
m_sum_err = 0.0;
|
||||
m_pos_sum = 0.0;
|
||||
m_neg_sum = 0.0;
|
||||
m_pos_sum1_count = 0;
|
||||
m_pos_sum2_count = 0;
|
||||
m_pos_sum3_count = 0;
|
||||
m_neg_sum1_count = 0;
|
||||
m_neg_sum2_count = 0;
|
||||
m_neg_sum3_count = 0;
|
||||
m_pos_count = 0;
|
||||
m_neg_count = 0;
|
||||
m_zero_count = 0;
|
||||
|
||||
if ( starting_value > 0.0 )
|
||||
{
|
||||
m_pos_sum = starting_value;
|
||||
}
|
||||
else if ( starting_value < 0.0 )
|
||||
{
|
||||
m_neg_sum = starting_value;
|
||||
}
|
||||
}
|
||||
|
||||
double ON_Sum::SortAndSum( int count, double* a )
|
||||
{
|
||||
// note that the arrays passed to ON_Sum::SortAndSum() are all
|
||||
// homogeneous in sign
|
||||
double s = 0.0;
|
||||
if ( count > 0 )
|
||||
{
|
||||
if ( count >= 2 )
|
||||
{
|
||||
ON_SortDoubleArray( ON::sort_algorithm::quick_sort, a, count );
|
||||
//double a0 = fabs(a[0]);
|
||||
//double a1 = fabs(a[count-1]);
|
||||
m_sum_err += ON_EPSILON*( fabs(a[count-1]) + count*fabs(a[0]) );
|
||||
}
|
||||
if ( a[count] < 0.0 )
|
||||
{
|
||||
a += count-1;
|
||||
while (count--)
|
||||
s += *a--;
|
||||
}
|
||||
else
|
||||
{
|
||||
while (count--)
|
||||
s += *a++;
|
||||
}
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
void ON_Sum::Plus( double x, double dx )
|
||||
{
|
||||
Plus(x);
|
||||
if ( ON_IsValid(dx) )
|
||||
m_sum_err += fabs(dx);
|
||||
}
|
||||
|
||||
void ON_Sum::Plus( double x )
|
||||
{
|
||||
if (x > 0.0)
|
||||
{
|
||||
m_pos_count++;
|
||||
m_pos_sum1[m_pos_sum1_count++] = x;
|
||||
if ( m_pos_sum1_count == sum1_max_count )
|
||||
{
|
||||
m_pos_sum2[m_pos_sum2_count++] = SortAndSum( m_pos_sum1_count, m_pos_sum1 );
|
||||
m_pos_sum1_count = 0;
|
||||
if ( m_pos_sum2_count == sum2_max_count )
|
||||
{
|
||||
m_pos_sum3[m_pos_sum3_count++] = SortAndSum( m_pos_sum2_count, m_pos_sum2 );
|
||||
m_pos_sum2_count = 0;
|
||||
if ( m_pos_sum3_count == sum3_max_count )
|
||||
{
|
||||
x = SortAndSum( m_pos_sum3_count, m_pos_sum3 );
|
||||
m_sum_err += ON_EPSILON*( fabs(x) + fabs(m_pos_sum) );
|
||||
m_pos_sum += x;
|
||||
m_pos_sum3_count = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( x < 0.0 )
|
||||
{
|
||||
m_neg_count++;
|
||||
m_neg_sum1[m_neg_sum1_count++] = x;
|
||||
if ( m_neg_sum1_count == sum1_max_count )
|
||||
{
|
||||
m_neg_sum2[m_neg_sum2_count++] = SortAndSum( m_neg_sum1_count, m_neg_sum1 );
|
||||
m_neg_sum1_count = 0;
|
||||
if ( m_neg_sum2_count == sum2_max_count )
|
||||
{
|
||||
m_neg_sum3[m_neg_sum3_count++] = SortAndSum( m_neg_sum2_count, m_neg_sum2 );
|
||||
m_neg_sum2_count = 0;
|
||||
if ( m_neg_sum3_count == sum3_max_count )
|
||||
{
|
||||
x = SortAndSum( m_neg_sum3_count, m_neg_sum3 );
|
||||
m_sum_err += ON_EPSILON*( fabs(x) + fabs(m_neg_sum) );
|
||||
m_neg_sum += x;
|
||||
m_neg_sum3_count = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
m_zero_count++;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ON_Sum::operator=(double x)
|
||||
{
|
||||
Begin(x);
|
||||
}
|
||||
|
||||
void ON_Sum::operator+=(double x)
|
||||
{
|
||||
Plus(x);
|
||||
}
|
||||
|
||||
void ON_Sum::operator-=(double x)
|
||||
{
|
||||
Plus(-x);
|
||||
}
|
||||
|
||||
|
||||
|
||||
double ON_Sum::Total( double* error_estimate )
|
||||
{
|
||||
double x;
|
||||
if ( m_pos_sum1_count > 0 )
|
||||
{
|
||||
m_pos_sum2[m_pos_sum2_count++] = SortAndSum( m_pos_sum1_count, m_pos_sum1 );
|
||||
m_pos_sum1_count = 0;
|
||||
}
|
||||
if ( m_pos_sum2_count > 0 )
|
||||
{
|
||||
m_pos_sum3[m_pos_sum3_count++] = SortAndSum( m_pos_sum2_count, m_pos_sum2 );
|
||||
m_pos_sum2_count = 0;
|
||||
}
|
||||
if ( m_pos_sum3_count > 0 )
|
||||
{
|
||||
x = SortAndSum( m_pos_sum3_count, m_pos_sum3 );
|
||||
m_sum_err += ON_EPSILON*( fabs(x) + fabs(m_pos_sum) );
|
||||
m_pos_sum += x;
|
||||
m_pos_sum3_count = 0;
|
||||
}
|
||||
|
||||
if ( m_neg_sum1_count > 0 )
|
||||
{
|
||||
m_neg_sum2[m_neg_sum2_count++] = SortAndSum( m_neg_sum1_count, m_neg_sum1 );
|
||||
m_neg_sum1_count = 0;
|
||||
}
|
||||
if ( m_neg_sum2_count > 0 )
|
||||
{
|
||||
m_neg_sum3[m_neg_sum3_count++] = SortAndSum( m_neg_sum2_count, m_neg_sum2 );
|
||||
m_neg_sum2_count = 0;
|
||||
}
|
||||
if ( m_neg_sum3_count > 0 )
|
||||
{
|
||||
x = SortAndSum( m_neg_sum3_count, m_neg_sum3 );
|
||||
m_sum_err += ON_EPSILON*( fabs(x) + fabs(m_neg_sum) );
|
||||
m_neg_sum += x;
|
||||
m_neg_sum3_count = 0;
|
||||
}
|
||||
|
||||
if ( error_estimate )
|
||||
{
|
||||
*error_estimate = m_sum_err + ON_EPSILON*(fabs(m_pos_sum) + fabs(m_neg_sum));
|
||||
}
|
||||
|
||||
return m_pos_sum + m_neg_sum;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user