到现在我对多线程的理解就是,能够同时让多个任务同时执行----this is right
镇赉ssl适用于网站、小程序/APP、API接口等需要进行数据传输应用场景,ssl证书未来市场广阔!成为创新互联的ssl证书销售渠道,可以享受市场价格4-6折优惠!如果有意向欢迎电话联系或者加微信:18980820575(备注:SSL证书合作)期待与您的合作!
但是仅仅对一个对象的话能否让一个对象同时做多个事情呢? -----不可以
你记得书上讲多线程提到的一个概念叫做锁。synchronized.
一个对象只有一把锁 当然这个对象只能对打开他锁的人敞开心扉。
你明白了吗。
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.geom.*;
/**
* @author Hardneedl
*/
class RectTransform extends JFrame {
private static final Dimension minSize = new Dimension(300, 200);
private static final Dimension maxSize = new Dimension(1024, 768);
private static final Dimension preferredSize = new Dimension(600, 400);
public Dimension getMaximumSize() {return maxSize;}
public Dimension getMinimumSize() {return minSize;}
public Dimension getPreferredSize() {return preferredSize;}
public String getTitle() {return "Frame Title";}
private AffineTransform af = new AffineTransform();
private Stroke stroke = new BasicStroke(2.0f);
private Rectangle rct = new Rectangle(40,140,200,140);
private JComponent canvas = new JComponent(){
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.BLACK);
g.fillRect(0,0,getWidth(),getHeight());
Graphics2D g2d = (Graphics2D)g.create();
g2d.setColor(Color.YELLOW);
g2d.setTransform(af);
g2d.setStroke(stroke);
g2d.draw(rct);
g2d.dispose();
}
};
RectTransform() throws HeadlessException {
init();
doLay();
attachListeners();
}
private void init() {
}
private void doLay() {
Container container = getContentPane();
JPanel panel = new JPanel(new FlowLayout(FlowLayout.CENTER,30,5));
panel.add(new JButton( new AfAction("move", AffineTransform.getTranslateInstance(100,100)) ));
panel.add(new JButton( new AfAction("rotate", AffineTransform.getRotateInstance(Math.PI/3,40,120) ) ));
panel.add(new JButton( new AfAction("zoomIn", AffineTransform.getScaleInstance(2,2)) ));
panel.add(new JButton( new AfAction("ZoomOut", AffineTransform.getScaleInstance(.5d,.5d)) ));
panel.add(new JButton( new AfAction("Original", new AffineTransform()) ) );
container.add(panel,BorderLayout.NORTH);
container.add(canvas,BorderLayout.CENTER);
pack();
}
private void attachListeners() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
private class AfAction extends AbstractAction {
private AffineTransform aff;
private AfAction(String n,AffineTransform af) {
super(n);
this.aff = af;
}
public void actionPerformed(ActionEvent e) {
af.setTransform(aff);
if(canvas.isVisible()) canvas.paintImmediately(0,0,getWidth(),getHeight());
}
}
public static void main(String[] args) {
new RectTransform().setVisible(true);
}
}
重载渲染控件的paintComponent(Graphics
g)方法.
设你当前图像实例为img,已初始化,需要旋转的角度为ang
public
void
paintComponent(Graphics
g){
super.paintCompoent(g);
Graphics2D
g2d
=
(Graphics2D)g;
g2d.rotate(-angle);
g2d.drawImage(img,0,0,this.getWidth(),this.getHeight(),null);
}
Graphics,Graphics2D
类中有对当前描绘环境进行仿射变换的方法,包括translate,scale,rotate,也可以直接设置仿射变换矩阵,利用这点就可以根据所需要的实现方式来进行描绘.
java编写二维坐标平移程序,主要是通过类继承Point2D,使用里面的方法来平移,如下代码:
class Point2D
{
int x, y;
Point2D(){ }
Point2D(int i,int j)
{
x=i;
y=j;
}
void offset(int a, int b)
{
x=x+a;
y=y+b;
}
void distance(Point2D a,Point2D b)
{
float m;
m=(float)Math.sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
System.out.print("二维空间两点之间的距离:");
System.out.println("m="+m);
}
}
public class Point3D extends Point2D
{
int x,y,z;
Point3D(int x,int y,int z)
{
this.x=x;
this.y=y;
this.z=z;
}
Point3D(Point2D p,int z)
{
x=p.x;
y=p.y;
this.z=z;
}
void offset(int a, int b,int c)
{
x=x+a;
b=x+b;
c=x+c;
}
void distance(Point3D a,Point3D b)
{
float n;
n=(float)Math.sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)+(a.y-b.y)*(a.y-b.y));//计算两点之间的距离。
System.out.print("三维空间两点之间的距离:");
System.out.println("n="+n);
}
public static void main(String[] args)
{
Point2D p2d1=new Point2D(2,3);
Point2D p2d2=new Point2D(3,6);
Point3D p2d3=new Point3D(1,2,3);
Point3D p2d4=new Point3D(p2d1,3);
p2d1.distance(p2d1,p2d2);
p2d3.distance(p2d3,p2d4);//平移一段距离。
}
}
(注,下面的(x,y)就是你的图片所有的点围绕旋转的中心,为(0,0)即为绕原点进行旋转
当然是用矩阵啦,左乘一个三阶矩阵
(cosA, -sinA, x,sinA, cosA, y,0, 0 , s)
其中a代表你要旋转的角度 ;旋转变幻(绕原点,绕其他点直接平移即可)即为 X’ = X * cosA - Y * sinA; Y' = X * sinA + Y * cosA;
可以用极坐标轻松证明之,建议你自己推导一遍,,,,,,
(x,y)代表平移的坐标,不平移就为0, s代表缩放的倍数,,不缩放为1;
如果不会用矩阵或者不想用的话就直接用上面那个给出的公式进行变幻,,,,,,
还是用矩阵吧,,方便一点。。。。
在操作二维或三维的图形图像上,长期以来人们总结出了一些常用的变换矩阵,这些矩阵就像公式和定理一样被开发人员使用,楼主可以把这些矩阵当成公式来记忆,就像我们小时候背加法、乘法口诀一样。
如果楼主想了解得更深入一些,请往下看:
[ x'] [ m00 m01 m02 ] [ x ] [ m00x + m01y + m02 ]
[ y'] = [ m10 m11 m12 ] [ y ] = [ m10x + m11y + m12 ]
[ 1 ] [ 0 0 1 ] [ 1 ] [ 1 ]
上面的式子是jdk文档中复制过来的,就是变换时的运算过程,也就是说变换后的坐标x'、y'是由一个3*3的矩阵与原坐标x、y相乘得出的,其中的m00~m12就是AffineTransform构造方法中的六个参数,另外,式子中的最后一行是固定的。
矩阵乘法就不用说了吧,最后得出的结果就是上式中的最后一列,可能写成下面这样会更容易理解:
x' = m00x + m01y + m02
y' = m10x + m11y + m12
看出什么了吗?其实这就是二维平面直角坐标系中的两个很简单的二元一次方程而已,方程定义的就是横纵坐标变换的规则。
以水平翻转为例,水平翻转是以图形/图像的垂直中线为轴来翻转的,因此任何一个点(x,y)变换后的坐标应该是y坐标不变,x坐标变为-x+width-1,即(-x+width-1,y),之所以减1是因为垂直中轴上的点不应该改变。
理解了上面的变换过程之后,将结果带入上面的两个二元一次方程,可以得出
m00=-1、m01=0、m02=width-1
m10=0、m11=1、m12=0
正好是你给的代码中的六个值(AffineTransform构造方法中的参数顺序为m00、m10、m01、m11、m02、m12)
其他几个变换道理是一样的