/* * Copyright 2009 Hao Nguyen * * Licensed 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. */ package gwt.g2d.client.graphics.visitor; import gwt.g2d.client.graphics.Surface; import gwt.g2d.shared.math.Vector2; /** * Adds a point to the current path, connected to the previous one by a * straight line, then adds a second point to the current path, connected to * the previous one by an arc whose properties are described by the arguments. * * @author hao1300@gmail.com */ public class ArcToVisitor implements ShapeVisitor { private final double x0, y0, x1, y1, x2, y2, radius; private final boolean connectFromPrev; /** * <p> * If the point (x0, y0) is equal to the point (x1, y1), or if the point * (x1, y1) is equal to the point (x2, y2), or if the radius radius is zero, * then the method must add the point (x1, y1) to the subpath, and connect * that point to the previous point (x0, y0) by a straight line. * <p> * Otherwise, if the points (x0, y0), (x1, y1), and (x2, y2) all lie on a * single straight line, then the method must add the point (x1, y1) to the * subpath, and connect that point to the previous point (x0, y0) by a * straight line. * <p> * Otherwise, let The Arc be the shortest arc given by circumference of the * circle that has radius radius, and that has one point tangent to the * half-infinite line that crosses the point (x0, y0) and ends at the point * (x1, y1), and that has a different point tangent to the half-infinite line * that ends at the point (x1, y1) and crosses the point (x2, y2). The points * at which this circle touches these two lines are called the start and end * tangent points respectively. The method must connect the point (x0, y0) to * the start tangent point by a straight line, adding the start tangent point * to the subpath, and then must connect the start tangent point to the end * tangent point by The Arc, adding the end tangent point to the subpath. */ public ArcToVisitor(double x0, double y0, double x1, double y1, double x2, double y2, double radius) { this.x0 = x0; this.y0 = y0; this.x1 = x1; this.y1 = y1; this.x2 = x2; this.y2 = y2; this.radius = radius; this.connectFromPrev = false; } /** * Let the point (x0, y0) be the last point in the subpath. * <p> * If the point (x0, y0) is equal to the point (x1, y1), or if the point * (x1, y1) is equal to the point (x2, y2), or if the radius radius is zero, * then the method must add the point (x1, y1) to the subpath, and connect * that point to the previous point (x0, y0) by a straight line. * <p> * Otherwise, if the points (x0, y0), (x1, y1), and (x2, y2) all lie on a * single straight line, then the method must add the point (x1, y1) to the * subpath, and connect that point to the previous point (x0, y0) by a * straight line. * <p> * Otherwise, let The Arc be the shortest arc given by circumference of the * circle that has radius radius, and that has one point tangent to the * half-infinite line that crosses the point (x0, y0) and ends at the point * (x1, y1), and that has a different point tangent to the half-infinite line * that ends at the point (x1, y1) and crosses the point (x2, y2). The points * at which this circle touches these two lines are called the start and end * tangent points respectively. The method must connect the point (x0, y0) to * the start tangent point by a straight line, adding the start tangent point * to the subpath, and then must connect the start tangent point to the end * tangent point by The Arc, adding the end tangent point to the subpath. */ public ArcToVisitor(double x1, double y1, double x2, double y2, double radius) { this.x0 = 0; this.y0 = 0; this.x1 = x1; this.y1 = y1; this.x2 = x2; this.y2 = y2; this.radius = radius; this.connectFromPrev = true; } /** * @see #ArcToVisitor(double, double, double, double, double, double, double) */ public ArcToVisitor(Vector2 point0, Vector2 point1, Vector2 point2, double radius) { this(point0.getX(), point0.getY(), point1.getX(), point1.getY(), point2.getX(), point2.getY(), radius); } /** * @see #ArcToVisitor(double, double, double, double, double) */ public ArcToVisitor(Vector2 point1, Vector2 point2, double radius) { this(point1.getX(), point1.getY(), point2.getX(), point2.getY(), radius); } @Override public void visit(Surface surface) { if (!connectFromPrev) { surface.getContext().moveTo(x0, y0); } surface.getContext().arcTo(x1, y1, x2, y2, radius); } }