回答編集履歴
3
ベジェ円 java コード追加
test
CHANGED
@@ -93,3 +93,144 @@
|
|
93
93
|
[ベジェ曲線を使って 円を描画する Java2D](https://blog.ideastorage.net/posts/kotlin-java2d-bezier/)
|
94
94
|
|
95
95
|
1/4 円を GeneralPath の curveTo で書いているので、そのパラメータの点の位置をずらすような形にすればうねうねする…かもしれません。
|
96
|
+
kotlin だったので java に直しました。
|
97
|
+
```java
|
98
|
+
import java.awt.Color;
|
99
|
+
import java.awt.Graphics2D;
|
100
|
+
import java.awt.geom.GeneralPath;
|
101
|
+
import java.awt.geom.Point2D;
|
102
|
+
import java.awt.image.BufferedImage;
|
103
|
+
import java.io.File;
|
104
|
+
import java.io.IOException;
|
105
|
+
import java.util.Arrays;
|
106
|
+
import java.util.List;
|
107
|
+
|
108
|
+
import javax.imageio.ImageIO;
|
109
|
+
|
110
|
+
class BezierCircle {
|
111
|
+
private static class MatrixUtils {
|
112
|
+
static float[] times(float[] a, float[] b) {
|
113
|
+
return new float[] {
|
114
|
+
a[0]*b[0] + a[1]*b[3] + a[2]*b[6],
|
115
|
+
a[0]*b[1] + a[1]*b[4] + a[2]*b[7],
|
116
|
+
a[0]*b[2] + a[1]*b[5] + a[2]*b[8],
|
117
|
+
|
118
|
+
a[0+3]*b[0] + a[1+3]*b[3] + a[2+3]*b[6],
|
119
|
+
a[0+3]*b[1] + a[1+3]*b[4] + a[2+3]*b[7],
|
120
|
+
a[0+3]*b[2] + a[1+3]*b[5] + a[2+3]*b[8],
|
121
|
+
|
122
|
+
a[0+3*2]*b[0] + a[1+3*2]*b[3] + a[2+3*2]*b[6],
|
123
|
+
a[0+3*2]*b[1] + a[1+3*2]*b[4] + a[2+3*2]*b[7],
|
124
|
+
a[0+3*2]*b[2] + a[1+3*2]*b[5] + a[2+3*2]*b[8]
|
125
|
+
};
|
126
|
+
}
|
127
|
+
|
128
|
+
static float[] times(float[] a, float[] b, float[] c) { return times( a, times(b, c) ); }
|
129
|
+
static float[] times(float[] a, float[] b, float[] c, float[] d) { return times( a, times(b, times(c, d)) ); }
|
130
|
+
|
131
|
+
static float[] transform(float[] a, float x, float y) {
|
132
|
+
float[] b = new float[] { x, y, 1f };
|
133
|
+
|
134
|
+
float c00 = a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
|
135
|
+
float c10 = a[0 + 3] * b[0] + a[1 + 3] * b[1] + a[2 + 3] * b[2];
|
136
|
+
float c20 = a[0 + 6] * b[0] + a[1 + 6] * b[1] + a[2 + 6] * b[2];
|
137
|
+
|
138
|
+
return new float[] { c00, c10, c20 };
|
139
|
+
}
|
140
|
+
|
141
|
+
static Point2D.Float transform(float[] a, Point2D.Float pt) {
|
142
|
+
float[] array = transform(a, pt.x, pt.y);
|
143
|
+
return new Point2D.Float(array[0], array[1]);
|
144
|
+
}
|
145
|
+
}
|
146
|
+
|
147
|
+
private static double toRadian(double degree) { return degree * Math.PI/180f; }
|
148
|
+
|
149
|
+
// 原点に並行移動して、degree度分回転、元の位置へ並行移動する matrixValues を生成:
|
150
|
+
private static float[] toMatrixValues(double degree) {
|
151
|
+
double radian = toRadian(degree);
|
152
|
+
|
153
|
+
float[] matrixValues0 = new float[] {
|
154
|
+
1f, 0f, -50f,
|
155
|
+
0f, 1f, -50f,
|
156
|
+
0f, 0f, 1f };
|
157
|
+
|
158
|
+
float[] matrixValues1 = new float[] {
|
159
|
+
(float)Math.cos(radian), (float)-Math.sin(radian), 0f,
|
160
|
+
(float)Math.sin(radian), (float) Math.cos(radian), 0f,
|
161
|
+
0f, 0f, 1f };
|
162
|
+
|
163
|
+
float[] matrixValues2 = new float[] {
|
164
|
+
1f, 0f, 50f,
|
165
|
+
0f, 1f, 50f,
|
166
|
+
0f, 0f, 1f };
|
167
|
+
|
168
|
+
return MatrixUtils.times(matrixValues2, matrixValues1, matrixValues0);
|
169
|
+
};
|
170
|
+
|
171
|
+
// 回転して並行移動する matrixValues を生成:
|
172
|
+
static float[] toMatrixValuesWithTranslation(double degree, float dx, float dy) {
|
173
|
+
float[] matrixValues = new float[] {
|
174
|
+
1f, 0f, dx,
|
175
|
+
0f, 1f, dy,
|
176
|
+
0f, 0f, 1f };
|
177
|
+
|
178
|
+
return MatrixUtils.times( matrixValues, toMatrixValues(degree) );
|
179
|
+
}
|
180
|
+
|
181
|
+
public static void main(String[] args) throws IOException {
|
182
|
+
System.setProperty("java.awt.headless", "true");
|
183
|
+
|
184
|
+
// 200x200 のキャンバスを作成:
|
185
|
+
int w = 200;
|
186
|
+
int h = 200;
|
187
|
+
|
188
|
+
BufferedImage img = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
|
189
|
+
|
190
|
+
Graphics2D g = (Graphics2D)img.getGraphics();
|
191
|
+
g.setColor(Color.WHITE);
|
192
|
+
g.fillRect(0, 0, w, h);
|
193
|
+
|
194
|
+
// 中心が (100,100) 半径 R=100 の円弧 (左上1/4) を描画するための点の計算:
|
195
|
+
float M = (4f / 3f * ((float)Math.sqrt(2d)-1f)); /// 円をベジェで描くためのマジックナンバー
|
196
|
+
float R = 100f;
|
197
|
+
float RM = R*M;
|
198
|
+
|
199
|
+
Point2D.Float startPt = new Point2D.Float(0f, R);
|
200
|
+
Point2D.Float controlPt1 = new Point2D.Float(0f, R-RM);
|
201
|
+
Point2D.Float controlPt2 = new Point2D.Float(R-RM, 0f);
|
202
|
+
Point2D.Float stopPt = new Point2D.Float(R, 0f);
|
203
|
+
|
204
|
+
List<Point2D.Float> ptList = Arrays.asList(startPt, controlPt1, controlPt2, stopPt);
|
205
|
+
|
206
|
+
// 残りの 3つの円弧は、今作成した点をベースに回転と並行移動を使って作成:
|
207
|
+
|
208
|
+
float[] matrixValues1 = toMatrixValuesWithTranslation(90*1d, 100f, 0f);
|
209
|
+
float[] matrixValues2 = toMatrixValuesWithTranslation(90*2d, 100f, 100f);
|
210
|
+
float[] matrixValues3 = toMatrixValuesWithTranslation(90*3d, 0f, 100f);
|
211
|
+
|
212
|
+
List<Point2D.Float> ptList1 = ptList.stream().map(it -> MatrixUtils.transform(matrixValues1, it)).toList();
|
213
|
+
List<Point2D.Float> ptList2 = ptList.stream().map(it -> MatrixUtils.transform(matrixValues2, it)).toList();
|
214
|
+
List<Point2D.Float> ptList3 = ptList.stream().map(it -> MatrixUtils.transform(matrixValues3, it)).toList();
|
215
|
+
|
216
|
+
// パスを使って円を描画:
|
217
|
+
GeneralPath path = new GeneralPath();
|
218
|
+
|
219
|
+
Arrays.asList(ptList, ptList1, ptList2, ptList3).stream().forEach(it -> {
|
220
|
+
path.moveTo(it.get(0).x, it.get(0).y);
|
221
|
+
path.curveTo(
|
222
|
+
it.get(1).x, it.get(1).y,
|
223
|
+
it.get(2).x, it.get(2).y,
|
224
|
+
it.get(3).x, it.get(3).y);
|
225
|
+
});
|
226
|
+
|
227
|
+
g.setColor(Color.BLACK);
|
228
|
+
g.draw(path);
|
229
|
+
|
230
|
+
// PNGとしてファイルに保存:
|
231
|
+
File pngFile = new File("circle.png");
|
232
|
+
ImageIO.write(img, "PNG", pngFile);
|
233
|
+
}
|
234
|
+
}
|
235
|
+
```
|
236
|
+
![circle.png](https://ddjkaamml8q8x.cloudfront.net/questions/2024-05-21/6eb0e43a-2ba6-4c3d-b69e-a9df57cab248.png)
|
2
追記
test
CHANGED
@@ -88,3 +88,8 @@
|
|
88
88
|
}
|
89
89
|
}
|
90
90
|
```
|
91
|
+
何か弄る元になるものは無いかなと探すと
|
92
|
+
|
93
|
+
[ベジェ曲線を使って 円を描画する Java2D](https://blog.ideastorage.net/posts/kotlin-java2d-bezier/)
|
94
|
+
|
95
|
+
1/4 円を GeneralPath の curveTo で書いているので、そのパラメータの点の位置をずらすような形にすればうねうねする…かもしれません。
|
1
修正
test
CHANGED
@@ -1,4 +1,6 @@
|
|
1
1
|
CirclePanel 部分だけで動かしてみました。
|
2
|
+
で、コード通りならこうなるワケですけども、HTML は角丸を変えることでうねうねしていますがそれが全くコードに無いですね。
|
3
|
+
理想通りにならないというのは、角丸を色々変える方法を知りたいということになるのでしょうか。
|
2
4
|
```java
|
3
5
|
import java.awt.*;
|
4
6
|
import java.awt.event.MouseAdapter;
|