zoukankan      html  css  js  c++  java
  • 基于APE物理引擎的管线容积率计算方法

    容积率一般应用在房地产开发中,是指用地范围内地上总建筑面积与项目总用地面积的比值,这个参数是衡量建设用地使用强度的一项非常重要的指标。在其他行业,容积率的计算也非常重要,如产品利用率、管道使用率等等。那么在监控系统中,如何能够生动形象的表达容积率的计算,是的监控系统具有准确性、安全性的同时,还具备了多样性,良好交互性等等。 最近的游戏产业发展也非常迅速,在手持终端3D的游戏也越来越多,那么如果我们将游戏引擎融入到监控系统中,会实现什么样的效果呢,本文重点介绍使用APE物理引擎结合TWaver 2D产品实现管线的容积率计算。 先来看下效果:
    guandao2
    物理引擎很多,我们使用比较容易入手的APE引擎,首先要对APE物理引擎有所了解,可以下载经典的APEdemo进行研究,下载链接:APE物理引擎Demo(提取密码:eyjm)。简单的介绍下APE:

    AbstractCollection  所有群组的抽象类

    AbstractConstraint  所有物理相互作用的的抽象类

    AbstractItem  所有相互作用(碰撞)、粒子的基类

    AbstractParticle  关于粒子的基类

    APEngine  主引擎、力的类

    CircleParticle  圆形粒子

    RectangleParticle  矩形粒子

    Composite  可以包含粒子和碰撞的复合物类

    Group  一个组的类,可以包含粒子、碰撞、复合物

    SpringConstraint  两个粒子之间类似弹性碰撞的类(弹簧)

    Vector  

    WheelParticle  一个粒子,模拟轮子行为

    接下来开始结合TWaver 2D产品:

    1.创建一个具有物理参数的网元CircleParticle:类CircleParticle继承于AbstractParticle,AbstractParticle继承于TWaver的Node网元;

    import java.awt.geom.*;
    import twaver.TWaverConst;
        public class CircleParticle extends AbstractParticle {
            private double _radius;
    
            @Override
            public String getUIClassID() {
                return CircleParticleUI.class.getName();
            }
            
            public CircleParticle (
                    double x, 
                    double y, 
                    double radius, 
                    boolean fixed,
                    double mass, 
                    double elasticity,
                    double friction) {
                super(x, y, fixed, mass, elasticity, friction);
                _radius = radius;
    
                if((Double.valueOf(x) != null) && (Double.valueOf(y) != null)){
                    this.setLocation(x, y);
                }
                
                this.putCustomDraw(true);
                this.putCustomDrawShapeFactory(TWaverConst.SHAPE_CIRCLE);
            }
    
            @Override
            public int getWidth() {
                // TODO Auto-generated method stub
                if(Double.valueOf(_radius) != null){
                    return (int) _radius*2;
                }
                return super.getWidth();
            }
            
            @Override
            public int getHeight() {
                // TODO Auto-generated method stub
                if(Double.valueOf(_radius) != null){
                    return (int) _radius*2;
                }
                return super.getHeight();
            }
            
            public double getRadius() {
                return _radius;
            }        
            
            public void setRadius(double r) {
                _radius = r;
            }
            
            public void paint() {    
                if(curr.y > 500) return;
                if(Math.pow(curr.x+_radius-330,2) + Math.pow(curr.y+_radius-240, 2) > 150*150){
                    return;
                }
                this.setLocation((int)(curr.x - getRadius()), (int)(curr.y - getRadius()));
            }
        
            public Interval getProjection(Vector axis) {
                double c = curr.dot(axis);
                interval.min = c - _radius;
                interval.max = c + _radius;
                return interval;
            }
            
            public Interval getIntervalX() {
                interval.min = curr.x - _radius;
                interval.max = curr.x + _radius;
                return interval;
            }
                    
            public Interval getIntervalY() {
                interval.min = curr.y - _radius;
                interval.max = curr.y + _radius;
                return interval;
            }
        }

    2.另外创建一个视图类CircleParticleUI类,继承NodeUI,用于绘制网元。

    import twaver.Node;
    import twaver.network.TNetwork;
    
    public class CircleParticleUI extends AbstractParticeUI{
    
        public CircleParticleUI(TNetwork network, Node node) {
            super(network, node);
        }
    }

    这样物理引擎下的网元就创建成功了,接下来就可以按照TWaver的方式创建加载网元了。

    //初始化场景,加载网元到box和物理引擎中
    private void initWorld(){
    APEngine.init((double) 1 / 5);
            APEngine.setCollisionResponseMode(APEngine.STANDARD);
            APEngine.addMasslessForce(new Vector(0, 10));
    
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    int Count = 500;
                    for (int i = 0; i < Count; i++) {
                        float centerX = 330;
                        float centerY = 240;
                        float radius = 150;
                        float x = (float) (centerX + radius
                                * Math.cos(Math.PI * 2 / Count * i));
                        float y = (float) (centerY + radius
                                * Math.sin(Math.PI * 2 / Count * i));
    
                        CircleParticle circle = new CircleParticle(x, y, 1, true, 1, 0, 1);
                        APEngine.addParticle(circle);
                        box.addElement(circle);
                        i++;
                    }
                    
                }
            });
            
            paintQueue = APEngine.getAll();
        }
    //更新容积率以及告警显示规则
    public void updateWorld() {
        APEngine.step();
        alarm.setName(Count+"个管道"+"/剩余面积:"+remainS/totalS*100+"%");
        if(remainS/totalS*100 <15){
            AlarmState alarmState = alarm.getAlarmState();
            alarmState.increaseNewAlarm(AlarmSeverity.MINOR, 1);
            alarm.putClientProperty("alarm", "alarm");
            flag = false;
        }
        }
    
    //绘制网元
        public void paintWorld() {
        for (int i = 0; i < paintQueue.size(); i++) {
            if (paintQueue.get(i) instanceof CircleParticle) {
                ((CircleParticle) paintQueue.get(i)).paint();    
                }
        }
        }
    //最后设置场景更新规则
    private void game() {
        usedTime = 1000;
        t = 0;
        initWorld();
        while (flag) {
        t++;
        long startTime = System.currentTimeMillis();
        updateWorld();
        paintWorld();
        usedTime = System.currentTimeMillis() - startTime;
        try {
            Thread.sleep(30);
        } catch (InterruptedException e) {
            }
        }
    }

    这样一个监控容积率计算的平台就完成了,当然建立在各种物理引擎之上可以完成更加丰富的表达方式,如果您有这方面的需求和想法,欢迎和我们进行探讨!

  • 相关阅读:
    Vue的style与class
    position记录
    JS 原型模式创建对象
    Js 栈和堆的实现
    slice深拷贝数组
    Vue路由query传参
    Object.prototype.toString.call(value)
    Node里面的对象创建问题
    Django模板语言 标签整理
    JavaScript基础
  • 原文地址:https://www.cnblogs.com/twaver/p/4233216.html
Copyright © 2011-2022 走看看