United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-4724552 CubicCurve2D contains(Rectangle2D) returns true when only partially contained
JDK-4724552 : CubicCurve2D contains(Rectangle2D) returns true when only partially contained

Details
Type:
Bug
Submit Date:
2002-08-01
Status:
Closed
Updated Date:
2011-02-01
Project Name:
JDK
Resolved Date:
2011-03-08
Component:
client-libs
OS:
windows_98
Sub-Component:
2d
CPU:
x86
Priority:
P4
Resolution:
Fixed
Affected Versions:
1.3.0
Fixed Versions:

Related Reports

Sub Tasks

Description

Name: jk109818			Date: 08/01/2002


FULL PRODUCT VERSION :
\jdk1.3\bin\java cubconrc

cubconrc.java:
...

A DESCRIPTION OF THE PROBLEM :
A cubic curve joining endpoints
is NOT necessarily the union
of two convex sets on opposite
sides of the segment joining the
endpoints. A rectangle with all
corners inside the curve and on
one side of the segment is declared
to be contained by the
CubicCurve2D contains(Rectangle2D)
method even if it is only partially
contained.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1.Create a CubicCurve2D.Double object
with control points placed so that
curve is not convex nor the union of
convex sets separated by the segment.
2.Create a Rectangle2D.Double object
with all corners but not all edges
inside the region.
3.Call the "contains" method of the
CubicCurve2D object with respect to the
Rectangle2D object

EXPECTED VERSUS ACTUAL BEHAVIOR :
The "contains" method returns true
even though the rectangle is only
partially contained.

This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.lang.*;
import java.awt.*;
import java.awt.geom.*;
import java.awt.event.*;
import java.applet.*;
public class cubconrc extends Applet
{  private static boolean standalone=false;
   private Frame win=null;
   private TextArea ta=null;
   private canvcls canvobj=null;
   public static final void main(String[] args)
   {  standalone=true;
      (new cubconrc()).init(); }
   public void init()
   {  win=new Frame("cubics");
      win.addWindowListener(new WindowAdapter()
        {  public void windowClosing(WindowEvent we)
           { we.getWindow().dispose(); }
           public void windowClosed(WindowEvent we)
           { if (standalone) System.exit(0); } });
      win.setLayout(new FlowLayout(FlowLayout.CENTER,10,10));
      ta=new TextArea("",10,60);
      win.add(ta);
      canvobj=new canvcls();
      win.add(canvobj);
      win.pack();
      win.setSize(600,480);
      win.show(); }
    //see also  http://members.aol.com/FolkThomasF/MATHTXT.HTM
    private void dispmsg(String msg)
    { ta.append(msg+"\r\n");
      if (standalone) System.out.println(msg);   }
    private class canvcls extends Canvas
    { private Dimension dim=null;
      public canvcls() { dim=new Dimension(500,200); }
      public Dimension getMinimumSize() { return dim; }
      public Dimension getPreferredSize() { return dim; }
      public void paint(Graphics g)
      { g.setColor(Color.green);
        g.fillRect(0,0,dim.width,dim.height);
        ta.setText("");
        try { calculate(g); }
        catch(Throwable te) { dispmsg(String.valueOf(te)); }      }
      private int mapx(double x)
      { return (int)Math.round(dim.width/2+20*x); }
      private int mapy(double y)
      { return (int)Math.round(dim.height/2+20*y); }
      private void calculate(Graphics g)
      { CubicCurve2D cc=null;
        Rectangle2D rect=null;
        int ii=0;
        double xx=0,yy=0,tt=0;
        double[] eqn=null,res=null;
        boolean contained=false;
        cc=new CubicCurve2D.Double(5,-2,-1,4,-3,-6,0,3);
        dispmsg(" x1 "+cc.getX1()+" y1 "+cc.getY1()
                  +" x2 "+cc.getX2()+" y2 "+cc.getY2()
                  +" cpx1 "+cc.getCtrlX1()+" cpy1 "+cc.getCtrlY1()
                  +" cpx2 "+cc.getCtrlX2()+" cpy2 "+cc.getCtrlY2());
        g.setColor(Color.blue);
        g.drawLine(mapx(cc.getX1()),mapy(cc.getY1()),
                   mapx(cc.getX2()),mapy(cc.getY2()));
        for (tt=0;tt<=1;tt+=0.02)
        { xx=    cc.getX1()    *(1-tt)*(1-tt)*(1-tt)
            +  3*cc.getCtrlX1()*(1-tt)*(1-tt)*tt
            +  3*cc.getCtrlX2()*(1-tt)*tt    *tt
            +    cc.getX2()    *tt    *tt    *tt;
          yy=    cc.getY1()    *(1-tt)*(1-tt)*(1-tt)
            +  3*cc.getCtrlY1()*(1-tt)*(1-tt)*tt
            +  3*cc.getCtrlY2()*(1-tt)*tt    *tt
            +    cc.getY2()    *tt    *tt    *tt;
          g.setColor(Color.blue);
          g.fillOval(mapx(xx)-1,mapy(yy)-1,2,2);           }
        g.setColor(Color.red);
        rect=new Rectangle2D.Double(-1,-0.25,4,0.05);
        g.drawRect(mapx(rect.getX()),
                   mapy(rect.getY()),
                   mapx(rect.getX()+rect.getWidth())
                  -mapx(rect.getX()),
                   mapy(rect.getY()+rect.getHeight())
                  -mapy(rect.getY()));
        dispmsg(String.valueOf(rect));
        dispmsg("contains "+cc.contains(rect));  }  }  }

---------- END SOURCE ----------

CUSTOMER WORKAROUND :
"contains" method should
also call the "intersects" method
(Review ID: 146601) 
======================================================================

                                    

Comments
EVALUATION

Fixed in JDk 7
Changeset: 0bec5d506120
Author:    dlila
Date:      2011-01-19 09:44 -0500
URL:       http://hg.openjdk.java.net/jdk7/2d/jdk/rev/0bec5d506120

4724552: CubicCurve2D.contains(Rectangle2D) returns true when only partially contained.
Summary: Now using subdivision code in sun.awt.geom.Curve.
Reviewed-by: flar

! src/share/classes/java/awt/geom/CubicCurve2D.java
                                     
2011-02-01



Hardware and Software, Engineered to Work Together