1 /* 2 * Copyright 2006-2009, Haiku. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Stephan Aßmus <superstippi@gmx.de> 7 */ 8 9 #include "support.h" 10 11 #include <math.h> 12 #include <stdio.h> 13 #include <string.h> 14 15 #include <DataIO.h> 16 #include <Point.h> 17 #include <String.h> 18 19 20 // point_line_distance 21 double 22 point_line_distance(double x1, double y1, double x2, double y2, double x, 23 double y) 24 { 25 double dx = x2 - x1; 26 double dy = y2 - y1; 27 return ((x - x2) * dy - (y - y2) * dx) / sqrt(dx * dx + dy * dy); 28 } 29 30 31 // point_line_distance 32 double 33 point_line_distance(BPoint point, BPoint pa, BPoint pb) 34 { 35 // first figure out if point is between segment start and end points 36 double a = point_point_distance(point, pb); 37 double b = point_point_distance(point, pa); 38 double c = point_point_distance(pa, pb); 39 40 float currentDist = min_c(a, b); 41 42 if (a > 0.0 && b > 0.0) { 43 double alpha = acos((b*b + c*c - a*a) / (2*b*c)); 44 double beta = acos((a*a + c*c - b*b) / (2*a*c)); 45 46 if (alpha <= M_PI_2 && beta <= M_PI_2) { 47 currentDist = fabs(point_line_distance(pa.x, pa.y, pb.x, pb.y, 48 point.x, point.y)); 49 } 50 } 51 52 return currentDist; 53 } 54 55 56 // calc_angle 57 double 58 calc_angle(BPoint origin, BPoint from, BPoint to, bool degree) 59 { 60 double angle = 0.0; 61 62 double d = point_line_distance(from.x, from.y, origin.x, origin.y, 63 to.x, to.y); 64 if (d != 0.0) { 65 double a = point_point_distance(from, to); 66 double b = point_point_distance(from, origin); 67 double c = point_point_distance(to, origin); 68 if (a > 0.0 && b > 0.0 && c > 0.0) { 69 angle = acos((b*b + c*c - a*a) / (2.0*b*c)); 70 71 if (d < 0.0) 72 angle = -angle; 73 74 if (degree) 75 angle = angle * 180.0 / M_PI; 76 } 77 } 78 return angle; 79 } 80 81 82 // write_string 83 status_t 84 write_string(BPositionIO* stream, BString& string) 85 { 86 if (!stream) 87 return B_BAD_VALUE; 88 89 ssize_t written = stream->Write(string.String(), string.Length()); 90 if (written > B_OK && written < string.Length()) 91 written = B_ERROR; 92 string.SetTo(""); 93 return written; 94 } 95 96 97 // append_float 98 void 99 append_float(BString& string, float n, int32 maxDigits) 100 { 101 int32 rounded = n >= 0.0 ? (int32)fabs(floorf(n)) : (int32)fabs(ceilf(n)); 102 103 if (n < 0.0) { 104 string << "-"; 105 n *= -1.0; 106 } 107 string << rounded; 108 109 if ((float)rounded != n) { 110 // find out how many digits remain 111 n = n - rounded; 112 rounded = (int32)(n * pow(10, maxDigits)); 113 char tmp[maxDigits + 1]; 114 sprintf(tmp, "%0*ld", (int)maxDigits, rounded); 115 tmp[maxDigits] = 0; 116 int32 digits = strlen(tmp); 117 for (int32 i = strlen(tmp) - 1; i >= 0; i--) { 118 if (tmp[i] == '0') 119 digits--; 120 else 121 break; 122 } 123 // write after decimal 124 if (digits > 0) { 125 string << "."; 126 for (int32 i = 0; i < digits; i++) { 127 string << tmp[i]; 128 } 129 } 130 } 131 } 132 133 134 //// gauss 135 //double 136 //gauss(double f) 137 //{ 138 // // this aint' a real gauss function 139 ///* if (f >= -1.0 && f <= 1.0) { 140 // if (f < -0.5) { 141 // f = -1.0 - f; 142 // return (2.0 * f*f); 143 // } 144 // 145 // if (f < 0.5) 146 // return (1.0 - 2.0 * f*f); 147 // 148 // f = 1.0 - f; 149 // return (2.0 * f*f); 150 // }*/ 151 // if (f > 0.0) { 152 // if (f < 0.5) 153 // return (1.0 - 2.0 * f*f); 154 // 155 // f = 1.0 - f; 156 // return (2.0 * f*f); 157 // } 158 // return 1.0; 159 //} 160