1128277c9SStephan Aßmus/*
27f5bbbdcSAxel Dörfler * Copyright 2006-2009, 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
197f5bbbdcSAxel Dörfler
20128277c9SStephan Aßmus// point_line_distance
21128277c9SStephan Aßmusdouble
227f5bbbdcSAxel Dörflerpoint_line_distance(double x1, double y1, double x2, double y2, double x,
237f5bbbdcSAxel Dörfler	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
307f5bbbdcSAxel Dörfler
31128277c9SStephan Aßmus// point_line_distance
32128277c9SStephan Aßmusdouble
33128277c9SStephan Aßmuspoint_line_distance(BPoint point, BPoint pa, BPoint pb)
34128277c9SStephan Aßmus{
35128277c9SStephan Aßmus	// first figure out if point is between segment start and end points
36128277c9SStephan Aßmus	double a = point_point_distance(point, pb);
37128277c9SStephan Aßmus	double b = point_point_distance(point, pa);
38128277c9SStephan Aßmus	double c = point_point_distance(pa, pb);
39128277c9SStephan Aßmus
40128277c9SStephan Aßmus	float currentDist = min_c(a, b);
41128277c9SStephan Aßmus
42128277c9SStephan Aßmus	if (a > 0.0 && b > 0.0) {
43128277c9SStephan Aßmus		double alpha = acos((b*b + c*c - a*a) / (2*b*c));
44128277c9SStephan Aßmus		double beta = acos((a*a + c*c - b*b) / (2*a*c));
45128277c9SStephan Aßmus
467f5bbbdcSAxel Dörfler		if (alpha <= M_PI_2 && beta <= M_PI_2) {
47128277c9SStephan Aßmus			currentDist = fabs(point_line_distance(pa.x, pa.y, pb.x, pb.y,
487f5bbbdcSAxel Dörfler				point.x, point.y));
49128277c9SStephan Aßmus		}
50128277c9SStephan Aßmus	}
51128277c9SStephan Aßmus
52128277c9SStephan Aßmus	return currentDist;
53128277c9SStephan Aßmus}
54128277c9SStephan Aßmus
557f5bbbdcSAxel Dörfler
56128277c9SStephan Aßmus// calc_angle
57128277c9SStephan Aßmusdouble
58128277c9SStephan Aßmuscalc_angle(BPoint origin, BPoint from, BPoint to, bool degree)
59128277c9SStephan Aßmus{
60128277c9SStephan Aßmus	double angle = 0.0;
61128277c9SStephan Aßmus
627f5bbbdcSAxel Dörfler	double d = point_line_distance(from.x, from.y, origin.x, origin.y,
637f5bbbdcSAxel Dörfler		to.x, to.y);
64128277c9SStephan Aßmus	if (d != 0.0) {
65128277c9SStephan Aßmus		double a = point_point_distance(from, to);
66128277c9SStephan Aßmus		double b = point_point_distance(from, origin);
67128277c9SStephan Aßmus		double c = point_point_distance(to, origin);
68128277c9SStephan Aßmus		if (a > 0.0 && b > 0.0 && c > 0.0) {
69128277c9SStephan Aßmus			angle = acos((b*b + c*c - a*a) / (2.0*b*c));
707f5bbbdcSAxel Dörfler
71128277c9SStephan Aßmus			if (d < 0.0)
72128277c9SStephan Aßmus				angle = -angle;
73128277c9SStephan Aßmus
74128277c9SStephan Aßmus			if (degree)
757f5bbbdcSAxel Dörfler				angle = angle * 180.0 / M_PI;
76128277c9SStephan Aßmus		}
77128277c9SStephan Aßmus	}
78128277c9SStephan Aßmus	return angle;
79128277c9SStephan Aßmus}
80128277c9SStephan Aßmus
817f5bbbdcSAxel Dörfler
82128277c9SStephan Aßmus// write_string
83128277c9SStephan Aßmusstatus_t
84128277c9SStephan Aßmuswrite_string(BPositionIO* stream, BString& string)
85128277c9SStephan Aßmus{
86128277c9SStephan Aßmus	if (!stream)
87128277c9SStephan Aßmus		return B_BAD_VALUE;
88128277c9SStephan Aßmus
89128277c9SStephan Aßmus	ssize_t written = stream->Write(string.String(), string.Length());
90128277c9SStephan Aßmus	if (written > B_OK && written < string.Length())
91128277c9SStephan Aßmus		written = B_ERROR;
92128277c9SStephan Aßmus	string.SetTo("");
93128277c9SStephan Aßmus	return written;
94128277c9SStephan Aßmus}
95128277c9SStephan Aßmus
967f5bbbdcSAxel Dörfler
97128277c9SStephan Aßmus// append_float
98128277c9SStephan Aßmusvoid
993ec18e87SMarcus Overhagenappend_float(BString& string, float n, int32 maxDigits)
100128277c9SStephan Aßmus{
101128277c9SStephan Aßmus	int32 rounded = n >= 0.0 ? (int32)fabs(floorf(n)) : (int32)fabs(ceilf(n));
102128277c9SStephan Aßmus
103128277c9SStephan Aßmus	if (n < 0.0) {
104128277c9SStephan Aßmus		string << "-";
105128277c9SStephan Aßmus		n *= -1.0;
106128277c9SStephan Aßmus	}
107128277c9SStephan Aßmus	string << rounded;
108128277c9SStephan Aßmus
109128277c9SStephan Aßmus	if ((float)rounded != n) {
110128277c9SStephan Aßmus		// find out how many digits remain
111128277c9SStephan Aßmus		n = n - rounded;
112128277c9SStephan Aßmus		rounded = (int32)(n * pow(10, maxDigits));
113128277c9SStephan Aßmus		char tmp[maxDigits + 1];
11460128b54SJérôme Duval		sprintf(tmp, "%0*" B_PRId32, (int)maxDigits, rounded);
115128277c9SStephan Aßmus		tmp[maxDigits] = 0;
116128277c9SStephan Aßmus		int32 digits = strlen(tmp);
117128277c9SStephan Aßmus		for (int32 i = strlen(tmp) - 1; i >= 0; i--) {
118128277c9SStephan Aßmus			if (tmp[i] == '0')
119128277c9SStephan Aßmus				digits--;
120128277c9SStephan Aßmus			else
121128277c9SStephan Aßmus				break;
122128277c9SStephan Aßmus		}
123128277c9SStephan Aßmus		// write after decimal
124128277c9SStephan Aßmus		if (digits > 0) {
125128277c9SStephan Aßmus			string << ".";
126128277c9SStephan Aßmus			for (int32 i = 0; i < digits; i++) {
127128277c9SStephan Aßmus				string << tmp[i];
128128277c9SStephan Aßmus			}
129128277c9SStephan Aßmus		}
130128277c9SStephan Aßmus	}
131128277c9SStephan Aßmus}
132128277c9SStephan Aßmus
1337f5bbbdcSAxel Dörfler
1340e1ba39fSStephan Aßmus//// gauss
1350e1ba39fSStephan Aßmus//double
1360e1ba39fSStephan Aßmus//gauss(double f)
1377f5bbbdcSAxel Dörfler//{
1380e1ba39fSStephan Aßmus//	// this aint' a real gauss function
1390e1ba39fSStephan Aßmus///*	if (f >= -1.0 && f <= 1.0) {
1400e1ba39fSStephan Aßmus//		if (f < -0.5) {
1410e1ba39fSStephan Aßmus//			f = -1.0 - f;
1420e1ba39fSStephan Aßmus//			return (2.0 * f*f);
1430e1ba39fSStephan Aßmus//		}
1440e1ba39fSStephan Aßmus//
1450e1ba39fSStephan Aßmus//		if (f < 0.5)
1460e1ba39fSStephan Aßmus//			return (1.0 - 2.0 * f*f);
1470e1ba39fSStephan Aßmus//
1480e1ba39fSStephan Aßmus//		f = 1.0 - f;
1490e1ba39fSStephan Aßmus//		return (2.0 * f*f);
1500e1ba39fSStephan Aßmus//	}*/
1510e1ba39fSStephan Aßmus//	if (f > 0.0) {
1520e1ba39fSStephan Aßmus//		if (f < 0.5)
1530e1ba39fSStephan Aßmus//			return (1.0 - 2.0 * f*f);
1540e1ba39fSStephan Aßmus//
1550e1ba39fSStephan Aßmus//		f = 1.0 - f;
1560e1ba39fSStephan Aßmus//		return (2.0 * f*f);
1570e1ba39fSStephan Aßmus//	}
1580e1ba39fSStephan Aßmus//	return 1.0;
1590e1ba39fSStephan Aßmus//}
160