import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.awt.image.BufferedImage;
import javax.swing.*;
import javax.swing.event.MouseInputAdapter;
public class DrawCurve extends JPanel implements ActionListener {
ButtonManager buttonManager;
Path2D.Double path;
Point2D.Double[] points;
Line2D.Double[] connectors;
boolean showConnections= false;
boolean removePoint= false;
boolean firstTime= true;
final double Factor = 50.0D;
DrawCurve() {
float maxcamber,position,thickness;
int datapts;
double x1,y1;
maxcamber=0.08F;position=5.0F;thickness=0.12F;datapts=25;
int i=1;
double yt[]=new double [100];
double yc[]=new double [100];
double xu[]=new double [100];
double yu[]=new double [100];
double xl[]=new double [100];
double yl[]=new double [100];
double x[]=new double [100];
for(i=1;i<=datapts;i++)
{
x1=((3.141562/180)*(i-1)*(90/(datapts-1)));
x[i]=(1-Math.cos(x1));
yt[i]=(thickness/0.2)*((0.2969*Math.pow(x[i],0.5))-(0.126*x[i])-(0.3516*Math.pow(x[i],2))+(0.2843*Math.pow(x[i],3))-(0.1015*Math.pow(x[i],4)));
if(x[i]<(position/10))
{
yc[i]=(maxcamber/(Math.pow((position/10),2))*((2*(position/10)*x[i])-(Math.pow(x[i],2))));
}
else
{
yc[i]=(maxcamber/(Math.pow(1-(position/10),2)))*((1-(2*(position/10)))+(2*(position/10)*x[i])-Math.pow(x[i],2));
}
xu[i]=x[i]-yt[i]*(Math.sin(Math.atan((yc[i+1]-yc[i])/(x[i+1]-x[i]))));
yu[i]=yc[i]+yt[i]*(Math.cos(Math.atan((yc[i+1]-yc[i])/(x[i+1]-x[i]))));
xl[i]=x[i]+yt[i]*(Math.sin(Math.atan((yc[i+1]-yc[i])/(x[i+1]-x[i]))));
yl[i]=yc[i]-yt[i]*(Math.cos(Math.atan((yc[i+1]-yc[i]/(x[i+1]-x[i])))));
// System.out.println("x :"+x [i]);
//System.out.println("yt :"+yt [i]);
//System.out.println("yc :"+yc [i]);
System.out.println("xu :"+xu [i]);
System.out.println("yu :"+yu [i]);
System.out.println("xl :"+xl [i]);
System.out.println("yl :"+yl [i]);
System.out.println(" ");
/*double[][] cds= { {0,0},{0.00378,0.01779},{0.02536,0.03931}, {0.06478,0.06320},{0.12172,0.08733},
{0.19533,0.10908},{0.2, 8417,12564},{0.38625,0.13435},{0.49906,0.13293},
{0.61979,0.11971},{0.74551,0.09361},{0.87332,0.05412 },{1.0036,0.00121} };*/
double[][] cds= {{xu[i],yu[i]},{xl[i],yl[i]}};
System.out.println("cds :"+cds[i][i]);
points = new Point2D.Double[cds.length];
for(int j = 0; j < cds.length; j++) { // NOTE 1 based? -1 stops short here also
points[j] = new Point2D.Double(Factor * cds[j][0] + Factor, Factor * cds[j][1] + Factor);
}
}//for loop end
/*Path2D.Double*/ path = new Path2D.Double();
System.out.println("1path bnds=" + path.getBounds());
}
public void actionPerformed(ActionEvent e) {
System.out.println("aP e=" + e);
String ac = e.getActionCommand();
if(ac.equals("add")) {
connectors = new Line2D.Double[points.length-1];
showConnections = true;
repaint();
}
if(ac.equals("cancel")) {
showConnections = false;
removePoint = false;
repaint();
}
if(ac.equals("remove")) {
removePoint = true;
}
}
public void addPoint(Point2D.Double p, int index) {
int size = points.length;
Point2D.Double[] temp = new Point2D.Double[size+1];
System.arraycopy(points, 0, temp, 0, index);
temp[index] = p;
System.arraycopy(points, index, temp, index+1, size-index);
points = temp;
buttonManager.reset();
showConnections = false;
setPath();
repaint();
}
public void removePoint(Point2D.Double p) {
int size = points.length;
Point2D.Double[] temp = new Point2D.Double[size-1];
for(int j = 0, k = 0; j < size; j++) {
if(points[j] == p)
continue;
temp[k++] = points[j];
}
points = temp;
buttonManager.reset();
removePoint = false;
setPath();
repaint();
}
public void setPoint(Point2D.Double p,double x,double y) {
p.setLocation(x, y);
setPath();
repaint();
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
System.out.println("pC path bnds=" + path.getBounds()); //pC path bnds=java.awt.Rectangle[x=0,y=0,width=0,height=0]
Graphics2D g2 = (Graphics2D)g;
Path2D.Double path = new Path2D.Double();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL,
RenderingHints.VALUE_STROKE_PURE);
if(firstTime) {
firstTime = false;
setPath();
}
g2.setPaint(Color.green.darker());
g2.draw(path); //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ????
g2.setPaint(Color.red);
for(int j = 0; j < points.length; j++) {
mark(g2, points[j]);
}
// For adding a point.
if(showConnections) {
g2.setPaint(Color.yellow);
for(int j = 0; j < points.length-1; j++) {
connectors[j] = new Line2D.Double(points[j], points[j+1]);
g2.draw(connectors[j]);
}
}
} // end paintComponent()
/**
* P(t) = B(n,0)*P0 + B(n,1)*P1 + ... + B(n,n)*Pn
* 0 <= t <= 1
*
* B(n,m) = mth coefficient of nth degree Bernstein polynomial
* = C(n,m) * t^(m) * (1 - t)^(n-m)
* C(n,m) = Combinations of n things, taken m at a time
* = n! / (m! * (n-m)!)
*/
private void setPath() {
System.out.println("2path bnds=" + path.getBounds());
path.reset();
int n = points.length;
int w = getWidth();
for(int j = 0; j <= w; j++) {
double t = (double)j/w; // [0 <= t <= 1.0]
double x = 0;
double y = 0;
for(int k = 1; k < n; k++) {
// System.out.println("k=" + k + " points[k]=" + points[k]); //k=0 points[k]=null
x += B(n-1,k,t)*points[k].x;
y += B(n-1,k,t)*points[k].y;
}
if(j > 0)
path.lineTo(x,y);
else
path.moveTo(x,y);
}
} // end setPath()
private double B(int n, int m, double t) {
return C(n,m) * Math.pow(t, m) * Math.pow(1.0 - t, n-m);
}
private double C(int n, int m) {
return factorial(n) / (factorial(m)*factorial(n-m));
}
private double factorial(int n) {
return (n > 1) ? n*factorial(n-1) : 1;
}
private void mark(Graphics2D g2, Point2D.Double p) {
g2.fill(new Ellipse2D.Double(p.x-2, p.y-2, 4, 4));
}
private JPanel getButtonPanel() {
buttonManager = new ButtonManager();
String[] ids = { "add", "cancel", "remove" };
JPanel panel = new JPanel();
for(int j = 0; j < ids.length; j++) {
JButton button = new JButton(ids[j]);
button.setEnabled(j != 1);
buttonManager.add(button);
button.setActionCommand(ids[j]);
button.addActionListener(this);
panel.add(button);
}
return panel;
}
//----------------------------------------------------------------
public static void main(String[] args) {
DrawCurve test = new DrawCurve();
PointMover mover = new PointMover(test);
test.addMouseListener(mover);
test.addMouseMotionListener(mover);
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(test);
f.add(test.getButtonPanel(), "Last");
f.setSize(500,500);
f.setLocation(200,200);
f.setVisible(true);
}
//-------------------------------------------------------
static class PointMover extends MouseInputAdapter {
DrawCurve component;
Point2D.Double selectedPoint;
Cursor cursor;
Cursor defaultCursor = Cursor.getDefaultCursor();
Point2D.Double offset = new Point2D.Double();
boolean dragging = false;
final int PROX_DIST = 5;
PointMover(DrawCurve cf) {
component = cf;
BufferedImage image = getImage();
Point hotspot = new Point(17,17);
cursor = Toolkit.getDefaultToolkit().createCustomCursor(image, hotspot, null);
}
public void mousePressed(MouseEvent e) {
if(selectedPoint != null) {
if(component.removePoint) { // remove
component.removePoint(selectedPoint);
} else { // drag
offset.x = e.getX() - selectedPoint.x;
offset.y = e.getY() - selectedPoint.y;
dragging = true;
}
} else if(component.showConnections) { // add
Point p = e.getPoint();
Line2D.Double[] lines = component.connectors;
for(int j = 0; j < lines.length; j++) {
if(lines[j].ptSegDist(p) < PROX_DIST) {
component.addPoint(p, j+1);
break;
}
}
}
}
public void mouseReleased(MouseEvent e) {
dragging = false;
}
public void mouseDragged(MouseEvent e) {
if(dragging) {
double x = e.getX() - offset.x;
double y = e.getY() - offset.y;
component.setPoint(selectedPoint, x, y);
}
}
/** For point selection. */
public void mouseMoved(MouseEvent e) {
Point p = e.getPoint();
Point2D.Double[] pts = component.points;
boolean hovering = false;
for(int j = 0; j < pts.length; j++) {
if(pts[j].distance(p) < PROX_DIST) {
hovering = true;
if(selectedPoint != pts[j]) {
selectedPoint = pts[j];
component.setCursor(cursor);
break;
}
}
}
if(!hovering && selectedPoint != null) {
selectedPoint = null;
component.setCursor(defaultCursor);
}
}
private BufferedImage getImage() {
int w = 27, h = 27,
type = BufferedImage.TYPE_INT_ARGB_PRE;
BufferedImage image = new BufferedImage(w, h, type);
Graphics2D g2 = image.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2.setPaint(new Color(0x333333));
g2.draw(new Line2D.Double(w/2, 0, w/2, ); // n
g2.draw(new Line2D.Double(0, h/2, 8, h/2)); // w
g2.draw(new Line2D.Double(w/2, h-8, w/2, h)); // s
g2.draw(new Line2D.Double(w-8, h/2, w, h/2)); // e
g2.dispose();
return image;
}
}
//----------------------------------------
class ButtonManager implements ActionListener {
JButton[] buttons = new JButton[0];
public void actionPerformed(ActionEvent e) {
String ac = e.getActionCommand();
if(ac.equals("add")) {
getButton("remove").setEnabled(false);
enable(true);
} else if(ac.equals("remove")) {
getButton("add").setEnabled(false);
enable(true);
} else {
reset();
}
}
public void reset() {
getButton("add").setEnabled(true);
getButton("remove").setEnabled(true);
enable(false);
}
private void enable(boolean enable) {
getButton("cancel").setEnabled(enable);
}
public void add(JButton button) {
button.addActionListener(this);
int size = buttons.length;
JButton[] temp = new JButton[size+1];
System.arraycopy(buttons, 0, temp, 0, size);
temp[size] = button;
buttons = temp;
}
private JButton getButton(String target) {
for(int j = 0; j < buttons.length; j++) {
if(buttons[j].getActionCommand().equals(target))
return buttons[j];
}
return null;
}
}
} // end class