123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102 |
- /*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
- /* $Id$ */
-
- package org.apache.fop.render.intermediate;
-
- import java.io.IOException;
-
- public class ArcToBezierCurveTransformer {
-
- private final BezierCurvePainter bezierCurvePainter;
-
- public ArcToBezierCurveTransformer(BezierCurvePainter bezierCurvePainter) {
- this.bezierCurvePainter = bezierCurvePainter;
- }
-
- /**
- * Draws an arc on the ellipse centered at (cx, cy) with width width and height height
- * from start angle startAngle (with respect to the x-axis counter-clockwise)
- * to the end angle endAngle.
- * The ellipses major axis are assumed to coincide with the coordinate axis.
- * The current position MUST coincide with the starting position on the ellipse.
- * @param startAngle the start angle
- * @param endAngle the end angle
- * @param cx the x coordinate of the ellipse center
- * @param cy the y coordinate of the ellipse center
- * @param width the extent of the ellipse in the x direction
- * @param height the extent of the ellipse in the y direction
- * @throws IOException if an I/O error occurs
- */
- public void arcTo(final double startAngle, final double endAngle, final int cx, final int cy,
- final int width, final int height) throws IOException {
-
- // Implementation follows http://www.spaceroots.org/documents/ellipse/ -
- // Drawing an elliptical arc using polylines, quadratic or cubic Bézier curves
- // L. Maisonobe, July 21, 2003
-
- // Scaling the coordinate system to represent the ellipse as a circle:
- final double etaStart = Math.atan(Math.tan(startAngle) * width / height)
- + quadrant(startAngle);
- final double etaEnd = Math.atan(Math.tan(endAngle) * width / height)
- + quadrant(endAngle);
-
- final double sinStart = Math.sin(etaStart);
- final double cosStart = Math.cos(etaStart);
- final double sinEnd = Math.sin(etaEnd);
- final double cosEnd = Math.cos(etaEnd);
-
- final double p0x = cx + cosStart * width;
- final double p0y = cy + sinStart * height;
- final double p3x = cx + cosEnd * width;
- final double p3y = cy + sinEnd * height;
-
- double etaDiff = Math.abs(etaEnd - etaStart);
- double tan = Math.tan((etaDiff) / 2d);
- final double alpha = Math.sin(etaDiff) * (Math.sqrt(4d + 3d * tan * tan) - 1d) / 3d;
-
- int order = etaEnd > etaStart ? 1 : -1;
-
- // p1 = p0 + alpha*(-sin(startAngle), cos(startAngle))
- final double p1x = p0x - alpha * sinStart * width * order;
- final double p1y = p0y + alpha * cosStart * height * order;
-
- // p1 = p3 + alpha*(sin(endAngle), -cos(endAngle))
- final double p2x = p3x + alpha * sinEnd * width * order;
- final double p2y = p3y - alpha * cosEnd * height * order;
-
- //Draw the curve in original coordinate system
- bezierCurvePainter.cubicBezierTo((int) p1x, (int) p1y, (int) p2x, (int) p2y, (int) p3x, (int) p3y);
- }
-
- private double quadrant(double angle) {
- if (angle <= Math.PI) {
- if (angle <= Math.PI / 2d) {
- return 0;
- } else {
- return Math.PI;
- }
- } else {
- if (angle > Math.PI * 3d / 2d) {
- return 2d * Math.PI;
- } else {
- return Math.PI;
- }
- }
- }
- }
|