Graphviz 14.1.3~dev.20260124.0732
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#include "config.h"
12
13#include <math.h>
14#include <pathplan/solvers.h>
15
16static int solve1(double *coeff, double *roots);
17static int solve2(double *coeff, double *roots);
18
19#ifndef M_PI
20#define M_PI 3.14159265358979323846
21#endif
22
23#define EPS 1E-7
24#define AEQ0(x) (((x) < EPS) && ((x) > -EPS))
25
26int solve3(double *coeff, double *roots)
27{
28 double a, b, c, d;
29 int rootn, i;
30 double p, q, disc, b_over_3a, c_over_a, d_over_a;
31 double r, theta, temp, alpha, beta;
32
33 a = coeff[3], b = coeff[2], c = coeff[1], d = coeff[0];
34 if (AEQ0(a))
35 return solve2(coeff, roots);
36 b_over_3a = b / (3 * a);
37 c_over_a = c / a;
38 d_over_a = d / a;
39
40 p = b_over_3a * b_over_3a;
41 q = 2 * b_over_3a * p - b_over_3a * c_over_a + d_over_a;
42 p = c_over_a / 3 - p;
43 disc = q * q + 4 * p * p * p;
44
45 if (disc < 0) {
46 r = .5 * sqrt(-disc + q * q);
47 theta = atan2(sqrt(-disc), -q);
48 temp = 2 * cbrt(r);
49 roots[0] = temp * cos(theta / 3);
50 roots[1] = temp * cos((theta + M_PI + M_PI) / 3);
51 roots[2] = temp * cos((theta - M_PI - M_PI) / 3);
52 rootn = 3;
53 } else {
54 alpha = .5 * (sqrt(disc) - q);
55 beta = -q - alpha;
56 roots[0] = cbrt(alpha) + cbrt(beta);
57 if (disc > 0)
58 rootn = 1;
59 else
60 roots[1] = roots[2] = -.5 * roots[0], rootn = 3;
61 }
62
63 for (i = 0; i < rootn; i++)
64 roots[i] -= b_over_3a;
65
66 return rootn;
67}
68
69static int solve2(double *coeff, double *roots)
70{
71 double a, b, c;
72 double disc, b_over_2a, c_over_a;
73
74 a = coeff[2], b = coeff[1], c = coeff[0];
75 if (AEQ0(a))
76 return solve1(coeff, roots);
77 b_over_2a = b / (2 * a);
78 c_over_a = c / a;
79
80 disc = b_over_2a * b_over_2a - c_over_a;
81 if (disc < 0) {
82 return 0;
83 } else if (disc > 0) {
84 roots[0] = -b_over_2a + sqrt(disc);
85 roots[1] = -2 * b_over_2a - roots[0];
86 return 2;
87 }
88 roots[0] = -b_over_2a;
89 return 1;
90}
91
92static int solve1(double *coeff, double *roots)
93{
94 double a, b;
95
96 a = coeff[1], b = coeff[0];
97 if (AEQ0(a)) {
98 if (AEQ0(b))
99 return 4;
100 else
101 return 0;
102 }
103 roots[0] = -b / a;
104 return 1;
105}
static Dtdisc_t disc
Definition exparse.y:209
#define alpha
Definition shapes.c:4058
static int solve1(double *coeff, double *roots)
Definition solvers.c:92
#define AEQ0(x)
Definition solvers.c:24
int solve3(double *coeff, double *roots)
Definition solvers.c:26
static int solve2(double *coeff, double *roots)
Definition solvers.c:69
#define M_PI
Definition solvers.c:20