67 double bc = ( b.
x * b.
x + b.
y * b.
y ) / 2.0;
68 double cd = ( -d.
x * d.
x - d.
y * d.
y ) / 2.0;
69 double det = -b.
x * d.
y + d.
x * b.
y;
71 if( fabs( det ) < 1.0e-6 )
75 aCenter->
x = ( -bc * d.
y - cd * b.
y ) * det;
76 aCenter->
y = ( b.
x * cd + d.
x * bc ) * det;
88 double yDelta_21 = aMid.
y - aStart.
y;
89 double xDelta_21 = aMid.
x - aStart.
x;
90 double yDelta_32 = aEnd.
y - aMid.
y;
91 double xDelta_32 = aEnd.
x - aMid.
x;
96 if( ( ( xDelta_21 == 0.0 ) && ( yDelta_32 == 0.0 ) )
97 || ( ( yDelta_21 == 0.0 ) && ( xDelta_32 == 0.0 ) ) )
99 center.
x = ( aStart.
x + aEnd.
x ) / 2.0;
100 center.
y = ( aStart.
y + aEnd.
y ) / 2.0;
111 double aSlope = yDelta_21 / xDelta_21;
112 double bSlope = yDelta_32 / xDelta_32;
114 if( aSlope == bSlope )
120 center.
x = ( aStart.
x + aMid.
x ) / 2.0;
121 center.
y = ( aStart.
y + aMid.
y ) / 2.0;
134 center.
x = ( aSlope * bSlope * ( aStart.
y - aEnd.
y ) + bSlope * ( aStart.
x + aMid.
x )
135 - aSlope * ( aMid.
x + aEnd.
x ) )
136 / ( 2 * ( bSlope - aSlope ) );
140 center.
y = ( ( ( aStart.
x + aMid.
x ) / 2.0 - center.
x ) / aSlope
141 + ( aStart.
y + aMid.
y ) / 2.0 );
146 ( ( ( aMid.
x + aEnd.
x ) / 2.0 - center.
x ) / bSlope + ( aMid.
y + aEnd.
y ) / 2.0 );
170 std::vector<TEST_CALC_ARC_CENTER_CASE> calc_center_cases = {
174 const double tolerance = 1.0;
203 double crs = ( calcCenter - start ).EuclideanNorm();
204 double crm = ( calcCenter - mid ).EuclideanNorm();
205 double cre = ( calcCenter - end ).EuclideanNorm();
207 double cavg = ( crs + crm + cre ) / 3.0;
209 if(
std::abs( crs - cavg ) > tolerance ||
std::abs( crm - cavg ) > tolerance
210 ||
std::abs( cre - cavg ) > tolerance )
212 msg <<
"CalcArcCenter failed.";
214 msg <<
"\nstart: " << entry.istart.Format();
215 msg <<
"\nmid: " << entry.imid.Format();
216 msg <<
"\nend: " << entry.iend.Format();
219 msg <<
"\nCalculated center: " << wxString::Format(
"%.15f", calcCenter.
x ) <<
", "
220 << wxString::Format(
"%.15f", calcCenter.
y );
222 msg <<
"\n Avg radius: " << wxString::Format(
"%.15f", cavg );
223 msg <<
"\nStart radius: " << wxString::Format(
"%.15f", crs );
224 msg <<
"\n Mid radius: " << wxString::Format(
"%.15f", crm );
225 msg <<
"\n End radius: " << wxString::Format(
"%.15f", cre );
229 EDA_ANGLE angStart( start - calcCenter );
238 RotatePoint( newMid, calcCenter, -angCenter / 2.0 );
241 msg <<
"\nNew mid: " << wxString::Format(
"%.15f", newMid.
x ) <<
", "
242 << wxString::Format(
"%.15f", newMid.
y );
244 msg <<
"\nNew end: " << wxString::Format(
"%.15f", newEnd.
x ) <<
", "
245 << wxString::Format(
"%.15f", newEnd.
y );
248 double endsDist = ( newEnd - end ).EuclideanNorm();
250 msg <<
"\nNew end is off by " << wxString::Format(
"%.15f", endsDist );
258 double r0_rs = ( ref0Center - start ).EuclideanNorm();
259 double r0_rm = ( ref0Center - mid ).EuclideanNorm();
260 double r0_rre = ( ref0Center - end ).EuclideanNorm();
262 double r0_ravg = ( r0_rs + r0_rm + r0_rre ) / 3.0;
264 msg <<
"\nReference0 center: " << wxString::Format(
"%.15f", ref0Center.
x ) <<
", "
265 << wxString::Format(
"%.15f", ref0Center.
y );
267 msg <<
"\nRef0 Avg radius: " << wxString::Format(
"%.15f", r0_ravg );
268 msg <<
"\nRef0 Start radius: " << wxString::Format(
"%.15f", r0_rs );
269 msg <<
"\nRef0 Mid radius: " << wxString::Format(
"%.15f", r0_rm );
270 msg <<
"\nRef0 End radius: " << wxString::Format(
"%.15f", r0_rre );
277 double r1_rs = ( ref1Center - start ).EuclideanNorm();
278 double r1_rm = ( ref1Center - mid ).EuclideanNorm();
279 double r1_rre = ( ref1Center - end ).EuclideanNorm();
281 double r1_ravg = ( r1_rs + r1_rm + r1_rre ) / 3.0;
283 msg <<
"\nReference1 center: " << wxString::Format(
"%.15f", ref1Center.
x ) <<
", "
284 << wxString::Format(
"%.15f", ref1Center.
y );
286 msg <<
"\nRef1 Avg radius: " << wxString::Format(
"%.15f", r1_ravg );
287 msg <<
"\nRef1 Start radius: " << wxString::Format(
"%.15f", r1_rs );
288 msg <<
"\nRef1 Mid radius: " << wxString::Format(
"%.15f", r1_rm );
289 msg <<
"\nRef1 End radius: " << wxString::Format(
"%.15f", r1_rre );
294 BOOST_CHECK_MESSAGE(
false, msg );
327 for(
size_t i = 0; i < 16; i++ )
328 BOOST_CHECK( zero.Value8[i] == 0 );
332 for(
size_t i = 0; i < 16; i++ )
333 BOOST_CHECK( zero_h->
Value8[i] == 0 );
338 h.
Value64[0] = 0x00CDEF0123456789ULL;
339 h.
Value64[1] = 0x56789ABCDEF01234ULL;
341 BOOST_CHECK( h != zero );
344 BOOST_CHECK( b != zero );
346 BOOST_CHECK( b == h );
347 BOOST_CHECK( h == b );
348 BOOST_CHECK_EQUAL( h.
ToString(), std::string(
"00CDEF012345678956789ABCDEF01234" ) );
361 std::vector<std::vector<int32_t>> data;
363 for(
size_t i = 0; i < 10; i++ )
365 std::vector<int32_t>& vec = data.emplace_back();
367 size_t vecSize = rand() % 128;
369 for(
size_t j = 0; j < vecSize; j++ )
370 vec.emplace_back( rand() );
375 for(
const std::vector<int32_t>& vec : data )
379 for(
const int32_t val : vec )
388 BOOST_CHECK( h128 == orig128 );
401#if defined( _MSC_VER )
402 #define FORCE_INLINE __forceinline
404 #define ROTL64( x, y ) _rotl64( x, y )
405 #define BIG_CONSTANT( x ) ( x )
408 #define FORCE_INLINE inline __attribute__( ( always_inline ) )
409 inline uint64_t
rotl64( uint64_t x, int8_t r )
411 return ( x << r ) | ( x >> ( 64 - r ) );
413 #define ROTL64( x, y ) rotl64( x, y )
414 #define BIG_CONSTANT( x ) ( x##LLU )
435 const uint32_t seed,
void * out )
437 const uint8_t * data = (
const uint8_t*)key;
438 const int nblocks = len / 16;
449 const uint64_t * blocks = (
const uint64_t *)(data);
451 for(
int i = 0; i < nblocks; i++)
456 k1 *= c1; k1 =
ROTL64(k1,31); k1 *= c2; h1 ^= k1;
458 h1 =
ROTL64(h1,27); h1 += h2; h1 = h1*5+0x52dce729;
460 k2 *= c2; k2 =
ROTL64(k2,33); k2 *= c1; h2 ^= k2;
462 h2 =
ROTL64(h2,31); h2 += h1; h2 = h2*5+0x38495ab5;
468 const uint8_t * tail = (
const uint8_t*)(data + nblocks*16);
475 case 15: k2 ^= ((uint64_t)tail[14]) << 48;
476 case 14: k2 ^= ((uint64_t)tail[13]) << 40;
477 case 13: k2 ^= ((uint64_t)tail[12]) << 32;
478 case 12: k2 ^= ((uint64_t)tail[11]) << 24;
479 case 11: k2 ^= ((uint64_t)tail[10]) << 16;
480 case 10: k2 ^= ((uint64_t)tail[ 9]) << 8;
481 case 9: k2 ^= ((uint64_t)tail[ 8]) << 0;
482 k2 *= c2; k2 =
ROTL64(k2,33); k2 *= c1; h2 ^= k2;
484 case 8: k1 ^= ((uint64_t)tail[ 7]) << 56;
485 case 7: k1 ^= ((uint64_t)tail[ 6]) << 48;
486 case 6: k1 ^= ((uint64_t)tail[ 5]) << 40;
487 case 5: k1 ^= ((uint64_t)tail[ 4]) << 32;
488 case 4: k1 ^= ((uint64_t)tail[ 3]) << 24;
489 case 3: k1 ^= ((uint64_t)tail[ 2]) << 16;
490 case 2: k1 ^= ((uint64_t)tail[ 1]) << 8;
491 case 1: k1 ^= ((uint64_t)tail[ 0]) << 0;
492 k1 *= c1; k1 =
ROTL64(k1,31); k1 *= c2; h1 ^= k1;
498 h1 ^= len; h2 ^= len;
509 ((uint64_t*)out)[0] = h1;
510 ((uint64_t*)out)[1] = h2;
A streaming C++ equivalent for MurmurHash3_x64_128.
FORCE_INLINE void add(const std::string &input)
FORCE_INLINE HASH_128 digest()
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
A storage class for 128-bit hash value.
std::string ToString() const
BOOST_AUTO_TEST_SUITE(CadstarPartParser)
BOOST_AUTO_TEST_SUITE_END()
FORCE_INLINE uint64_t fmix64(uint64_t k)
uint64_t rotl64(uint64_t x, int8_t r)
static const VECTOR2D Ref1CalcArcCenter(const VECTOR2D &aStart, const VECTOR2D &aMid, const VECTOR2D &aEnd)
FORCE_INLINE uint64_t getblock64(const uint64_t *p, int i)
void MurmurHash3_x64_128(const void *key, const int len, const uint32_t seed, void *out)
static bool Ref0CircleCenterFrom3Points(const VECTOR2D &p1, const VECTOR2D &p2, const VECTOR2D &p3, VECTOR2D *aCenter)
Test suite for KiCad math code.
BOOST_AUTO_TEST_CASE(TestCalcArcCenter3Pts)
Declare the test suite.
void RotatePoint(int *pX, int *pY, const EDA_ANGLE &aAngle)
Calculate the new point of coord coord pX, pY, for a rotation center 0, 0.
bool InterceptsPositiveX(double aStartAngle, double aEndAngle)
Test if an arc from aStartAngle to aEndAngle crosses the positive X axis (0 degrees).
bool InterceptsNegativeX(double aStartAngle, double aEndAngle)
Test if an arc from aStartAngle to aEndAngle crosses the negative X axis (180 degrees).
const VECTOR2I CalcArcCenter(const VECTOR2I &aStart, const VECTOR2I &aMid, const VECTOR2I &aEnd)
Determine the center of an arc or circle given three points on its circumference.