@@ -460,11 +460,51 @@ double MapXCoordinate(double x, double xMin, double xMax, double xPixelMin, doub
460
460
return x ;
461
461
}
462
462
double MapXCoordinateAutoSettings (double x , RGBABitmapImage * image , double * xs , size_t xsLength ){
463
- return MapXCoordinate (x , GetMinimum (xs , xsLength ), GetMaximum (xs , xsLength ) - GetMinimum ( xs , xsLength ) , GetDefaultPaddingPercentage ()* ImageWidth (image ), (1.0 - GetDefaultPaddingPercentage ())* ImageWidth (image ));
463
+ return MapXCoordinate (x , GetMinimum (xs , xsLength ), GetMaximum (xs , xsLength ), GetDefaultPaddingPercentage ()* ImageWidth (image ), (1.0 - GetDefaultPaddingPercentage ())* ImageWidth (image ));
464
464
}
465
465
double MapYCoordinateAutoSettings (double y , RGBABitmapImage * image , double * ys , size_t ysLength ){
466
466
return MapYCoordinate (y , GetMinimum (ys , ysLength ), GetMaximum (ys , ysLength ), GetDefaultPaddingPercentage ()* ImageHeight (image ), (1.0 - GetDefaultPaddingPercentage ())* ImageHeight (image ));
467
467
}
468
+ double MapXCoordinateBasedOnSettings (double x , ScatterPlotSettings * settings ){
469
+ double xMin , xMax , xPadding , xPixelMin , xPixelMax ;
470
+ Rectangle * boundaries ;
471
+
472
+ boundaries = (Rectangle * )malloc (sizeof (Rectangle ));
473
+ ComputeBoundariesBasedOnSettings (settings , boundaries );
474
+ xMin = boundaries -> x1 ;
475
+ xMax = boundaries -> x2 ;
476
+
477
+ if (settings -> autoPadding ){
478
+ xPadding = floor (GetDefaultPaddingPercentage ()* settings -> width );
479
+ }else {
480
+ xPadding = settings -> xPadding ;
481
+ }
482
+
483
+ xPixelMin = xPadding ;
484
+ xPixelMax = settings -> width - xPadding ;
485
+
486
+ return MapXCoordinate (x , xMin , xMax , xPixelMin , xPixelMax );
487
+ }
488
+ double MapYCoordinateBasedOnSettings (double y , ScatterPlotSettings * settings ){
489
+ double yMin , yMax , yPadding , yPixelMin , yPixelMax ;
490
+ Rectangle * boundaries ;
491
+
492
+ boundaries = (Rectangle * )malloc (sizeof (Rectangle ));
493
+ ComputeBoundariesBasedOnSettings (settings , boundaries );
494
+ yMin = boundaries -> y1 ;
495
+ yMax = boundaries -> y2 ;
496
+
497
+ if (settings -> autoPadding ){
498
+ yPadding = floor (GetDefaultPaddingPercentage ()* settings -> height );
499
+ }else {
500
+ yPadding = settings -> yPadding ;
501
+ }
502
+
503
+ yPixelMin = yPadding ;
504
+ yPixelMax = settings -> height - yPadding ;
505
+
506
+ return MapYCoordinate (y , yMin , yMax , yPixelMin , yPixelMax );
507
+ }
468
508
double GetDefaultPaddingPercentage (){
469
509
return 0.10 ;
470
510
}
@@ -503,10 +543,10 @@ ScatterPlotSettings *GetDefaultScatterPlotSettings(){
503
543
settings -> yPadding = 0.0 ;
504
544
settings -> title = L"" ;
505
545
settings -> titleLength = wcslen (settings -> title );
506
- settings -> yLabel = L"" ;
507
- settings -> yLabelLength = wcslen (settings -> yLabel );
508
546
settings -> xLabel = L"" ;
509
547
settings -> xLabelLength = wcslen (settings -> xLabel );
548
+ settings -> yLabel = L"" ;
549
+ settings -> yLabelLength = wcslen (settings -> yLabel );
510
550
settings -> scatterPlotSeries = (ScatterPlotSeries * * )malloc (sizeof (ScatterPlotSeries ) * 0.0 );
511
551
settings -> scatterPlotSeriesLength = 0.0 ;
512
552
settings -> showGrid = true;
@@ -560,6 +600,7 @@ void DrawScatterPlot(RGBABitmapImageReference *canvasReference, double width, do
560
600
}
561
601
_Bool DrawScatterPlotFromSettings (RGBABitmapImageReference * canvasReference , ScatterPlotSettings * settings ){
562
602
double xMin , xMax , yMin , yMax , xLength , yLength , i , x , y , xPrev , yPrev , px , py , pxPrev , pyPrev , originX , originY , p , l , plot ;
603
+ Rectangle * boundaries ;
563
604
double xPadding , yPadding , originXPixels , originYPixels ;
564
605
double xPixelMin , yPixelMin , xPixelMax , yPixelMax , xLengthPixels , yLengthPixels , axisLabelPadding ;
565
606
NumberReference * nextRectangle , * x1Ref , * y1Ref , * x2Ref , * y2Ref , * patternOffset ;
@@ -588,53 +629,32 @@ _Bool DrawScatterPlotFromSettings(RGBABitmapImageReference *canvasReference, Sca
588
629
589
630
if (success ){
590
631
591
- if (settings -> scatterPlotSeriesLength >= 1.0 ){
592
- xMin = GetMinimum (settings -> scatterPlotSeries [0 ]-> xs , settings -> scatterPlotSeries [0 ]-> xsLength );
593
- xMax = GetMaximum (settings -> scatterPlotSeries [0 ]-> xs , settings -> scatterPlotSeries [0 ]-> xsLength );
594
- yMin = GetMinimum (settings -> scatterPlotSeries [0 ]-> ys , settings -> scatterPlotSeries [0 ]-> ysLength );
595
- yMax = GetMaximum (settings -> scatterPlotSeries [0 ]-> ys , settings -> scatterPlotSeries [0 ]-> ysLength );
596
- }else {
597
- xMin = -10.0 ;
598
- xMax = 10.0 ;
599
- yMin = -10.0 ;
600
- yMax = 10.0 ;
601
- }
602
-
603
- if ( !settings -> autoBoundaries ){
604
- xMin = settings -> xMin ;
605
- xMax = settings -> xMax ;
606
- yMin = settings -> yMin ;
607
- yMax = settings -> yMax ;
608
- }else {
609
- for (plot = 1.0 ; plot < settings -> scatterPlotSeriesLength ; plot = plot + 1.0 ){
610
- sp = settings -> scatterPlotSeries [(int )(plot )];
611
-
612
- xMin = fmin (xMin , GetMinimum (sp -> xs , sp -> xsLength ));
613
- xMax = fmax (xMax , GetMaximum (sp -> xs , sp -> xsLength ));
614
- yMin = fmin (yMin , GetMinimum (sp -> ys , sp -> ysLength ));
615
- yMax = fmax (yMax , GetMaximum (sp -> ys , sp -> ysLength ));
616
- }
617
- }
632
+ boundaries = (Rectangle * )malloc (sizeof (Rectangle ));
633
+ ComputeBoundariesBasedOnSettings (settings , boundaries );
634
+ xMin = boundaries -> x1 ;
635
+ yMin = boundaries -> y1 ;
636
+ xMax = boundaries -> x2 ;
637
+ yMax = boundaries -> y2 ;
618
638
619
639
xLength = xMax - xMin ;
620
640
yLength = yMax - yMin ;
621
641
622
642
if (settings -> autoPadding ){
623
- xPadding = floor (GetDefaultPaddingPercentage ()* ImageWidth ( canvas ) );
624
- yPadding = floor (GetDefaultPaddingPercentage ()* ImageHeight ( canvas ) );
643
+ xPadding = floor (GetDefaultPaddingPercentage ()* settings -> width );
644
+ yPadding = floor (GetDefaultPaddingPercentage ()* settings -> height );
625
645
}else {
626
646
xPadding = settings -> xPadding ;
627
647
yPadding = settings -> yPadding ;
628
648
}
629
649
630
650
/* Draw title */
631
- DrawText (canvas , floor (ImageWidth ( canvas ) /2.0 - GetTextWidth (settings -> title , settings -> titleLength )/2.0 ), floor (yPadding /3.0 ), settings -> title , settings -> titleLength , GetBlack ());
651
+ DrawText (canvas , floor (settings -> width /2.0 - GetTextWidth (settings -> title , settings -> titleLength )/2.0 ), floor (yPadding /3.0 ), settings -> title , settings -> titleLength , GetBlack ());
632
652
633
653
/* Draw grid */
634
654
xPixelMin = xPadding ;
635
655
yPixelMin = yPadding ;
636
- xPixelMax = ImageWidth ( canvas ) - xPadding ;
637
- yPixelMax = ImageHeight ( canvas ) - yPadding ;
656
+ xPixelMax = settings -> width - xPadding ;
657
+ yPixelMax = settings -> height - yPadding ;
638
658
xLengthPixels = xPixelMax - xPixelMin ;
639
659
yLengthPixels = yPixelMax - yPixelMin ;
640
660
DrawRectangle1px (canvas , xPixelMin , yPixelMin , xLengthPixels , yLengthPixels , settings -> gridColor );
@@ -755,8 +775,8 @@ if(settings->yAxisLeft){
755
775
}
756
776
757
777
/* Draw origin axis titles. */
758
- DrawTextUpwards (canvas , 10.0 , floor (originTextYPixels - GetTextWidth (settings -> xLabel , settings -> xLabelLength )/2.0 ), settings -> xLabel , settings -> xLabelLength , GetBlack ());
759
- DrawText (canvas , floor (originTextXPixels - GetTextWidth (settings -> yLabel , settings -> yLabelLength )/2.0 ), yPixelMax + axisLabelPadding , settings -> yLabel , settings -> yLabelLength , GetBlack ());
778
+ DrawTextUpwards (canvas , 10.0 , floor (originTextYPixels - GetTextWidth (settings -> yLabel , settings -> yLabelLength )/2.0 ), settings -> yLabel , settings -> yLabelLength , GetBlack ());
779
+ DrawText (canvas , floor (originTextXPixels - GetTextWidth (settings -> xLabel , settings -> xLabelLength )/2.0 ), yPixelMax + axisLabelPadding , settings -> xLabel , settings -> xLabelLength , GetBlack ());
760
780
761
781
/* X-grid-markers */
762
782
for (i = 0.0 ; i < xGridPositionsLength ; i = i + 1.0 ){
@@ -899,6 +919,43 @@ if(settings->yAxisLeft){
899
919
900
920
return success ;
901
921
}
922
+ void ComputeBoundariesBasedOnSettings (ScatterPlotSettings * settings , Rectangle * boundaries ){
923
+ ScatterPlotSeries * sp ;
924
+ double plot , xMin , xMax , yMin , yMax ;
925
+
926
+ if (settings -> scatterPlotSeriesLength >= 1.0 ){
927
+ xMin = GetMinimum (settings -> scatterPlotSeries [0 ]-> xs , settings -> scatterPlotSeries [0 ]-> xsLength );
928
+ xMax = GetMaximum (settings -> scatterPlotSeries [0 ]-> xs , settings -> scatterPlotSeries [0 ]-> xsLength );
929
+ yMin = GetMinimum (settings -> scatterPlotSeries [0 ]-> ys , settings -> scatterPlotSeries [0 ]-> ysLength );
930
+ yMax = GetMaximum (settings -> scatterPlotSeries [0 ]-> ys , settings -> scatterPlotSeries [0 ]-> ysLength );
931
+ }else {
932
+ xMin = -10.0 ;
933
+ xMax = 10.0 ;
934
+ yMin = -10.0 ;
935
+ yMax = 10.0 ;
936
+ }
937
+
938
+ if ( !settings -> autoBoundaries ){
939
+ xMin = settings -> xMin ;
940
+ xMax = settings -> xMax ;
941
+ yMin = settings -> yMin ;
942
+ yMax = settings -> yMax ;
943
+ }else {
944
+ for (plot = 1.0 ; plot < settings -> scatterPlotSeriesLength ; plot = plot + 1.0 ){
945
+ sp = settings -> scatterPlotSeries [(int )(plot )];
946
+
947
+ xMin = fmin (xMin , GetMinimum (sp -> xs , sp -> xsLength ));
948
+ xMax = fmax (xMax , GetMaximum (sp -> xs , sp -> xsLength ));
949
+ yMin = fmin (yMin , GetMinimum (sp -> ys , sp -> ysLength ));
950
+ yMax = fmax (yMax , GetMaximum (sp -> ys , sp -> ysLength ));
951
+ }
952
+ }
953
+
954
+ boundaries -> x1 = xMin ;
955
+ boundaries -> y1 = yMin ;
956
+ boundaries -> x2 = xMax ;
957
+ boundaries -> y2 = yMax ;
958
+ }
902
959
_Bool ScatterPlotFromSettingsValid (ScatterPlotSettings * settings ){
903
960
_Bool success , found ;
904
961
ScatterPlotSeries * series ;
@@ -1392,7 +1449,6 @@ double RoundToDigits(double element, double digitsAfterPoint){
1392
1449
return Round (element * pow (10.0 , digitsAfterPoint ))/pow (10.0 , digitsAfterPoint );
1393
1450
}
1394
1451
double test (){
1395
- ScatterPlotSettings * scatterPlotSettings ;
1396
1452
double z ;
1397
1453
double * gridlines ;
1398
1454
size_t gridlinesLength ;
@@ -1407,8 +1463,6 @@ double test(){
1407
1463
1408
1464
imageReference = CreateRGBABitmapImageReference ();
1409
1465
1410
- scatterPlotSettings = GetDefaultScatterPlotSettings ();
1411
-
1412
1466
labels = (StringArrayReference * )malloc (sizeof (StringArrayReference ));
1413
1467
labelPriorities = (NumberArrayReference * )malloc (sizeof (NumberArrayReference ));
1414
1468
@@ -1466,8 +1520,151 @@ double test(){
1466
1520
1467
1521
imageReference -> image = DrawBarPlot (800.0 , 600.0 , ys , ysLength );
1468
1522
1523
+ TestMapping (failures );
1524
+ TestMapping2 (failures );
1525
+
1469
1526
return failures -> numberValue ;
1470
1527
}
1528
+ void TestMapping (NumberReference * failures ){
1529
+ ScatterPlotSeries * series ;
1530
+ ScatterPlotSettings * settings ;
1531
+ RGBABitmapImageReference * imageReference ;
1532
+ double x1 , y1 ;
1533
+
1534
+ series = GetDefaultScatterPlotSeriesSettings ();
1535
+
1536
+ series -> xs = (double * )malloc (sizeof (double ) * (5.0 ));
1537
+ series -> xsLength = 5.0 ;
1538
+ series -> xs [0 ] = -2.0 ;
1539
+ series -> xs [1 ] = -1.0 ;
1540
+ series -> xs [2 ] = 0.0 ;
1541
+ series -> xs [3 ] = 1.0 ;
1542
+ series -> xs [4 ] = 2.0 ;
1543
+ series -> ys = (double * )malloc (sizeof (double ) * (5.0 ));
1544
+ series -> ysLength = 5.0 ;
1545
+ series -> ys [0 ] = -2.0 ;
1546
+ series -> ys [1 ] = -1.0 ;
1547
+ series -> ys [2 ] = -2.0 ;
1548
+ series -> ys [3 ] = -1.0 ;
1549
+ series -> ys [4 ] = 2.0 ;
1550
+ series -> linearInterpolation = true;
1551
+ series -> lineType = L"dashed" ;
1552
+ series -> lineTypeLength = wcslen (series -> lineType );
1553
+ series -> lineThickness = 2.0 ;
1554
+ series -> color = GetGray (0.3 );
1555
+
1556
+ settings = GetDefaultScatterPlotSettings ();
1557
+ settings -> width = 600.0 ;
1558
+ settings -> height = 400.0 ;
1559
+ settings -> autoBoundaries = true;
1560
+ settings -> autoPadding = true;
1561
+ settings -> title = L"x^2 - 2" ;
1562
+ settings -> titleLength = wcslen (settings -> title );
1563
+ settings -> xLabel = L"X axis" ;
1564
+ settings -> xLabelLength = wcslen (settings -> xLabel );
1565
+ settings -> yLabel = L"Y axis" ;
1566
+ settings -> yLabelLength = wcslen (settings -> yLabel );
1567
+ settings -> scatterPlotSeries = (ScatterPlotSeries * * )malloc (sizeof (ScatterPlotSeries ) * 1.0 );
1568
+ settings -> scatterPlotSeriesLength = 1.0 ;
1569
+ settings -> scatterPlotSeries [0 ] = series ;
1570
+
1571
+ imageReference = CreateRGBABitmapImageReference ();
1572
+ DrawScatterPlotFromSettings (imageReference , settings );
1573
+
1574
+ x1 = MapXCoordinateAutoSettings ( -1.0 , imageReference -> image , series -> xs , series -> xsLength );
1575
+ y1 = MapYCoordinateAutoSettings ( -1.0 , imageReference -> image , series -> ys , series -> ysLength );
1576
+
1577
+ AssertEquals (x1 , 180.0 , failures );
1578
+ AssertEquals (y1 , 280.0 , failures );
1579
+ }
1580
+ void TestMapping2 (NumberReference * failures ){
1581
+ double * xs , * ys , * xs2 , * ys2 ;
1582
+ size_t xsLength , ysLength , xs2Length , ys2Length ;
1583
+ double i , x , y , w , h , xMin , xMax , yMin , yMax ;
1584
+ RGBABitmapImageReference * canvasReference ;
1585
+ ScatterPlotSettings * settings ;
1586
+ double points ;
1587
+ double x1 , y1 ;
1588
+
1589
+ points = 300.0 ;
1590
+ w = 600.0 * 2.0 ;
1591
+ h = 300.0 * 2.0 ;
1592
+ xMin = 0.0 ;
1593
+ xMax = 150.0 ;
1594
+ yMin = 0.0 ;
1595
+ yMax = 1.0 ;
1596
+
1597
+ xs = (double * )malloc (sizeof (double ) * (points ));
1598
+ xsLength = points ;
1599
+ ys = (double * )malloc (sizeof (double ) * (points ));
1600
+ ysLength = points ;
1601
+ xs2 = (double * )malloc (sizeof (double ) * (points ));
1602
+ xs2Length = points ;
1603
+ ys2 = (double * )malloc (sizeof (double ) * (points ));
1604
+ ys2Length = points ;
1605
+
1606
+ for (i = 0.0 ; i < points ; i = i + 1.0 ){
1607
+ x = xMin + (xMax - xMin )/(points - 1.0 )* i ;
1608
+ /* points - 1d is to ensure both extremeties are included. */
1609
+ y = x /(x + 7.0 );
1610
+
1611
+ xs [(int )(i )] = x ;
1612
+ ys [(int )(i )] = y ;
1613
+
1614
+ y = 1.4 * x /(x + 7.0 )* (1.0 - (atan ((x /1.5 - 30.0 )/5.0 )/1.6 + 1.0 )/2.0 );
1615
+
1616
+ xs2 [(int )(i )] = x ;
1617
+ ys2 [(int )(i )] = y ;
1618
+ }
1619
+
1620
+ settings = GetDefaultScatterPlotSettings ();
1621
+
1622
+ settings -> scatterPlotSeries = (ScatterPlotSeries * * )malloc (sizeof (ScatterPlotSeries ) * 2.0 );
1623
+ settings -> scatterPlotSeriesLength = 2.0 ;
1624
+ settings -> scatterPlotSeries [0 ] = (ScatterPlotSeries * )malloc (sizeof (ScatterPlotSeries ));
1625
+ settings -> scatterPlotSeries [0 ]-> xs = xs ;
1626
+ settings -> scatterPlotSeries [0 ]-> xsLength = xsLength ;
1627
+ settings -> scatterPlotSeries [0 ]-> ys = ys ;
1628
+ settings -> scatterPlotSeries [0 ]-> ysLength = ysLength ;
1629
+ settings -> scatterPlotSeries [0 ]-> linearInterpolation = true;
1630
+ settings -> scatterPlotSeries [0 ]-> lineType = L"solid" ;
1631
+ settings -> scatterPlotSeries [0 ]-> lineTypeLength = wcslen (settings -> scatterPlotSeries [0 ]-> lineType );
1632
+ settings -> scatterPlotSeries [0 ]-> lineThickness = 3.0 ;
1633
+ settings -> scatterPlotSeries [0 ]-> color = CreateRGBColor (1.0 , 0.0 , 0.0 );
1634
+ settings -> scatterPlotSeries [1 ] = (ScatterPlotSeries * )malloc (sizeof (ScatterPlotSeries ));
1635
+ settings -> scatterPlotSeries [1 ]-> xs = xs2 ;
1636
+ settings -> scatterPlotSeries [1 ]-> xsLength = xs2Length ;
1637
+ settings -> scatterPlotSeries [1 ]-> ys = ys2 ;
1638
+ settings -> scatterPlotSeries [1 ]-> ysLength = ys2Length ;
1639
+ settings -> scatterPlotSeries [1 ]-> linearInterpolation = true;
1640
+ settings -> scatterPlotSeries [1 ]-> lineType = L"solid" ;
1641
+ settings -> scatterPlotSeries [1 ]-> lineTypeLength = wcslen (settings -> scatterPlotSeries [1 ]-> lineType );
1642
+ settings -> scatterPlotSeries [1 ]-> lineThickness = 3.0 ;
1643
+ settings -> scatterPlotSeries [1 ]-> color = CreateRGBColor (0.0 , 0.0 , 1.0 );
1644
+ settings -> autoBoundaries = false;
1645
+ settings -> xMin = xMin ;
1646
+ settings -> xMax = xMax ;
1647
+ settings -> yMin = yMin ;
1648
+ settings -> yMax = yMax ;
1649
+ settings -> yLabel = L"" ;
1650
+ settings -> yLabelLength = wcslen (settings -> yLabel );
1651
+ settings -> xLabel = L"Features" ;
1652
+ settings -> xLabelLength = wcslen (settings -> xLabel );
1653
+ settings -> title = L"" ;
1654
+ settings -> titleLength = wcslen (settings -> title );
1655
+ settings -> width = w ;
1656
+ settings -> height = h ;
1657
+
1658
+ canvasReference = CreateRGBABitmapImageReference ();
1659
+
1660
+ DrawScatterPlotFromSettings (canvasReference , settings );
1661
+
1662
+ x1 = MapXCoordinateBasedOnSettings (27.0 , settings );
1663
+ y1 = MapYCoordinateBasedOnSettings (1.0 , settings );
1664
+
1665
+ AssertEquals (floor (x1 ), 292.0 , failures );
1666
+ AssertEquals (y1 , 60.0 , failures );
1667
+ }
1471
1668
RGBA * GetBlack (){
1472
1669
RGBA * black ;
1473
1670
black = (RGBA * )malloc (sizeof (RGBA ));
0 commit comments