Skip to content

Commit 1d6e72b

Browse files
author
david
committed
re-added removed code
1 parent 65880e1 commit 1d6e72b

File tree

2 files changed

+227
-20
lines changed

2 files changed

+227
-20
lines changed

src/main/java/net/onelitefeather/bettergopaint/utils/curve/BezierSpline.java

Lines changed: 132 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,17 +20,27 @@
2020

2121

2222
import org.bukkit.Location;
23+
import org.bukkit.World;
24+
import org.bukkit.util.Vector;
25+
import org.jetbrains.annotations.NotNull;
26+
import org.jetbrains.annotations.Nullable;
2327

2428
import java.util.LinkedList;
2529

2630
public class BezierSpline {
2731

28-
private final LinkedList<Location> knotsList;
32+
private final @NotNull LinkedList<Location> knotsList;
2933
private Location[] knots;
30-
private BezierSplineSegment[] segments;
31-
private double length;
34+
private @NotNull BezierSplineSegment[] segments;
35+
private double length = 0;
36+
private Location anchorPoint;
3237

33-
public BezierSpline(LinkedList<Location> knotsList) {
38+
public BezierSpline() {
39+
knotsList = new LinkedList<>();
40+
segments = new BezierSplineSegment[0];
41+
}
42+
43+
public BezierSpline(@NotNull LinkedList<Location> knotsList) {
3444
this.knotsList = knotsList;
3545
recalculate();
3646
}
@@ -45,6 +55,18 @@ private void recalculate() {
4555
calculateLength();
4656
}
4757

58+
public void addKnot(@NotNull Location location) {
59+
knotsList.add(location);
60+
recalculate();
61+
}
62+
63+
public void removeKnot(int n) {
64+
if (n < knots.length) {
65+
knotsList.remove(n);
66+
recalculate();
67+
}
68+
}
69+
4870
public double getCurveLength() {
4971
return length;
5072
}
@@ -57,21 +79,76 @@ public void calculateLength() {
5779
}
5880
}
5981

60-
public Location getPoint(double point) {
82+
public int getSegmentsCount() {
83+
return segments.length;
84+
}
85+
86+
public BezierSplineSegment getCurveSegment(int n) {
87+
assert (n < segments.length);
88+
return segments[n];
89+
}
90+
91+
public double getT(double blocks) {
92+
if (length == 0) {
93+
calculateLength();
94+
}
95+
96+
assert (blocks >= 0);
97+
assert (blocks <= length);
98+
if (blocks == 0) {
99+
return 0;
100+
}
101+
if (blocks == length) {
102+
return segments.length;
103+
}
104+
double current = 0;
105+
int i = 0;
106+
107+
for (i = 0; i < segments.length; ++i) {
108+
current += segments[i].getCurveLength();
109+
if (current > blocks) {
110+
current -= segments[i].getCurveLength();
111+
break;
112+
}
113+
}
114+
if (i >= segments.length) {
115+
return segments.length;
116+
}
117+
return i + segments[i].getT(blocks - current);
118+
}
119+
120+
public @NotNull Location getPoint(double point) {
61121
if (point >= segments.length) {
62122
return getPoint(segments.length - 1, 1);
63123
} else {
64124
return getPoint((int) Math.floor(point), point - Math.floor(point));
65125
}
66126
}
67127

68-
public Location getPoint(int n, double f) {
128+
public @NotNull Location getPoint(int n, double f) {
69129
assert (n < segments.length);
70130
assert (0 <= f && f <= 1);
71131
BezierSplineSegment segment = segments[n];
72132
return segment.getPoint(f);
73133
}
74134

135+
public double getdTdS(double f) {
136+
if (f >= segments.length) {
137+
return segments[segments.length - 1].getdTdS(1);
138+
} else {
139+
return segments[(int) Math.floor(f)].getdTdS(f - Math.floor(f));
140+
}
141+
}
142+
143+
public double getHAngle(double f) {
144+
assert (f <= segments.length);
145+
if (f >= segments.length) {
146+
return segments[segments.length - 1].getHAngle(1);
147+
} else {
148+
return segments[(int) Math.floor(f)].getHAngle(f - Math.floor(f));
149+
}
150+
}
151+
75152
public void calculateControlPoints() {
76153
/*
77154
* Do not touch.
@@ -209,6 +286,43 @@ public void calculateControlPoints() {
209286
}
210287
}
211288

289+
public void shift(@NotNull Vector vector) {
290+
for (Location location : knotsList) {
291+
location.add(vector);
292+
}
293+
recalculate();
294+
}
295+
296+
public void scale(double d) {
297+
for (Location l : knotsList) {
298+
l.subtract(anchorPoint);
299+
l.multiply(d);
300+
l.add(anchorPoint);
301+
}
302+
recalculate();
303+
}
304+
305+
public void scale(@NotNull Vector vector) {
306+
for (Location l : knotsList) {
307+
l.subtract(anchorPoint);
308+
l.setX(l.getX() * vector.getX());
309+
l.setY(l.getY() * vector.getY());
310+
l.setZ(l.getZ() * vector.getZ());
311+
l.add(anchorPoint);
312+
}
313+
recalculate();
314+
}
315+
316+
public @Nullable World getWorld() {
317+
if (knots == null) {
318+
return null;
319+
}
320+
if (knots.length == 0) {
321+
return null;
322+
}
323+
return knots[0].getWorld();
324+
}
325+
212326
@Override
213327
public String toString() {
214328
if (knots == null) {
@@ -217,4 +331,16 @@ public String toString() {
217331
return knots.length + " points.";
218332
}
219333

334+
public @NotNull String toName() {
335+
return "Curve";
336+
}
337+
338+
public @NotNull BezierSpline emptySystem() {
339+
return new BezierSpline();
340+
}
341+
342+
public @NotNull String toShorthand() {
343+
return "curve";
344+
}
345+
220346
}

src/main/java/net/onelitefeather/bettergopaint/utils/curve/BezierSplineSegment.java

Lines changed: 95 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -20,23 +20,22 @@
2020

2121
import org.bukkit.Location;
2222
import org.jetbrains.annotations.NotNull;
23+
import org.jetbrains.annotations.Nullable;
2324

2425
import java.util.Objects;
2526

2627
public class BezierSplineSegment {
2728

28-
private final double[] lengths;
29-
private final Location p0, p3;
30-
private Location p1, p2;
29+
private final double[] lengths = new double[20];
30+
private @NotNull Location p0, p1, p2, p3;
3131
private float a, b, c;
32-
private Double xFlat, yFlat, zFlat;
33-
private final Location r;
32+
private @Nullable Double xFlat, yFlat, zFlat;
33+
private @NotNull Location r;
3434
private double curveLength;
3535

3636
public BezierSplineSegment(@NotNull Location p0, @NotNull Location p3) {
3737
this.p0 = p0;
3838
this.p3 = p3;
39-
lengths = new double[20];
4039
p1 = new Location(p0.getWorld(), 0, 0, 0);
4140
p2 = new Location(p0.getWorld(), 0, 0, 0);
4241
r = new Location(p0.getWorld(), 0, 0, 0);
@@ -83,6 +82,73 @@ public void calculateCurveLength() {
8382
curveLength = lengths[19];
8483
}
8584

85+
public double getdXdT(double t) {
86+
assert (t >= 0);
87+
assert (t <= 1);
88+
return 3 * (1 - t) * (1 - t) * (p1.getX() - p0.getX()) + 6 * (1 - t) * t
89+
* (p2.getX() - p1.getX()) + 3 * t * t * (p3.getX() - p2.getX());
90+
}
91+
92+
public double getdYdT(double t) {
93+
assert (t <= 1);
94+
return 3 * (1 - t) * (1 - t) * (p1.getY() - p0.getY()) + 6 * (1 - t) * t
95+
* (p2.getY() - p1.getY()) + 3 * t * t * (p3.getY() - p2.getY());
96+
}
97+
98+
public double getdZdT(double t) {
99+
assert (t >= 0);
100+
assert (t <= 1);
101+
return 3 * (1 - t) * (1 - t) * (p1.getZ() - p0.getZ()) + 6 * (1 - t) * t
102+
* (p2.getZ() - p1.getZ()) + 3 * t * t * (p3.getZ() - p2.getZ());
103+
}
104+
105+
public double getdTdS(double t) {
106+
double dZdT = getdZdT(t);
107+
double dXdT = getdXdT(t);
108+
double dYdT = getdYdT(t);
109+
return 1 / Math.sqrt(dZdT * dZdT + dXdT * dXdT + dYdT * dYdT);
110+
}
111+
112+
public double getHAngle(double t) {
113+
// Positive x is 0, positive z is pi/2, negative x is pi, negative z is
114+
// 3*pi/2
115+
double dZdT = getdZdT(t);
116+
double dXdT = getdXdT(t);
117+
if (dXdT == 0) {
118+
if (dZdT < 0) {
119+
return Math.PI / 2;
120+
} else {
121+
return -Math.PI / 2;
122+
}
123+
}
124+
125+
if (dXdT < 0) {
126+
return Math.PI + Math.atan(dZdT / dXdT);
127+
}
128+
return Math.atan(dZdT / dXdT);
129+
}
130+
131+
public double getT(double d) {
132+
assert (d >= 0);
133+
assert (d <= curveLength);
134+
if (d == 0) {
135+
return 0;
136+
}
137+
if (d == curveLength) {
138+
return 1;
139+
}
140+
int i = 0;
141+
for (i = 0; i < 20; i++) {
142+
if (d == lengths[i]) {
143+
return i / 19d;
144+
}
145+
if (d < lengths[i]) {
146+
break;
147+
}
148+
}
149+
return (i + (d - lengths[i - 1]) / (lengths[i] - lengths[i - 1])) / 20;
150+
}
151+
86152
public Location getPoint(double f) {
87153
Location result = new Location(p0.getWorld(), 0, 0, 0);
88154
result.setX(Objects.requireNonNullElseGet(xFlat, () -> (Math.pow(1 - f, 3) * p0.getX())
@@ -97,30 +163,42 @@ public Location getPoint(double f) {
97163
return result;
98164
}
99165

100-
public Location getP0() {
166+
public double getLinearLength() {
167+
return p0.distance(p3);
168+
}
169+
170+
public @NotNull Location getP0() {
101171
return p0;
102172
}
103173

104-
public Location getP1() {
174+
public void setP0(@NotNull Location p0) {
175+
this.p0 = p0;
176+
}
177+
178+
public @NotNull Location getP1() {
105179
return p1;
106180
}
107181

108-
public void setP1(Location p1) {
182+
public void setP1(@NotNull Location p1) {
109183
this.p1 = p1;
110184
}
111185

112-
public Location getP2() {
186+
public @NotNull Location getP2() {
113187
return p2;
114188
}
115189

116-
public void setP2(Location p2) {
190+
public void setP2(@NotNull Location p2) {
117191
this.p2 = p2;
118192
}
119193

120-
public Location getP3() {
194+
public @NotNull Location getP3() {
121195
return p3;
122196
}
123197

198+
public void setP3(@NotNull Location p3) {
199+
this.p3 = p3;
200+
}
201+
124202
public float getA() {
125203
return a;
126204
}
@@ -145,9 +223,12 @@ public void setC(float c) {
145223
this.c = c;
146224
}
147225

148-
public Location getR() {
226+
public @NotNull Location getR() {
149227
return r;
150228
}
151229

152-
}
230+
public void setR(@NotNull Location r) {
231+
this.r = r;
232+
}
153233

234+
}

0 commit comments

Comments
 (0)