如何使用夹子减少喷漆时间? [英] how to use clip to reduce paint time?

查看:92
本文介绍了如何使用夹子减少喷漆时间?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用剪辑来减少cpu负载。

i am trying to use clip to reduce the cpu load.

但是剪辑在屏幕上留下了一些我似乎无法摆脱的垃圾。同样,打开和关闭裁剪似乎对cpu负载也没有影响。

but the clip leaves some garbage on the screen that i can not seem to get rid of. also, turning clipping on and off seems to have no effect on the cpu load.

不论哪种情况。大部分时间似乎都花在了重新绘制管理器和绘制缓冲的图像上。

in either case. most of the time seems to be spent in the repaint manager and paint buffered image.

import static java.lang.Math.*;
import static java.awt.Color.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.awt.image.*;
import java.lang.reflect.InvocationTargetException;
import java.util.*;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.logging.Logger;
import javax.swing.*;
class Piece {
    protected Piece(int piece,int pieces,int radius) {
        this.piece=piece;
        this.start=piece*2*PI/pieces;
        this.end=(piece+1)*2*PI/pieces;
        points=new ArrayList<Point>((int)ceil(4*PI*radius*radius/pieces));
    }
    public double start() {
        return start;
    }
    public double end() {
        return end;
    }
    public int piece() {
        return piece;
    }
    public static double angleToPiece(int piece,int pieces) {
        return piece*2*PI/pieces;
    }
    public String toString() {
        return piece+" "+start+" "+end+" "+start*180/PI;
    }
    protected final double start;
    protected final double end;
    final int piece;
    public final ArrayList<Point> points;
}
class P extends Piece {
    P(int piece,int pieces,int radius) {
        super(piece,pieces,radius);
        shape=new Arc2D.Double(0,0,2*radius,2*radius,toDegrees(start),toDegrees(end-start),Arc2D.PIE);
        shapeAndPrevious=new Arc2D.Double(0-extra,0-extra,2*radius+extra,2*radius+extra,toDegrees(start-2*PI/pieces)-extrad,toDegrees(2*(end-start))+2*extrad,Arc2D.PIE);
    }
    final Shape shape,shapeAndPrevious;
    static final int extra=0;
    static final int extrad=0;
}
class Y extends JPanel {
    Y(int radius,int nPieces,long period) {
        this.radius=radius;
        this.nPieces=nPieces;
        this.period=period;
        d=new Dimension(2*radius,2*radius);
        lhsOrigin=new Point(radius,radius);
        // setOpaque(false);
    }
    private void init() {
        pieces=new P[nPieces];
        for(int i=0;i<nPieces;i++)
            pieces[i]=new P(i,nPieces,radius);
        while(gc==null)
            Thread.yield(); // wait for gui to be constructed
        bi=gc.createCompatibleImage(d.width,d.height);
        stpe.scheduleAtFixedRate(new Runnable() {
            @Override public void run() {
                dtrt();
            }
        },0,1,TimeUnit.MILLISECONDS);
    }
    private int dt() {
        return (int)(System.currentTimeMillis()-t0);
    }
    private long dtNanos() {
        return System.nanoTime()-t0Nanos;
    }
    private double dtMillis() {
        return dtNanos()/1000000.;
    }
    private void paintRadialLine(Graphics2D g) {
        g.setColor(green);
        if(line2d!=null)
            if(paintRadialLine)
                g.draw(line2d);
    }
    private void paintPieceShape(Graphics g,int index) {
        g.setColor(red);
        if(paintPieceShape) {
            ((Graphics2D)g).draw(pieces[index].shape);
            g.setColor(yellow);
            //((Graphics2D)g).fill(pieces[index].shape);
        }
    }
    @Override public void paintComponent(Graphics g) {
        // super.paintComponent(g);
        Shape s=g.getClip();
        if(clip!=null) {
            AlphaComposite ac=AlphaComposite.getInstance(AlphaComposite.SRC_OVER,.75f);
            ((Graphics2D)g).setComposite(ac);
            ((Graphics2D)g).clip(clip);
        }
        paintBufferedImage(g);
        Color old=g.getColor();
        paintPieceShape(g,piece);
        paintRadialLine(((Graphics2D)g));
        g.setColor(old);
        g.setColor(Color.white);
        g.drawLine(radius,0,radius,2*radius);
        g.drawLine(0,radius,2*radius,radius);
        if(clip!=null)
            ((Graphics2D)g).setClip(s);
    }
    private void paintBufferedImage(Graphics g) {
        if(bi!=null)
            g.drawImage(bi,0,0,null);
    }
    @Override public Dimension getPreferredSize() {
        return new Dimension(d);
    }
    private void dtrt() {
        piece=(int)(dtNanos()%period*nPieces/period);
        if(!(0<=piece&&piece<nPieces)) {
            System.out.println("!(0<=piece&&piece<nPieces)");
            throw new RuntimeException("!(0<=piece&&piece<nPieces)");
        }
        long dtNanos=dtNanos();
        if(piece!=previous) {
            if(dtNanos()<=period)
                log.info("piece="+piece);
            log.fine("piece "+piece+" "+dtMillis()+" "+round(dtMillis())+" "+(dt()-dtMillis())+" "+dtNanos()%(period/nPieces)+" "+period/nPieces);
            if(useClip)
                clip=piece==0?null:pieces[piece].shapeAndPrevious;
            // repaint();
            previous=piece;
        }
        double angle=2*PI*((dtNanos()%period)/(double)period);
        Point2D.Double pd=new Point2D.Double((double)radius*cos(angle),radius*sin(angle));
        int x=(int)rint(pd.x);
        int y=(int)rint(pd.y);
        Point p=new Point(x+radius,radius-y);
        line2d=new Line2D.Double(lhsOrigin,p);
        if(false&&useClip&&round(dtNanos()%(period/nPieces))!=0)
            clip=angle==0?null:line2d;
        if(paintImmediately)
            paintImmediately(0,0,2*radius,2*radius);
        else repaint();
    }
    private void createAndShowGUI() {
        System.out.println("start constructing gui");
        setSize(d);
        setPreferredSize(d);
        Frame f=new Frame("X");
        f.setUndecorated(true);
        f.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
        f.add("Center",this);
        gc=getGraphicsConfiguration();
        f.pack();
        if(System.getProperty("user.name").equals("ray")) {
            Rectangle rectangle=f.getBounds();
            rectangle.x+=-700;
            rectangle.y+=1080;
            f.setBounds(rectangle);
        }
        f.setVisible(true);
        System.out.println("end constructing gui");
    }
    public static void main(String[] args) throws InvocationTargetException,InterruptedException {
        RepaintManager rm;
        Y x0;
        if(false)
            x0=new Y(512,400,2000*1000000l); // real app
        else x0=new Y(512,16,10000*1000000l); // easier to see
        final Y x=x0;
        x.log=Logger.getLogger("");
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                x.createAndShowGUI();
            }
        });
        x.init();
    }
    private GraphicsConfiguration gc;
    private BufferedImage bi;
    private P[] pieces;
    private int previous,piece,n;
    private final long t0=System.currentTimeMillis(),t0Nanos=System.nanoTime();
    private final int radius,nPieces;
    private final long period;
    private final Dimension d;
    private final Point lhsOrigin;
    private Shape clip;
    private boolean useClip=true;
    private boolean paintRadialLine=true;
    private boolean paintPieceShape=true;
    private boolean paintImmediately=false; 
    private final ScheduledThreadPoolExecutor stpe=new ScheduledThreadPoolExecutor(2);
    private Line2D line2d;
    private Logger log;
}

谢谢

推荐答案

问题似乎出在 P.shapeAndPrevious 范围不够远。

The problem would appear to be the P.shapeAndPrevious which doesn't extend far enough. Adding to it's size seems to make the extra stuff disappear.

class P extends Piece
{
    P(int piece, int pieces, int radius)
    {
        super(piece, pieces, radius);
        shape = new Arc2D.Double(0, 0, 2 * radius, 2 * radius,
            toDegrees(start), toDegrees(end - start), Arc2D.PIE);       
        shapeAndPrevious = new Arc2D.Double(0 - extra,
            0 - extra,
            2 * radius + extra,
            2 * radius + extra,
            toDegrees((start - 2 * PI / pieces)) - extrad,
            toDegrees((2 * (end - start))) + 2 * extrad,
            Arc2D.PIE);
}

    ...

class P extends Piece
{
    P(int piece, int pieces, int radius)
    {
        super(piece, pieces, radius);
        shape = new Arc2D.Double(0, 0, 2 * radius, 2 * radius,
            toDegrees(start), toDegrees(end - start), Arc2D.PIE);           
        shapeAndPrevious = new Arc2D.Double(0 - extra,
            0 - extra,
            2 * radius + extra + 10, // add some extra
            2 * radius + extra + 10, // add some extra
            toDegrees((start - 2 * PI / pieces) - 1) - extrad,  // add some extra
            toDegrees((2 * (end - start)) + 1) + 2 * extrad,  // add some extra
            Arc2D.PIE);
}

更新

实际上,您似乎已经意识到了这个问题,因为那里有变量可以执行我的硬编码。因此,整个 P 类变为

Actually you seem to have already realised this problem as you've got variables in there to do what I hardcoded. So the whole P class becomes

class P extends Piece
{
    P(int piece, int pieces, int radius)
    {
        super(piece, pieces, radius);
        shape = new Arc2D.Double(0, 0, 2 * radius, 2 * radius,
                toDegrees(start), toDegrees(end - start), Arc2D.PIE);
        shapeAndPrevious = new Arc2D.Double(0 - extra,
                0 - extra,
                2 * radius + extra,
                2 * radius + extra,
                toDegrees((start - 2 * PI / pieces)) - extrad,
                toDegrees((2 * (end - start))) + 2 * extrad,
                Arc2D.PIE);
    }

    final Shape shape, shapeAndPrevious;
    static final int extra = 15; // add some extra
    static final int extrad = 25; // add some extra
}

这似乎仍然在右下方留下了问题没有绘制弧位的手部分位数,但这肯定与剪辑有关。

this still seems to leave a problem on the lower right hand side quantile where the arc bit isn't being drawn, but that is certainly something to do with the clip.

这篇关于如何使用夹子减少喷漆时间?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆