Ellipse Specification Using Vectors

The program Robert presents here demonstrates a method for rendering ellipses that's suited to the specific task of aligning ellipses to arbitrary curve segments using trigonometric splines.


July 25, 2008
URL:http://www.drdobbs.com/architecture-and-design/ellipse-specification-using-vectors/209601027

Robert is a software engineer and award-winning independent animator. He can be reached at [email protected].


Over the years, I've made heavy use of graphical editing programs and sometimes needed to use ellipse drawing functions. What I've found is that ellipse drawing functions in graphical editing programs typically use bounding boxes for specifying ellipses. This method serves well if the task requires fitting the ellipse within the confines of a box, or if it's not necessary to align the edge of the ellipse with precision. On occasion, however, I've had a need to use an ellipse (or a portion thereof) to approximate a freeform curve. In such cases, bounding boxes serve poorly. Why? Because the outer corner of the bounding box that specifies the ellipse is far enough away from the curve of interest that "eyeballing" placement of the nearest corner of the bounding box to specify an ellipse that approximates the freeform curve is error prone and usually produces erroneous results, as in Figure 1.

The problem is that ellipse curves specified by bounding boxes are physically disconnected from the opposite corners of the box that are actually under user control. This physical disconnect robs users of the ability to place the edge of the ellipse precisely against the freeform curve of interest. To give users the control needed to produce ellipses that approximate the curvature of a freeform curve, it is more expedient to specify an ellipse using points that interpolate (lie on the actual ellipse) rather than exterpolate (in which the ellipse is tied to the points but detached from them). This lets users click directly on the curve and anchor the ellipse to the freeform curve of interest from the outset. One approach is to specify an ellipse from a vector the user specifies. In Figure 2, the user clicks on some point lying upon the freeform curve and drags the end of the vector—along with the corresponding ellipse—until it closely approximates the freeform curve.

Figure 1: "Eyeballing" placement of the nearest corner of the bounding box.

Figure 2: Approximating with a vector-based ellipse.

You can implement this scheme using a uniform interpolating trigonometric spline (TSpline) whose control points lie at the corners of a rectangle. Alternatively, you can use the corners of a rhombus (see "Implementing Uniform Trigonometric Spline Curves"; www.ddj.com/architect/184410198). Both approaches inscribe (rather than circumscribe) the ellipse. In either case, a single vector is sufficient to define the four control points that specify an ellipse formed of a TSpline. For this algorithm, the most practical choice is to implement the TSpline ellipse that is specified by an inscribed rectangle.

Trigonometric Splines

For the purpose of the application I present here, think of splines as a means used to mathematically "connect the dots" with a smooth curve in some application where you are interested in defining a curve of arbitrary shape using movable points to control the shape of the curve. An interpolating uniform spline such as the Catmull-Rom spline, or the interpolating TSpline used in this algorithm, is controlled by a set of control points (commonly known as "knots"). Splines are defined piecewise, each piece being determined by four control points—the two preceding and two following the curve segment in sequence. Figure 3 shows a sample spline curve segment along with its control points.

The interpolating TSpline used in this algorithm is defined by a set of parametric equations (which form a basis curve) and control points, each arranged in vertical/horizontal vectors that are combined by means of matrix multiplication. They are arranged in vectors and given by the equations in Figure 4.

The TSpline basis is formed from a single trigonometric function with a period equal to four units. Each unit segment is then shifted to [0,1] to form the four basis spline function curves (Figure 5). Note in the upper graph that all of the zero crossings occur on unit intervals, except for the central part of the graph, which has a value of 1.0. The result can be seen in the lower graph where F2 and F3 have values of 1.0, which when multiplied by P2 and P3 yield the coordinates of P2 and P3 exactly, ensuring that the resulting curve segment interpolates P2 and P3. (Multiply the x and y components of P2 and P3 by 1.0, and you will get P2 and P3, respectively. The other curve segments, multiplied by 0.0, will contribute exactly 0.0 to the calculation.)

Figure 3: Sample spline curve segment along with its control points.

Figure 4: Equations that define the interpolating TSpline.

Figure 5: Four basis spline function curves.

Rendering Ellipses

A typical uniform spline is applied over a set of control points P1, P2, ..., Pi, ..., Pn-1, Pn such that segment i is denoted by points Pi-1, Pi, Pi+1, Pi+2; see Figure 6(a). The end segments are specified by doubling up the endpoints such as for the first segment: P1, P1, P2, P3. A TSpline-based ellipse is formed from a set of control points in a rectangular formation denoted by P1, P2, P3, P4. Each ellipse segment is derived from the control points in a round-robin scheme: P4 ,P1, P2, P3 for segment 1, P1, P2, P3, P4 for segment 2, and so on; see Figure 6(b).

Since the TSpline is defined by a periodic basis function, you can dispense with defining the ellipse as a piecewise function and simply render all four quadrants of the ellipse by choosing one of the four curve segment configurations and iterating over the interval of [0,4] rather than in four times over [0,1]. This is a cleaner, more efficient implementation scheme than piecewise rendering. This functionality has been subclassed off of the VectorEllipse class as VectorEllipse4 (available online at www.ddj.com/code/).

Figure 6: How spline segments of the ellipses are defined.

Demo Program

The demo program, specified by the EllipseDemo class (Listing One, available online), is a framework subclassed from the Java Frame class and derived from the paint program in Steve Holzner's book Java After Hours: 10 Projects You'll Never Do at Work. Each function is selected from a drop-down menu called Draw.

The Freehand Drawing function lets users draw a freeform curve against which to test ellipse-fitting using the two methods. It simply leaves a line following the path of the mouse when dragged across the drawing space and needs no further explanation.

The Box Ellipse function demonstrates an ellipse drawn from a bounding box using Java's built-in Ellipse2D.Double definition. The bounding box is drawn in red during editing for reference. To match this ellipse to a portion of a freeform curve, eyeball where the nearest corner of the bounding box of the ellipse falls to match the ellipse to the curve without the ellipse drifting away. (Not always an easy task!) See Figure 1.

The Vector Ellipse function demonstrates how to improve upon the standard bounding-box method by rendering ellipses drawn from a vector using TSplines. The VectorEllipse class (Listing Two, available online) is used to define and then render the ellipse. VectorEllipse is defined globally rather than locally in the place where it is used, as was Ellipse2D.Double. Had VectorEllipse been defined locally during use, it would have negated the benefits of precomputing the basis function in the setBasis method. During editing, the defining vector is drawn in red. To align a vector ellipse with curve, choose a point at about a 45-degree angle or at the halfway point about an ellipse quadrant for optimal results; see Figure 2.

A second Vector Ellipse function, Vector Ellipse 4, demonstrates the TSpline ellipse drawn in one piece rather than four. The VectorEllipse4 class (Listing Three, available online) defines and renders the ellipse. Subclassed from VectorEllipse, the setBasis, plotEllipse, and putEllipse methods are overridden to achieve this. A separate menu selection, Vector Ellipse 4 is provided to demonstrate this functionality. Its outward behavior is identical to its piecewise counterpart.

Performance

I developed this program on a Mac Powerbook G4 1.5-GHz PowerPC processor under Mac OS X v 0.4.3 using Java 1.4, which came installed in the system. On the G4 system, the program ran smoothly without screen flicker. I then tested the program on a Mac G3 iBook and PC Pentium 4 under Java 1.3. On both platforms, flickering was prominently notable, indicating a deficiency in speed.

Conclusion

The program I present here demonstrates an alternative method for rendering ellipses. This method is suited to the specific task of aligning ellipses to arbitrary curve segments using trigonometric splines (which, as yet, seems little known among most computer graphics practitioners). You can do a number of other things to facilitate matching ellipses to freeform curves, such as adjusting the ellipse through rotation and resizing. Since these methods are well understood and available in many graphical editing programs, I didn't include them here.

References

Holzner, Steven. Java After Hours: 10 Projects You'll Never Do at Work, Sams Publishing, 2006.

Kauffmann, Robert F. "Implementing Uniform Trigonometric Spline Curves," DDJ, May 1997.

Niemeyer, Patrick and Jonathan Knudsen. Learning Java, Third Edition, O'Reilly & Associates, 2005.

Terms of Service | Privacy Statement | Copyright © 2024 UBM Tech, All rights reserved.