xref: /haiku/src/apps/icon-o-matic/generic/support/support.cpp (revision 2222d0559df303a9846a2fad53741f8b20b14d7c)
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