From 1802977b95d29198f27535b1b731d1180c083667 Mon Sep 17 00:00:00 2001 From: Aleks Kissinger Date: Wed, 11 Jan 2017 16:33:00 +0100 Subject: made new subdir --- tikzit-1/src/common/test/maths.m | 562 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 562 insertions(+) create mode 100644 tikzit-1/src/common/test/maths.m (limited to 'tikzit-1/src/common/test/maths.m') diff --git a/tikzit-1/src/common/test/maths.m b/tikzit-1/src/common/test/maths.m new file mode 100644 index 0000000..a11e58e --- /dev/null +++ b/tikzit-1/src/common/test/maths.m @@ -0,0 +1,562 @@ +// +// TikZiT +// +// Copyright 2011 Alex Merry +// +// This file is part of TikZiT. +// +// TikZiT is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// TikZiT is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with TikZiT. If not, see . +// + +#import "../util.h" + +#import "test.h" + +void testRectAroundPoints() { + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + startTestBlock(@"NSRectAroundPoints"); + + NSRect rect = NSRectAroundPoints (NSZeroPoint, NSZeroPoint); + assertRectsEqual (@"(0,0) and (0,0)", rect, NSZeroRect); + + rect = NSRectAroundPoints (NSZeroPoint, NSMakePoint (1.0f, 1.0f)); + assertRectsEqual (@"(0,0) and (1,1)", rect, NSMakeRect (0.0f, 0.0f, 1.0f, 1.0f)); + + rect = NSRectAroundPoints (NSMakePoint (-1.0f, 1.0f), NSMakePoint (1.0f, -1.0f)); + assertRectsEqual (@"(-1,1) and (1,-1)", rect, NSMakeRect (-1.0f, -1.0f, 2.0f, 2.0f)); + + endTestBlock(@"NSRectAroundPoints"); + [pool drain]; +} + +void testRectAroundPointsWithPadding() { + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + startTestBlock(@"NSRectAroundPointsWithPadding"); + + NSRect rect = NSRectAroundPointsWithPadding (NSZeroPoint, NSZeroPoint, 0.0f); + assertRectsEqual (@"(0,0) and (0,0); 0 padding", rect, NSZeroRect); + + rect = NSRectAroundPointsWithPadding (NSZeroPoint, NSZeroPoint, 0.2f); + assertRectsEqual (@"(0,0) and (0,0); 0.2 padding", rect, NSMakeRect (-0.2f, -0.2f, 0.4f, 0.4f)); + + rect = NSRectAroundPointsWithPadding (NSZeroPoint, NSMakePoint (1.0f, 1.0f), -0.2f); + assertRectsEqual (@"(0,0) and (1,1); -0.2 padding", rect, NSMakeRect (0.2f, 0.2f, 0.6f, 0.6f)); + + endTestBlock(@"NSRectAroundPointsWithPadding"); + [pool drain]; +} + +void testGoodAtan() { + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + startTestBlock(@"good_atan"); + + assertFloatsEqual (@"0.0, 0.0", good_atan (0.0f, 0.0f), 0.0f); + assertFloatsEqual (@"0.0, 1.0", good_atan (0.0f, 1.0f), 0.5f * M_PI); + assertFloatsEqual (@"0.0, -1.0", good_atan (0.0f, -1.0f), 1.5f * M_PI); + assertFloatsEqual (@"1.0, 0.0", good_atan (1.0f, 0.0f), 0.0f); + assertFloatsEqual (@"1.0, 0.1", good_atan (1.0f, 0.1f), 0.0996687f); + + endTestBlock(@"good_atan"); + [pool drain]; +} + +void testBezierInterpolate() { + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + startTestBlock(@"bezierInterpolate"); + + assertFloatsEqual (@"0.0, (0.0, 0.1, 0.2, 0.3)", bezierInterpolate (0.0f, 0.0f, 0.1f, 0.2f, 0.3f), 0.0f); + assertFloatsEqual (@"1.0, (0.0, 0.1, 0.2, 0.3)", bezierInterpolate (1.0f, 0.0f, 0.1f, 0.2f, 0.3f), 0.3f); + assertFloatsEqual (@"0.5, (0.0, 0.1, 0.2, 0.3)", bezierInterpolate (0.5f, 0.0f, 0.1f, 0.2f, 0.3f), 0.15f); + // FIXME: other tests + + endTestBlock(@"bezierInterpolate"); + [pool drain]; +} + +void testLineSegmentsIntersect() { + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + startTestBlock(@"lineSegmentsIntersect"); + + BOOL result = NO; + NSPoint intersection = NSMakePoint (-1.0f, -1.0f); + + result = lineSegmentsIntersect (NSMakePoint (-1.0f, -1.0f), NSMakePoint (1.0f, 1.0f), + NSMakePoint (-1.0f, 1.0f), NSMakePoint (1.0f, -1.0f), + &intersection); + TEST (@"Cross at zero: has intersection", result); + assertPointsEqual (@"Cross at zero: intersection value", intersection, NSZeroPoint); + + result = lineSegmentsIntersect (NSMakePoint (-1.0f, -1.0f), NSMakePoint (-0.5f, -0.5f), + NSMakePoint (-1.0f, 1.0f), NSMakePoint (1.0f, -1.0f), + &intersection); + TEST (@"Fail to cross at zero", !result); + + result = lineSegmentsIntersect (NSMakePoint (1.0f, 1.0f), NSMakePoint (1.0f, -1.0f), + NSMakePoint (0.0f, 0.0f), NSMakePoint (1.0f, 0.0f), + &intersection); + TEST (@"Touch at one: has intersection", result); + assertPointsEqual (@"Touch at one: intersection value", intersection, NSMakePoint (1.0f, 0.0f)); + + endTestBlock(@"lineSegmentsIntersect"); + [pool drain]; +} + +void testLineSegmentIntersectsRect() { + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + startTestBlock(@"lineSegmentIntersectsRect"); + + BOOL result = NO; + + result = lineSegmentIntersectsRect ( + NSMakePoint (-1.0f, -1.0f), + NSMakePoint (0.0f, 0.0f), + NSZeroRect); + TEST (@"Zero rect; line touches zero", result); + + result = lineSegmentIntersectsRect ( + NSMakePoint (-1.0f, -1.0f), + NSMakePoint (-0.1f, -0.1f), + NSZeroRect); + TEST (@"Zero rect; line short of zero", !result); + + NSRect rect = NSMakeRect (1.0f, 1.0f, 1.0f, 1.0f); + + result = lineSegmentIntersectsRect ( + NSMakePoint (0.0f, 0.0f), + NSMakePoint (3.0f, 1.0f), + rect); + TEST (@"Line underneath", !result); + + result = lineSegmentIntersectsRect ( + NSMakePoint (0.0f, 0.0f), + NSMakePoint (1.0f, 3.0f), + rect); + TEST (@"Line to left", !result); + + result = lineSegmentIntersectsRect ( + NSMakePoint (0.0f, 2.0f), + NSMakePoint (3.0f, 3.0f), + rect); + TEST (@"Line above", !result); + + result = lineSegmentIntersectsRect ( + NSMakePoint (2.0f, 0.0f), + NSMakePoint (3.0f, 3.0f), + rect); + TEST (@"Line to right", !result); + + result = lineSegmentIntersectsRect ( + NSMakePoint (0.0f, 0.0f), + NSMakePoint (0.9f, 0.9f), + rect); + TEST (@"Line short", !result); + + result = lineSegmentIntersectsRect ( + NSMakePoint (1.1f, 1.1f), + NSMakePoint (1.9f, 1.9f), + rect); + TEST (@"Line inside", result); + + result = lineSegmentIntersectsRect ( + NSMakePoint (0.0f, 1.5f), + NSMakePoint (3.0f, 1.5f), + rect); + TEST (@"Horizontal line through", result); + + result = lineSegmentIntersectsRect ( + NSMakePoint (1.5f, 0.0f), + NSMakePoint (1.5f, 3.0f), + rect); + TEST (@"Vertical line through", result); + + result = lineSegmentIntersectsRect ( + NSMakePoint (0.5f, 1.0f), + NSMakePoint (2.0f, 2.5f), + rect); + TEST (@"Cut top and left", result); + + result = lineSegmentIntersectsRect ( + NSMakePoint (2.0f, 0.5f), + NSMakePoint (0.5f, 2.0f), + rect); + TEST (@"Cut bottom and left", result); + + result = lineSegmentIntersectsRect ( + NSMakePoint (1.0f, 0.5f), + NSMakePoint (2.5f, 2.0f), + rect); + TEST (@"Cut bottom and right", result); + + result = lineSegmentIntersectsRect ( + NSMakePoint (0.0f, 1.0f), + NSMakePoint (2.0f, 3.0f), + rect); + TEST (@"Touch top left", result); + + result = lineSegmentIntersectsRect ( + NSMakePoint (1.0f, 0.0f), + NSMakePoint (3.0f, 2.0f), + rect); + TEST (@"Touch bottom right", result); + + result = lineSegmentIntersectsRect ( + NSMakePoint (1.0f, 0.0f), + NSMakePoint (1.0f, 3.0f), + rect); + TEST (@"Along left side", result); + + result = lineSegmentIntersectsRect ( + NSMakePoint (0.0f, 1.0f), + NSMakePoint (3.0f, 1.0f), + rect); + TEST (@"Along bottom side", result); + + endTestBlock(@"lineSegmentIntersectsRect"); + [pool drain]; +} + +struct line_bezier_test { + NSString *msg; + NSPoint lstart; + NSPoint lend; + NSPoint c0; + NSPoint c1; + NSPoint c2; + NSPoint c3; + BOOL expectedResult; + float expectedT; + NSPoint expectedIntersect; +}; + +static struct line_bezier_test line_bezier_tests[] = { + { + @"Outside box", + {0.0f, 0.0f}, + {1.0f, 0.0f}, + {0.0f, 1.0f}, + {0.0f, 2.0f}, + {1.0f, 2.0f}, + {1.0f, 1.0f}, + NO, + -1.0f, + {0.0f, 0.0f} + }, + { + @"Single intersect", + {100.0f, 20.0f}, + {195.0f, 255.0f}, + {93.0f, 163.0f}, + {40.0f, 30.0f}, + {270.0f, 115.0f}, + {219.0f, 178.0f}, + YES, + -0.4f, + {129.391693f, 92.705772f} + }, + { + @"Double intersect", + {100.0f, 20.0f}, + {195.0f, 255.0f}, + {93.0f, 163.0f}, + {40.0f, 30.0f}, + {270.0f, 115.0f}, + {154.0f, 212.0f}, + YES, + -0.909f, + {170.740646f,194.990021f} + }, + { + @"Near miss", + {100.0f, 20.0f}, + {195.0f, 255.0f}, + {93.0f, 163.0f}, + {40.0f, 30.0f}, + {176.0f, 100.0f}, + {154.0f, 212.0f}, + NO, + -1.0f, + {0.0f,0.0f} + } +}; +static unsigned int n_line_bezier_tests = sizeof (line_bezier_tests) / sizeof (line_bezier_tests[0]); + +void testLineSegmentIntersectsBezier() { + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + startTestBlock(@"lineSegmentIntersectsBezier"); + + for (unsigned int i = 0; i < n_line_bezier_tests; ++i) { + NSPoint intersect; + BOOL result = lineSegmentIntersectsBezier ( + line_bezier_tests[i].lstart, + line_bezier_tests[i].lend, + line_bezier_tests[i].c0, + line_bezier_tests[i].c1, + line_bezier_tests[i].c2, + line_bezier_tests[i].c3, + &intersect); + if (result) { + if (line_bezier_tests[i].expectedT < 0.0f) { + assertPointsEqual (line_bezier_tests[i].msg, intersect, line_bezier_tests[i].expectedIntersect); + } else { + assertPointsEqual (line_bezier_tests[i].msg, intersect, + bezierInterpolateFull (line_bezier_tests[i].expectedT, line_bezier_tests[i].c0, line_bezier_tests[i].c1, line_bezier_tests[i].c2, line_bezier_tests[i].c3)); + } + } else { + if (line_bezier_tests[i].expectedResult) + fail (line_bezier_tests[i].msg); + else + pass (line_bezier_tests[i].msg); + } + } + +BOOL lineSegmentIntersectsBezier (NSPoint lstart, NSPoint lend, NSPoint c0, NSPoint c1, NSPoint c2, NSPoint c3, NSPoint *result); + endTestBlock(@"lineSegmentIntersectsBezier"); + [pool drain]; +} + +struct exit_point_test { + NSString *msg; + NSPoint rayStart; + float angle; + NSRect rect; + NSPoint expected; +}; + +static struct exit_point_test exit_point_tests[] = { + { + @"0.0 rads", + {0.0f, 0.0f}, + 0.0f, + {{-1.0f, -1.0f}, {2.0f, 2.0f}}, + {1.0f, 0.0f} + }, + { + @"pi/2 rads", + {0.0f, 0.0f}, + M_PI / 2.0f, + {{-1.0f, -1.0f}, {2.0f, 2.0f}}, + {0.0f, 1.0f} + }, + { + @"-pi/2 rads", + {0.0f, 0.0f}, + -M_PI / 2.0f, + {{-1.0f, -1.0f}, {2.0f, 2.0f}}, + {0.0f, -1.0f} + }, + { + @"pi rads", + {0.0f, 0.0f}, + M_PI, + {{-1.0f, -1.0f}, {2.0f, 2.0f}}, + {-1.0f, 0.0f} + }, + { + @"-pi rads", + {0.0f, 0.0f}, + -M_PI, + {{-1.0f, -1.0f}, {2.0f, 2.0f}}, + {-1.0f, 0.0f} + }, + { + @"pi/4 rads", + {0.0f, 0.0f}, + M_PI / 4.0f, + {{-1.0f, -1.0f}, {2.0f, 2.0f}}, + {1.0f, 1.0f} + }, + { + @"3pi/4 rads", + {0.0f, 0.0f}, + (3.0f * M_PI) / 4.0f, + {{-1.0f, -1.0f}, {2.0f, 2.0f}}, + {-1.0f, 1.0f} + }, + { + @"-pi/4 rads", + {0.0f, 0.0f}, + -M_PI / 4.0f, + {{-1.0f, -1.0f}, {2.0f, 2.0f}}, + {1.0f, -1.0f} + }, + { + @"-3pi/4 rads", + {0.0f, 0.0f}, + (-3.0f * M_PI) / 4.0f, + {{-1.0f, -1.0f}, {2.0f, 2.0f}}, + {-1.0f, -1.0f} + }, + { + @"pi/8 rads", + {0.0f, 0.0f}, + M_PI / 8.0f, + {{-1.0f, -1.0f}, {2.0f, 2.0f}}, + {1.0f, 0.414213562373095f} + }, + { + @"3pi/8 rads", + {0.0f, 0.0f}, + 3.0f * M_PI / 8.0f, + {{-1.0f, -1.0f}, {2.0f, 2.0f}}, + {0.414213562373095f, 1.0f} + }, + { + @"-5pi/8 rads", + {0.0f, 0.0f}, + -5.0f * M_PI / 8.0f, + {{-1.0f, -1.0f}, {2.0f, 2.0f}}, + {-0.414213562373095f, -1.0f} + }, + { + @"-7pi/8 rads", + {0.0f, 0.0f}, + -7.0f * M_PI / 8.0f, + {{-1.0f, -1.0f}, {2.0f, 2.0f}}, + {-1.0f, -0.414213562373095f} + }, + { + @"pi/8 rads; origin (1,1)", + {1.0f, 1.0f}, + M_PI / 8.0f, + {{0.0f, 0.0f}, {2.0f, 2.0f}}, + {2.0f, 1.414213562373095f} + }, + { + @"7pi/8 rads; origin (-2,2)", + {-2.0f, 2.0f}, + 7.0f * M_PI / 8.0f, + {{-3.0f, 1.0f}, {2.0f, 2.0f}}, + {-3.0f, 2.414213562373095f} + }, + { + @"pi/8 rads; origin (1,1); SW of box", + {1.0f, 1.0f}, + M_PI / 8.0f, + {{1.0f, 1.0f}, {1.0f, 1.0f}}, + {2.0f, 1.414213562373095f} + }, + { + @"pi/8 rads; origin (1,1); SE of box", + {1.0f, 1.0f}, + M_PI / 8.0f, + {{0.0f, 1.0f}, {1.0f, 1.0f}}, + {1.0f, 1.0f} + }, + { + @"pi/8 rads; origin (1,1); NE of box", + {1.0f, 1.0f}, + M_PI / 8.0f, + {{0.0f, 1.0f}, {1.0f, 1.0f}}, + {1.0f, 1.0f} + }, + { + @"pi/8 rads; origin (1,1); NW of box", + {1.0f, 1.0f}, + M_PI / 8.0f, + {{1.0f, 0.0f}, {1.0f, 1.0f}}, + {1.0f, 1.0f} + }, + { + @"pi/8 rads; origin (1,1); N of box", + {1.0f, 1.0f}, + M_PI / 8.0f, + {{0.5f, 0.0f}, {1.0f, 1.0f}}, + {1.0f, 1.0f} + }, + { + @"7pi/8 rads; origin (1,1); N of box", + {1.0f, 1.0f}, + 7.0f * M_PI / 8.0f, + {{0.5f, 0.0f}, {1.0f, 1.0f}}, + {1.0f, 1.0f} + }, + { + @"-pi/8 rads; origin (1,1); S of box", + {1.0f, 1.0f}, + -M_PI / 8.0f, + {{0.5f, 1.0f}, {1.0f, 1.0f}}, + {1.0f, 1.0f} + }, + { + @"-pi/8 rads; origin (1,1); E of box", + {1.0f, 1.0f}, + -M_PI / 8.0f, + {{0.0f, 0.5f}, {1.0f, 1.0f}}, + {1.0f, 1.0f} + }, + { + @"-7pi/8 rads; origin (1,1); W of box", + {1.0f, 1.0f}, + -7.0f * M_PI / 8.0f, + {{1.0f, 0.5f}, {1.0f, 1.0f}}, + {1.0f, 1.0f} + }, + { + @"7pi/8 rads; origin (1,1); W of box", + {1.0f, 1.0f}, + 7.0f * M_PI / 8.0f, + {{1.0f, 0.5f}, {1.0f, 1.0f}}, + {1.0f, 1.0f} + }, + { + @"pi/8 rads; origin (1,1); leave through top", + {1.0f, 1.0f}, + M_PI / 8.0f, + {{0.9f, 0.1f}, {1.0f, 1.0f}}, + {1.2414213562373f, 1.1f} + }, + { + @"0 rads; origin (1,1); N of box", + {1.0f, 1.0f}, + 0.0f, + {{0.5f, 0.0f}, {1.0f, 1.0f}}, + {1.5f, 1.0f} + } +}; +static unsigned int n_exit_point_tests = sizeof (exit_point_tests) / sizeof (exit_point_tests[0]); + +void testFindExitPointOfRay() { + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + startTestBlock(@"findExitPointOfRay"); + + for (unsigned int i = 0; i < n_exit_point_tests; ++i) { + NSPoint exitPoint = findExitPointOfRay ( + exit_point_tests[i].rayStart, + exit_point_tests[i].angle, + exit_point_tests[i].rect); + assertPointsEqual (exit_point_tests[i].msg, exitPoint, exit_point_tests[i].expected); + } + + endTestBlock(@"findExitPointOfRay"); + [pool drain]; +} + +#ifdef STAND_ALONE +void runTests() { +#else +void testMaths() { +#endif + startTestBlock(@"maths"); + testRectAroundPoints(); + testRectAroundPointsWithPadding(); + testGoodAtan(); + testBezierInterpolate(); + testLineSegmentsIntersect(); + testLineSegmentIntersectsRect(); + testFindExitPointOfRay(); + testLineSegmentIntersectsBezier(); + endTestBlock(@"maths"); +} + +// vim:ft=objc:ts=4:sts=4:sw=4:noet -- cgit v1.2.3