xref: /haiku/src/apps/icon-o-matic/generic/support/support.cpp (revision 0e1ba39f0440e200e30b6a648e70c3e8683dc5f7)
1128277c9SStephan Aßmus /*
2128277c9SStephan Aßmus  * Copyright 2006, Haiku.
3128277c9SStephan Aßmus  * Distributed under the terms of the MIT License.
4128277c9SStephan Aßmus  *
5128277c9SStephan Aßmus  * Authors:
6128277c9SStephan Aßmus  *		Stephan Aßmus <superstippi@gmx.de>
7128277c9SStephan Aßmus  */
8128277c9SStephan Aßmus 
9128277c9SStephan Aßmus #include "support.h"
10128277c9SStephan Aßmus 
11128277c9SStephan Aßmus #include <math.h>
12128277c9SStephan Aßmus #include <stdio.h>
13128277c9SStephan Aßmus #include <string.h>
14128277c9SStephan Aßmus 
15128277c9SStephan Aßmus #include <DataIO.h>
16128277c9SStephan Aßmus #include <Point.h>
17128277c9SStephan Aßmus #include <String.h>
18128277c9SStephan Aßmus 
19128277c9SStephan Aßmus // point_line_distance
20128277c9SStephan Aßmus double
21128277c9SStephan Aßmus point_line_distance(double x1, double y1,
22128277c9SStephan Aßmus 					double x2, double y2,
23128277c9SStephan Aßmus 					double x,  double y)
24128277c9SStephan Aßmus {
25128277c9SStephan Aßmus 	double dx = x2 - x1;
26128277c9SStephan Aßmus 	double dy = y2 - y1;
27128277c9SStephan Aßmus 	return ((x - x2) * dy - (y - y2) * dx) / sqrt(dx * dx + dy * dy);
28128277c9SStephan Aßmus }
29128277c9SStephan Aßmus 
30128277c9SStephan Aßmus // point_line_distance
31128277c9SStephan Aßmus double
32128277c9SStephan Aßmus point_line_distance(BPoint point, BPoint pa, BPoint pb)
33128277c9SStephan Aßmus {
34128277c9SStephan Aßmus 	// first figure out if point is between segment start and end points
35128277c9SStephan Aßmus 	double a = point_point_distance(point, pb);
36128277c9SStephan Aßmus 	double b = point_point_distance(point, pa);
37128277c9SStephan Aßmus 	double c = point_point_distance(pa, pb);
38128277c9SStephan Aßmus 
39128277c9SStephan Aßmus 	float currentDist = min_c(a, b);
40128277c9SStephan Aßmus 
41128277c9SStephan Aßmus 	if (a > 0.0 && b > 0.0) {
42128277c9SStephan Aßmus 		double alpha = acos((b*b + c*c - a*a) / (2*b*c));
43128277c9SStephan Aßmus 		double beta = acos((a*a + c*c - b*b) / (2*a*c));
44128277c9SStephan Aßmus 
45128277c9SStephan Aßmus 		if (alpha <= PI2 && beta <= PI2) {
46128277c9SStephan Aßmus 			currentDist = fabs(point_line_distance(pa.x, pa.y, pb.x, pb.y,
47128277c9SStephan Aßmus 												   point.x, point.y));
48128277c9SStephan Aßmus 		}
49128277c9SStephan Aßmus 	}
50128277c9SStephan Aßmus 
51128277c9SStephan Aßmus 	return currentDist;
52128277c9SStephan Aßmus }
53128277c9SStephan Aßmus 
54128277c9SStephan Aßmus // calc_angle
55128277c9SStephan Aßmus double
56128277c9SStephan Aßmus calc_angle(BPoint origin, BPoint from, BPoint to, bool degree)
57128277c9SStephan Aßmus {
58128277c9SStephan Aßmus 	double angle = 0.0;
59128277c9SStephan Aßmus 
60128277c9SStephan Aßmus 	double d = point_line_distance(from.x, from.y,
61128277c9SStephan Aßmus 								   origin.x, origin.y,
62128277c9SStephan Aßmus 								   to.x, to.y);
63128277c9SStephan Aßmus 	if (d != 0.0) {
64128277c9SStephan Aßmus 		double a = point_point_distance(from, to);
65128277c9SStephan Aßmus 		double b = point_point_distance(from, origin);
66128277c9SStephan Aßmus 		double c = point_point_distance(to, origin);
67128277c9SStephan Aßmus 		if (a > 0.0 && b > 0.0 && c > 0.0) {
68128277c9SStephan Aßmus 			angle = acos((b*b + c*c - a*a) / (2.0*b*c));
69128277c9SStephan Aßmus 
70128277c9SStephan Aßmus 			if (d < 0.0)
71128277c9SStephan Aßmus 				angle = -angle;
72128277c9SStephan Aßmus 
73128277c9SStephan Aßmus 			if (degree)
74128277c9SStephan Aßmus 				angle = angle * 180.0 / PI;
75128277c9SStephan Aßmus 		}
76128277c9SStephan Aßmus 	}
77128277c9SStephan Aßmus 	return angle;
78128277c9SStephan Aßmus }
79128277c9SStephan Aßmus 
80128277c9SStephan Aßmus // write_string
81128277c9SStephan Aßmus status_t
82128277c9SStephan Aßmus write_string(BPositionIO* stream, BString& string)
83128277c9SStephan Aßmus {
84128277c9SStephan Aßmus 	if (!stream)
85128277c9SStephan Aßmus 		return B_BAD_VALUE;
86128277c9SStephan Aßmus 
87128277c9SStephan Aßmus 	ssize_t written = stream->Write(string.String(), string.Length());
88128277c9SStephan Aßmus 	if (written > B_OK && written < string.Length())
89128277c9SStephan Aßmus 		written = B_ERROR;
90128277c9SStephan Aßmus 	string.SetTo("");
91128277c9SStephan Aßmus 	return written;
92128277c9SStephan Aßmus }
93128277c9SStephan Aßmus 
94128277c9SStephan Aßmus // append_float
95128277c9SStephan Aßmus void
96128277c9SStephan Aßmus append_float(BString& string, float n, int32 maxDigits = 4)
97128277c9SStephan Aßmus {
98128277c9SStephan Aßmus 	int32 rounded = n >= 0.0 ? (int32)fabs(floorf(n)) : (int32)fabs(ceilf(n));
99128277c9SStephan Aßmus 
100128277c9SStephan Aßmus 	if (n < 0.0) {
101128277c9SStephan Aßmus 		string << "-";
102128277c9SStephan Aßmus 		n *= -1.0;
103128277c9SStephan Aßmus 	}
104128277c9SStephan Aßmus 	string << rounded;
105128277c9SStephan Aßmus 
106128277c9SStephan Aßmus 	if ((float)rounded != n) {
107128277c9SStephan Aßmus 		// find out how many digits remain
108128277c9SStephan Aßmus 		n = n - rounded;
109128277c9SStephan Aßmus 		rounded = (int32)(n * pow(10, maxDigits));
110128277c9SStephan Aßmus 		char tmp[maxDigits + 1];
111128277c9SStephan Aßmus 		sprintf(tmp, "%0*ld", (int)maxDigits, rounded);
112128277c9SStephan Aßmus 		tmp[maxDigits] = 0;
113128277c9SStephan Aßmus 		int32 digits = strlen(tmp);
114128277c9SStephan Aßmus 		for (int32 i = strlen(tmp) - 1; i >= 0; i--) {
115128277c9SStephan Aßmus 			if (tmp[i] == '0')
116128277c9SStephan Aßmus 				digits--;
117128277c9SStephan Aßmus 			else
118128277c9SStephan Aßmus 				break;
119128277c9SStephan Aßmus 		}
120128277c9SStephan Aßmus 		// write after decimal
121128277c9SStephan Aßmus 		if (digits > 0) {
122128277c9SStephan Aßmus 			string << ".";
123128277c9SStephan Aßmus 			for (int32 i = 0; i < digits; i++) {
124128277c9SStephan Aßmus 				string << tmp[i];
125128277c9SStephan Aßmus 			}
126128277c9SStephan Aßmus 		}
127128277c9SStephan Aßmus 	}
128128277c9SStephan Aßmus }
129128277c9SStephan Aßmus 
130*0e1ba39fSStephan Aßmus //// gauss
131*0e1ba39fSStephan Aßmus //double
132*0e1ba39fSStephan Aßmus //gauss(double f)
133*0e1ba39fSStephan Aßmus //{
134*0e1ba39fSStephan Aßmus //	// this aint' a real gauss function
135*0e1ba39fSStephan Aßmus ///*	if (f >= -1.0 && f <= 1.0) {
136*0e1ba39fSStephan Aßmus //		if (f < -0.5) {
137*0e1ba39fSStephan Aßmus //			f = -1.0 - f;
138*0e1ba39fSStephan Aßmus //			return (2.0 * f*f);
139*0e1ba39fSStephan Aßmus //		}
140*0e1ba39fSStephan Aßmus //
141*0e1ba39fSStephan Aßmus //		if (f < 0.5)
142*0e1ba39fSStephan Aßmus //			return (1.0 - 2.0 * f*f);
143*0e1ba39fSStephan Aßmus //
144*0e1ba39fSStephan Aßmus //		f = 1.0 - f;
145*0e1ba39fSStephan Aßmus //		return (2.0 * f*f);
146*0e1ba39fSStephan Aßmus //	}*/
147*0e1ba39fSStephan Aßmus //	if (f > 0.0) {
148*0e1ba39fSStephan Aßmus //		if (f < 0.5)
149*0e1ba39fSStephan Aßmus //			return (1.0 - 2.0 * f*f);
150*0e1ba39fSStephan Aßmus //
151*0e1ba39fSStephan Aßmus //		f = 1.0 - f;
152*0e1ba39fSStephan Aßmus //		return (2.0 * f*f);
153*0e1ba39fSStephan Aßmus //	}
154*0e1ba39fSStephan Aßmus //	return 1.0;
155*0e1ba39fSStephan Aßmus //}
156