xref: /haiku/src/apps/icon-o-matic/generic/support/support.cpp (revision 302f62604763c95777d6d04cca456e876f471c4f)
1 /*
2  * Copyright 2006, 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 // point_line_distance
20 double
21 point_line_distance(double x1, double y1,
22 					double x2, double y2,
23 					double x,  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 // point_line_distance
31 double
32 point_line_distance(BPoint point, BPoint pa, BPoint pb)
33 {
34 	// first figure out if point is between segment start and end points
35 	double a = point_point_distance(point, pb);
36 	double b = point_point_distance(point, pa);
37 	double c = point_point_distance(pa, pb);
38 
39 	float currentDist = min_c(a, b);
40 
41 	if (a > 0.0 && b > 0.0) {
42 		double alpha = acos((b*b + c*c - a*a) / (2*b*c));
43 		double beta = acos((a*a + c*c - b*b) / (2*a*c));
44 
45 		if (alpha <= PI2 && beta <= PI2) {
46 			currentDist = fabs(point_line_distance(pa.x, pa.y, pb.x, pb.y,
47 												   point.x, point.y));
48 		}
49 	}
50 
51 	return currentDist;
52 }
53 
54 // calc_angle
55 double
56 calc_angle(BPoint origin, BPoint from, BPoint to, bool degree)
57 {
58 	double angle = 0.0;
59 
60 	double d = point_line_distance(from.x, from.y,
61 								   origin.x, origin.y,
62 								   to.x, to.y);
63 	if (d != 0.0) {
64 		double a = point_point_distance(from, to);
65 		double b = point_point_distance(from, origin);
66 		double c = point_point_distance(to, origin);
67 		if (a > 0.0 && b > 0.0 && c > 0.0) {
68 			angle = acos((b*b + c*c - a*a) / (2.0*b*c));
69 
70 			if (d < 0.0)
71 				angle = -angle;
72 
73 			if (degree)
74 				angle = angle * 180.0 / PI;
75 		}
76 	}
77 	return angle;
78 }
79 
80 // write_string
81 status_t
82 write_string(BPositionIO* stream, BString& string)
83 {
84 	if (!stream)
85 		return B_BAD_VALUE;
86 
87 	ssize_t written = stream->Write(string.String(), string.Length());
88 	if (written > B_OK && written < string.Length())
89 		written = B_ERROR;
90 	string.SetTo("");
91 	return written;
92 }
93 
94 // append_float
95 void
96 append_float(BString& string, float n, int32 maxDigits)
97 {
98 	int32 rounded = n >= 0.0 ? (int32)fabs(floorf(n)) : (int32)fabs(ceilf(n));
99 
100 	if (n < 0.0) {
101 		string << "-";
102 		n *= -1.0;
103 	}
104 	string << rounded;
105 
106 	if ((float)rounded != n) {
107 		// find out how many digits remain
108 		n = n - rounded;
109 		rounded = (int32)(n * pow(10, maxDigits));
110 		char tmp[maxDigits + 1];
111 		sprintf(tmp, "%0*ld", (int)maxDigits, rounded);
112 		tmp[maxDigits] = 0;
113 		int32 digits = strlen(tmp);
114 		for (int32 i = strlen(tmp) - 1; i >= 0; i--) {
115 			if (tmp[i] == '0')
116 				digits--;
117 			else
118 				break;
119 		}
120 		// write after decimal
121 		if (digits > 0) {
122 			string << ".";
123 			for (int32 i = 0; i < digits; i++) {
124 				string << tmp[i];
125 			}
126 		}
127 	}
128 }
129 
130 //// gauss
131 //double
132 //gauss(double f)
133 //{
134 //	// this aint' a real gauss function
135 ///*	if (f >= -1.0 && f <= 1.0) {
136 //		if (f < -0.5) {
137 //			f = -1.0 - f;
138 //			return (2.0 * f*f);
139 //		}
140 //
141 //		if (f < 0.5)
142 //			return (1.0 - 2.0 * f*f);
143 //
144 //		f = 1.0 - f;
145 //		return (2.0 * f*f);
146 //	}*/
147 //	if (f > 0.0) {
148 //		if (f < 0.5)
149 //			return (1.0 - 2.0 * f*f);
150 //
151 //		f = 1.0 - f;
152 //		return (2.0 * f*f);
153 //	}
154 //	return 1.0;
155 //}
156