Graphviz 13.0.0~dev.20241220.2304
Loading...
Searching...
No Matches
solvers.c
Go to the documentation of this file.
1/*************************************************************************
2 * Copyright (c) 2011 AT&T Intellectual Property
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * https://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors: Details at https://graphviz.org
9 *************************************************************************/
10
11
12#include <math.h>
13#include <pathplan/solvers.h>
14
15static int solve1(double *coeff, double *roots);
16static int solve2(double *coeff, double *roots);
17
18#ifndef M_PI
19#define M_PI 3.14159265358979323846
20#endif
21
22#define EPS 1E-7
23#define AEQ0(x) (((x) < EPS) && ((x) > -EPS))
24
25int solve3(double *coeff, double *roots)
26{
27 double a, b, c, d;
28 int rootn, i;
29 double p, q, disc, b_over_3a, c_over_a, d_over_a;
30 double r, theta, temp, alpha, beta;
31
32 a = coeff[3], b = coeff[2], c = coeff[1], d = coeff[0];
33 if (AEQ0(a))
34 return solve2(coeff, roots);
35 b_over_3a = b / (3 * a);
36 c_over_a = c / a;
37 d_over_a = d / a;
38
39 p = b_over_3a * b_over_3a;
40 q = 2 * b_over_3a * p - b_over_3a * c_over_a + d_over_a;
41 p = c_over_a / 3 - p;
42 disc = q * q + 4 * p * p * p;
43
44 if (disc < 0) {
45 r = .5 * sqrt(-disc + q * q);
46 theta = atan2(sqrt(-disc), -q);
47 temp = 2 * cbrt(r);
48 roots[0] = temp * cos(theta / 3);
49 roots[1] = temp * cos((theta + M_PI + M_PI) / 3);
50 roots[2] = temp * cos((theta - M_PI - M_PI) / 3);
51 rootn = 3;
52 } else {
53 alpha = .5 * (sqrt(disc) - q);
54 beta = -q - alpha;
55 roots[0] = cbrt(alpha) + cbrt(beta);
56 if (disc > 0)
57 rootn = 1;
58 else
59 roots[1] = roots[2] = -.5 * roots[0], rootn = 3;
60 }
61
62 for (i = 0; i < rootn; i++)
63 roots[i] -= b_over_3a;
64
65 return rootn;
66}
67
68static int solve2(double *coeff, double *roots)
69{
70 double a, b, c;
71 double disc, b_over_2a, c_over_a;
72
73 a = coeff[2], b = coeff[1], c = coeff[0];
74 if (AEQ0(a))
75 return solve1(coeff, roots);
76 b_over_2a = b / (2 * a);
77 c_over_a = c / a;
78
79 disc = b_over_2a * b_over_2a - c_over_a;
80 if (disc < 0) {
81 return 0;
82 } else if (disc > 0) {
83 roots[0] = -b_over_2a + sqrt(disc);
84 roots[1] = -2 * b_over_2a - roots[0];
85 return 2;
86 }
87 roots[0] = -b_over_2a;
88 return 1;
89}
90
91static int solve1(double *coeff, double *roots)
92{
93 double a, b;
94
95 a = coeff[1], b = coeff[0];
96 if (AEQ0(a)) {
97 if (AEQ0(b))
98 return 4;
99 else
100 return 0;
101 }
102 roots[0] = -b / a;
103 return 1;
104}
static Dtdisc_t disc
Definition exparse.y:209
#define alpha
Definition shapes.c:4058
static int solve1(double *coeff, double *roots)
Definition solvers.c:91
#define AEQ0(x)
Definition solvers.c:23
int solve3(double *coeff, double *roots)
Definition solvers.c:25
static int solve2(double *coeff, double *roots)
Definition solvers.c:68
#define M_PI
Definition solvers.c:19