日出日落时间和年均光照时长计算 java

至入行多年仍是新手的我


前言

太阳系行星运行的规律早就被前人研究的彻彻底底,区域气象、楼宇采光等方面对太阳相对地球的运转规律应用还是比较多的。最近对有建筑物遮挡情况下区域光照时长,基于地域观测值对太阳辐射量的计算,做了一些研究,记录一下这段时间学习的过程。


不同专业间的第一道壁垒 基础定义

一、天文知识

这段主要是写定义

1、太阳高度角

是指对地球上的某个地点太阳光入射方向和地平面的夹角
太阳光高度角的定义

2、太阳方位角

自观察者所在地朝正南方向的水平线与太阳光线在地平面上的投影之间的夹角,通常规定,上午的太阳方位角为正,下午的太阳方位角为负。
太阳方位角定义

3、赤纬角

赤纬角又称太阳赤纬,是地球赤道平面与太阳和地球中心的连线之间的夹角。

赤纬角

4、时角

地球自转-周为一天,即24h,不同的时间有不同的时角,以Ω表示之。地球转一周为360°、因而每小时的时角为15°,即以,Ω= 15t,t表示时数。

定义很多,不在赘述,较为重要的是上面三个。

二、计算方法

我们之所以能看的很远,是因为我们站在巨人肩膀上

1、核心计算公式

太阳高度角: h s h_{s} hs:
sin ⁡ ( h s ) = sin ⁡ ( φ ) sin ⁡ ( δ ) + cos ⁡ ( φ ) cos ⁡ ( δ ) cos ⁡ ( Ω ) \sin(h_{s})=\sin(\varphi)\sin(\delta)+\cos(\varphi)\cos(\delta)\cos(\Omega) sin(hs)=sin(φ)sin(δ)+cos(φ)cos(δ)cos(Ω)
太阳方位角 A s A_{s} As:
cos ⁡ ( A s ) = sin ⁡ ( h s ) sin ⁡ ( φ ) − s i n ( δ ) cos ⁡ ( h s ) cos ⁡ ( φ ) \cos(A_{s})=\frac{\sin(h_{s})\sin(\varphi)-sin(\delta)}{\cos(h_s)\cos(\varphi)} cos(As)=cos(hs)cos(φ)sin(hs)sin(φ)sin(δ)
地理纬度: φ \varphi φ
赤纬角: δ \delta δ
δ = 23.45 s i n ( 2 π ∗ 284 + n 365 ) \delta=23.45sin(2\pi*\frac{284+n}{365}) δ=23.45sin(2π365284+n) (单位:°)
n表示天数,1月1日取为1,12月31日取为365。

时角: Ω \Omega Ω
角度的单位要统一 下面的是按照word体系插入的公式
在这里插入图片描述

2、日出日落时间

当太阳高度角为0时,对应时角即为日出日落时刻的时角。
对应 cos ⁡ ( Ω ) = − tan ⁡ ( δ ) tan ⁡ ( φ ) \cos(\Omega)=-\tan(\delta)\tan(\varphi) cos(Ω)=tan(δ)tan(φ)

计算得到时角后,需要转化为角度制,除以15,得到半天的日照时长;用12+或者减去这个值就是日出日落时间。

代码如下(示例):

public class SolarUtil {
    /**
     * 计算赤纬角 δ
     * @param day 一年里面的第几天 如1月1日 1; 12月31 365;
     * @return 角度制 赤纬角
     */
    public static double declination(int day){
        double args = 23.45;
        double season = 2* PI * (284 + day) / 365;
        return args * sin(season);
    }
    
    public static double solarTime2(double latitude,int day){
        // 判断极昼或者极夜
        double flag = latitude * SolarUtil.declination(day);
        double t = Math.acos( Math.tan(latitude * Math.PI / 180) * Math.tan(SolarUtil.declination(day) * Math.PI / 180));
        // 出现极昼或者是极夜
        if (Double.toString(t).equals("NaN")){
            if (flag < 0)
                return 0.0;
            else return 180.0;
        }
        double toDegrees = Math.toDegrees(t);
        return toDegrees;
    }
}

3、年均光照时长

目标是计算建筑物顶部每单元位置处的光照时间,不考虑建筑物的复杂结构,按照简单的长方体进行处理。
包结构
jar包结构

1.建筑物实体类

用左上角和右下角的横纵坐标定义建筑物。

package com.dwind.pojo;

import java.util.ArrayList;

/**
 * @author lcdwind
 * @date 2021/10/29 16:54
 */

public class Building {
    private double height;
    private double RDPointX;
    private double RDPointY;
    private double LUPointX;
    private double LUPointY;

    public Building() {
    }

    public Building(double height, double RDPointX, double RDPointY, double LUPointX, double LUPointY) {
        this.height = height;
        this.RDPointX = RDPointX;
        this.RDPointY = RDPointY;
        this.LUPointX = LUPointX;
        this.LUPointY = LUPointY;
    }

    public double getHeight() {
        return height;
    }

    public void setHeight(double height) {
        this.height = height;
    }

    public double getRDPointX() {
        return RDPointX;
    }

    public void setRDPointX(double RDPointX) {
        this.RDPointX = RDPointX;
    }

    public double getRDPointY() {
        return RDPointY;
    }

    public void setRDPointY(double RDPointY) {
        this.RDPointY = RDPointY;
    }

    public double getLUPointX() {
        return LUPointX;
    }

    public void setLUPointX(double LUPointX) {
        this.LUPointX = LUPointX;
    }

    public double getLUPointY() {
        return LUPointY;
    }

    public void setLUPointY(double LUPointY) {
        this.LUPointY = LUPointY;
    }

    @Override
    public String toString() {
        return "Building{" +
                "height=" + height +
                ", RDPointX=" + RDPointX +
                ", RDPointY=" + RDPointY +
                ", LUPointX=" + LUPointX +
                ", LUPointY=" + LUPointY +
                '}';
    }
}

3.工具类

本来觉得会经常用到,实际上没怎么用,反倒是多写了许多没有用的。

package com.dwind.util;

import static java.lang.Math.*;

/**
 * @author lcdwind
 * @date 2021/10/29 15:45
 */
public class SolarUtil {

    // 计算赤纬角 δ

    /**
     * 计算赤纬角 δ
     * @param day 一年里面的第几天 如1月1日 1; 12月31 365;
     * @return 角度制 赤纬角
     */
    public static double declination(int day){
        double args = 23.45;
        double season = 2* PI * (284 + day) / 365;
        return args * sin(season);
    }

    /**
     * 将当地时间转换为对应时刻得地球自转时角
     * @param tureSoloarTime 真太阳时 例如 12.5 表示12:30
     * @return 角度制 时角
     */
    public static double hourAngle(double tureSoloarTime){
        return  15.0 * (tureSoloarTime - 12);
    }

    /**
     * 返回对应经度下,北京时间相应的当地时间,也就是太阳时。
     * @param longitude 计算位置的经度
     * @param CST 北京时间
     * @param day 一年当中第几天
     * @return 当地太阳时
     */
    public static double trueSoloarTime(double longitude,double CST,double day){
        double B = 2* PI*(day-81) / 364;
        return  CST +(9.87 * sin(2*  B) - 7.53*cos(B) - 1.5*sin(B))/60+ (longitude - 120) / 15.0;
    }

    /**
     *
     * @param longitude 计算位置的经度
     * @param solarTime 当地太阳时
     * @param day 一年中第几天 用于修正地球自转时进动和变动产生的差异
     * @return 北京时间
     */
    public static double CSTTime(double longitude,double solarTime,double day){
        double B = 2* PI*(day-81) / 364;
        return solarTime + (120 - longitude) / 15.0 - (9.87 * sin(2*B) - 7.53*cos(B) - 1.5*sin(B))/60;
    }

    /**
     * 返回太阳高度角
     * @param latitude 纬度 弧度制
     * @param declination 赤纬角 弧度制
     * @param hourAngle 时角 弧度制
     * @return 太阳高度角 弧度制
     */
    public static double solarHight(double latitude, double declination, double hourAngle){
        return asin(sin(latitude) * sin(declination) + cos(latitude) * cos(declination) * cos(hourAngle));
    }

    /**
     * 返回太阳方位角
     * @param solarHight 太阳高度角
     * @param latidude 纬度
     * @param declination 赤纬角
     * @param time 当地太阳时,用于修正太阳方位角的正负值(与12作比较)
     * @return 太阳方位角
     */
    public static double solarAzimuth(double solarHight,double latidude, double declination,double time){

        if (time == 0){
            if(latidude>declination){
                return 0;
            } else {
                return PI;
            }
        }
        double a = (sin(solarHight) * sin(latidude) - sin(declination)) / cos(solarHight) / cos(latidude);
        if (time > 0){
            // time>12 表示下午,方位角为正。
            return acos(a);
        }else {
            // time < 12 上午,方位角为负。
            return -acos(a);
        }

    }


    /**
     * 根据太阳高度角计算太阳时角
     * @param xDiff 用于计算太阳高度角
     * @param yDiff 用于计算太阳高度角
     * @param highDiff 用于计算太阳高度角
     * @param latitude 此地的纬度
     * @param day 一年中的第几天
     * @return 角度制太阳时角
     */
    public static double solarTime(double xDiff,double yDiff,double highDiff,double latitude,int day){
        double sin_Hs = highDiff / Math.sqrt(xDiff * xDiff + yDiff * yDiff + highDiff * highDiff);


        double flag = Math.sin(latitude * Math.PI / 180)* Math.sin(SolarUtil.declination(day) * Math.PI /180);
        double t = Math.acos(sin_Hs - flag /( Math.cos(latitude * Math.PI / 180) * Math.cos(SolarUtil.declination(day) * Math.PI / 180)));
        if (Double.toString(t).equals("NaN")){
            if (flag < 0)
                return 0.0;
            else return 180.0;
        }
        double toDegrees = Math.toDegrees(t);
        return toDegrees;
    }
    public static double solarTime2(double latitude,int day){

        // 判断极昼或者极夜
        double flag = latitude * SolarUtil.declination(day);
        double t = Math.acos( Math.tan(latitude * Math.PI / 180) * Math.tan(SolarUtil.declination(day) * Math.PI / 180));
        // 出现极昼或者是极夜
        if (Double.toString(t).equals("NaN")){
            if (flag < 0)
                return 0.0;
            else return 180.0;
        }
        double toDegrees = Math.toDegrees(t);
        return toDegrees;
    }

    public static double sunDownTime(double latitude, double declination){
        return acos(-tan(latitude)*tan(declination));
    }

    /**
     * 所判断点在两点组成的直线的哪一侧,采用向量法计算,向量方向由点1指向点2
     * @param x1 点1横坐标
     * @param y1 点2纵坐标
     * @param x2 点2横坐标
     * @param y2 点2纵坐标
     * @param tempX 所判断点横坐标
     * @param tempY 所判断点纵坐标
     * @return 返回true表示线上或者右侧,false表示左侧
     */
    public static boolean lineSide(double x1,double y1, double x2,double y2, double tempX,double tempY){

//        if (x2 == x1){
//            return tempX >= x1;
//        }
        if(((tempY-y1)*(x2-x1) - (y2-y1)*(tempX-x1))>0) {
            // 左侧
            return false;
        }else {
            // 线上或者右侧
            return true;
        }

    }

    /**
     * 返回判断点是否在多边形内部
     * @param points 多边形的顶点数组
     * @param tempX 判断点横坐标
     * @param tempY 判断点纵坐标
     * @return 在多边形内或者上面 true,外面false
     */
    public static boolean isCovered(double[][] points,double tempX,double tempY){
        boolean flag = true;
        for (int i =0;i<points.length-1;i ++){
            boolean b = lineSide(points[i][0], points[i][1], points[i + 1][0], points[i + 1][1], tempX, tempY);
            if (!b){
                flag = false;
                break;
            }
        }
        return flag;
    }
}

4.计算部分

package com.dwind.building;

import com.dwind.pojo.Building;
import com.dwind.util.SolarUtil;

import java.util.ArrayList;
import java.util.HashMap;

/**
 * @author lcdwind
 * @date 2021/10/29 16:35
 */
public class Sunshine {
    public HashMap<Building, Double> sunTime(Building target, ArrayList<Building> buildings, double latitude, double longitude) {
        HashMap<String, Double> map = new HashMap<>();
        // 用于记录每个小单元的年均光照时间
        HashMap<Building, Double> cubeMap = new HashMap<>();
        // 切分的单位长度
        double cube = 1.0;
        // target切分成一个个小的单元 单位cube;
        ArrayList<Building> buildingCube = new ArrayList<>();
        for (double xMark = target.getLUPointX(), yMark = target.getRDPointY(); yMark < target.getLUPointY(); yMark += cube) {
            for (; xMark < target.getRDPointX(); xMark += cube) {
                Building building = new Building(target.getHeight(), xMark + cube, yMark, xMark, yMark + cube);
                buildingCube.add(building);
            }
            xMark = target.getLUPointX();
        }


        // 循环计算每一小块儿的年均光照
        for (Building building : buildingCube) {
            map.put("sunHour", 0.0);
            // 循环计算每天的光照情况
            for (int day = 1; day <= 365; day++) {

//遮挡物在建筑物的东边还是西边有区别没有?
                // 这里只判断高度角得出时角是不够精确的,并且在目标建筑物左右两侧的遮挡物并没有做区分处理,两者会被最高最近的结果所覆盖。
                // 有一种思路是根据建筑物的光影图棒长图计算出当日的日照影子时间变化,然后按照3种情况做分析,最后取中心值的点做为标记点也是不错的方法

                // sunUpTime 日出时刻的时角
                double sunUpTime = SolarUtil.solarTime(1, 1, 0, latitude, day);
                // sunUP,sunDown 日出日落时刻
                double sunUp = 12 - sunUpTime / 15;
                double sunDown = 12 + sunUpTime / 15;
                // 一天中没有被遮挡的时间。
                double noCoverTime = 0;
                // 每间隔 0.01*60 分钟采样一次,判断目标位置是否被覆盖
                for (double time = sunUp; time <= sunDown; time += 0.01) {
                    boolean total = true;
                    // 逐个建筑物判断遮挡情况
                    for (Building value : buildings) {
                        // 高度差,太阳高度角,太阳方位角,影子多边形数组
                        double highDiff = value.getHeight() - building.getHeight();
                        double sunHeight = SolarUtil.solarHight(latitude * Math.PI / 180, SolarUtil.declination(day) * Math.PI / 180, Math.abs(time - 12) * 15 * Math.PI / 180);
                        double sunAzimuth = SolarUtil.solarAzimuth(sunHeight, latitude * Math.PI / 180, SolarUtil.declination(day) * Math.PI / 180, time - 12);
                        double[][] polygon = null;
                        double shadowX, shadowY;
                        double shadowOfY = Math.abs(highDiff / Math.tan(sunHeight) * Math.cos(sunAzimuth));
                        double shadowOfX = highDiff / Math.tan(sunHeight) * Math.sin(sunAzimuth);
                        if (time > 12) {
                            // 上午的情况
                            shadowX = value.getLUPointX() - shadowOfX;
                            shadowY = value.getRDPointY() - shadowOfY;
                            polygon = new double[][]{
                                    {value.getRDPointX(), value.getRDPointY()},
                                    {shadowX + (value.getRDPointX() - value.getLUPointX()), shadowY},
                                    {shadowX, shadowY},
                                    {shadowX, shadowY + (value.getLUPointY() - value.getRDPointY())},
                                    {value.getLUPointX(), value.getRDPointY()},
                                    {value.getRDPointX(), value.getRDPointY()}
                            };
                        } else {
                            // 下午的情况
                            shadowX = value.getRDPointX() - shadowOfX;
                            shadowY = value.getRDPointY() - shadowOfY;
                            polygon = new double[][]{
                                    {value.getRDPointX(), value.getLUPointY()},
                                    {shadowX, shadowY + (value.getLUPointY() - value.getRDPointY())},
                                    {shadowX, shadowY},
                                    {shadowX - (value.getRDPointX() - value.getLUPointX()), shadowY},
                                    {value.getLUPointX(), value.getRDPointY()},
                                    {value.getRDPointX(), value.getLUPointY()}
                            };

                        }
                        // 有没有被覆盖
                        boolean covered = SolarUtil.isCovered(polygon, (building.getRDPointX() + building.getLUPointX()) / 2, (building.getLUPointY() + building.getRDPointY()) / 2);

                        if (time <= sunUp || time >= sunDown) {
                            covered = true;
                        }
                        if (covered) {
                            // 任意建筑物覆盖即为覆盖
                            total = false;
                            break;
                        }
                    }
                    if (total) {
                        noCoverTime += 0.01;
                    }
                }
                map.put("sunHour", map.get("sunHour") + noCoverTime);

            }
            cubeMap.put(building, map.get("sunHour"));

        }
        return cubeMap;
    }

}

该处主要是先将周围建筑物的阴影区计算出来,边界点存入数组中,构成一个多边形,判断目标位置是否在多边形区域内,是就意味着在影子范围内,被遮挡。
循环判断每个周边建筑物遮挡情况,循环计算一年中每天的光照时长,最后循环计算每个目标位置的年光照时长。循环非常多,计算非常耗费算力,我的测试用例大概需要23s的运行时长。

6、测试

package com.dwind.building;

import com.dwind.pojo.Building;
import com.dwind.util.SolarUtil;
import org.junit.jupiter.api.Test;

import java.util.ArrayList;
import java.util.HashMap;

import static org.junit.jupiter.api.Assertions.*;

/**
 * @author lcdwind
 * @date 2021/11/1 9:31
 */
class SunshineTest {

    @Test
    void sunTime() {
        Building target = new Building(10, 5, 0, 0, 5);

        Building building = new Building(20, 2, 5, -5, 10);
        Building building1 = new Building(20, 5, 6, 3, 10);

        ArrayList<Building> buildings = new ArrayList<>();
        buildings.add(building);
        buildings.add(building1);

        double latitude = 34.5;
        double longitude = 113.5;
//        70.9 6108.000000000003 79.9 7524.0 85.9 8267.999999999996

        long start = System.currentTimeMillis();
        Sunshine sunshine = new Sunshine();
        HashMap<Building, Double> map = sunshine.sunTime(target, buildings, latitude,longitude);
        System.out.println(map);
        long end = System.currentTimeMillis();
        System.out.println(end - start);
    }
}

测试结果:

{Building{height=10.0, RDPointX=3.0, RDPointY=2.0, LUPointX=2.0, LUPointY=3.0}=2723.4999999999563, Building{height=10.0, RDPointX=4.0, RDPointY=4.0, LUPointX=3.0, LUPointY=5.0}=1665.539999999981, Building{height=10.0, RDPointX=4.0, RDPointY=3.0, LUPointX=3.0, LUPointY=4.0}=2292.6099999999683, Building{height=10.0, RDPointX=5.0, RDPointY=2.0, LUPointX=4.0, LUPointY=3.0}=2907.0799999999567, Building{height=10.0, RDPointX=5.0, RDPointY=3.0, LUPointX=4.0, LUPointY=4.0}=2533.6099999999633, Building{height=10.0, RDPointX=4.0, RDPointY=1.0, LUPointX=3.0, LUPointY=2.0}=3120.6399999999494, Building{height=10.0, RDPointX=5.0, RDPointY=0.0, LUPointX=4.0, LUPointY=1.0}=3385.0299999999424, Building{height=10.0, RDPointX=5.0, RDPointY=4.0, LUPointX=4.0, LUPointY=5.0}=2101.9799999999723, Building{height=10.0, RDPointX=2.0, RDPointY=2.0, LUPointX=1.0, LUPointY=3.0}=2588.4099999999594, Building{height=10.0, RDPointX=2.0, RDPointY=4.0, LUPointX=1.0, LUPointY=5.0}=1172.2899999999863, Building{height=10.0, RDPointX=1.0, RDPointY=1.0, LUPointX=0.0, LUPointY=2.0}=2923.4099999999553, Building{height=10.0, RDPointX=1.0, RDPointY=3.0, LUPointX=0.0, LUPointY=4.0}=1865.1199999999715, Building{height=10.0, RDPointX=2.0, RDPointY=3.0, LUPointX=1.0, LUPointY=4.0}=1956.239999999974, Building{height=10.0, RDPointX=2.0, RDPointY=0.0, LUPointX=1.0, LUPointY=1.0}=3285.299999999948, Building{height=10.0, RDPointX=1.0, RDPointY=2.0, LUPointX=0.0, LUPointY=3.0}=2502.2399999999625, Building{height=10.0, RDPointX=3.0, RDPointY=1.0, LUPointX=2.0, LUPointY=2.0}=3080.9399999999505, Building{height=10.0, RDPointX=5.0, RDPointY=1.0, LUPointX=4.0, LUPointY=2.0}=3174.8799999999483, Building{height=10.0, RDPointX=4.0, RDPointY=2.0, LUPointX=3.0, LUPointY=3.0}=2791.96999999996, Building{height=10.0, RDPointX=3.0, RDPointY=4.0, LUPointX=2.0, LUPointY=5.0}=1539.9799999999827, Building{height=10.0, RDPointX=1.0, RDPointY=0.0, LUPointX=0.0, LUPointY=1.0}=3225.899999999951, Building{height=10.0, RDPointX=3.0, RDPointY=3.0, LUPointX=2.0, LUPointY=4.0}=2182.5799999999695, Building{height=10.0, RDPointX=2.0, RDPointY=1.0, LUPointX=1.0, LUPointY=2.0}=2997.8999999999523, Building{height=10.0, RDPointX=1.0, RDPointY=4.0, LUPointX=0.0, LUPointY=5.0}=1096.6699999999862, Building{height=10.0, RDPointX=3.0, RDPointY=0.0, LUPointX=2.0, LUPointY=1.0}=3339.789999999945, Building{height=10.0, RDPointX=4.0, RDPointY=0.0, LUPointX=3.0, LUPointY=1.0}=3362.059999999947}
20191

总结

写的太慢了,我写不完了

今天主要是练习写博客,分享记录近期的学习情况。

红尘不归尘
关注 关注
  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java根据地址计算日出日落时间(百度地图API)
qq_31350875的博客
05-22 2854
获取百度地图API返回值(基于IP大致定位),并转化为JSON Object import cn.hutool.core.lang.Console; import cn.hutool.http.HttpRequest; import cn.hutool.json.JSONObject; import cn.hutool.json.JSONUtil; /* * 基于IP大致定位 * ...
java版根据日期和经纬度计算日出日落
07-10
main函数需要三个参数,经纬度和距离2000-01-01的天数
Java获取当地的日出日落时间代码分享
09-04
主要介绍了Java获取当地的日出日落时间代码分享,国外猿友写的一个类,需要的朋友可以参考下
java 日出日落时间计算
04-27
通过坐标及时区计算日出日落工具类,内含 java及C++两个版本
太阳天顶角、太阳方位角、日地距离、时差、太阳赤纬角
热门推荐
qq_40843083的博客
11-01 1万+
(1)太阳天顶角 太阳天顶角是太阳光线入射方向和天顶垂直方向的夹角,范围为:0°~180°,其计算公式和太阳赤纬角、目标地区的纬度、太阳时角有关,具体表达式为: 式中,为黄赤交角,为目标地区纬度,其取值范围为-90°~90°正负取决于南北半球,南半球为负,北半球反之,为太阳时角,时角由时差决定,在计算时还需要对时差进行修正。 (2)太阳方位角 方位角计算公式如下: 式中以中午 ...
【C++】太阳高度角的计算(附代码
m0_46253997的博客
07-18 954
本文给出了计算太阳高度角的基本思路和方程,并给出了C++代码
Java 根据经纬度和日期计算出日出和日落时间
qq_40999938的博客
09-01 5018
package com.rtmc.cloud.commons.utils.calculationSunriseAndSunsetTime; import java.math.BigDecimal; import java.text.SimpleDateFormat; import java.util.Date; public class SunRiseSet { private s...
日照计算(日出、日落时间太阳高度角、方位角、日地距离、太阳位置)
10-23
该算法能够根据地球上任意位置计算其日出、日落时间,能够计算该地在指定时间太阳高度角、方位角,能够计算日地距离、太阳位置等。
Java : 香港经纬度和日出日落时间计算工具类
火星男孩的分享空间
06-09 330
日出日落时间按照经纬度的计算
根据经纬度和日期计算日出日落时间
06-28
可以自行输入经纬度和时间计算日出日落时间,亲测误差很小,也就正负2到3分钟
一年四季各个时段阳光照计算
05-13
可以计算房屋被前边遮挡物遮挡后,阳光进入房间的时间
根据经纬度计算日出日落时间算法实现(C#)
05-09
代码已经在项目中应用。 压缩包里附送 日升日落时间计算(2.0版).xls
经纬度和日期计算日出日落时间例程
最新发布
12-18
经纬度和日期计算日出日落时间例程
java 获取est时间_Java获取当地的日出日落时间代码分享
weixin_33771816的博客
02-26 427
/********************************************************************************SunriseSunset.java********************************************************************************** Java Class:...
三元组法矩阵加法java_Radiance基于矩阵的采光计算方法(一)
weixin_39609770的博客
11-02 373
Matrix Based Mrthod基于矩阵的计算方法(2 phase方法)一、基于矩阵采光模拟原理自然光直接或者间接进入室内过程可以用两个独立的变量来考虑,一个是天空的照度,另一个是建筑构件表面的光学属性和几何形状。为了给这一过程建立数学模型我们需要首先对连续的天空模型进行离散化,关于天空模型的离散化,天空被分成许多个小单元。对于每个天空单元对室内自然光照的影响进行建模,然后将所有天...
浅谈日出日落计算方法以及替代工具 - 日出日落 API
海碗吃饭的博客
04-21 829
如果你想知道精确的日落日出时间,又或者你想设计一个日出日落时间查询的应用,又或者你只是好奇点进来了,还是可以过来围观一下涨涨知识,今天想跟大家聊一聊的是日出日落计算方法以及替代工具 - 日出日落 API 。
JAVA根据IP确定时区_2019-05-23 Java根据地址计算日出日落时间(百度地图API)
weixin_36434531的博客
02-28 1030
获取百度地图API返回值(基于IP大致定位),并转化为JSON Objectimport cn.hutool.core.lang.Console;import cn.hutool.http.HttpRequest;import cn.hutool.json.JSONObject;import cn.hutool.json.JSONUtil;/** 基于IP大致定位* */public class ...
日出日落时间计算
土哥的BLOG
05-24 2892
日出时间计算器http://www.xdanger.com/vendors/sun-time/
利用python计算太阳高度角代码
09-10
利用Python计算太阳高度角可以使用天文学公式来实现。其中,太阳高度角是指太阳在天空中的位置,可以用来计算太阳的高度和仰角。 首先,我们需要获取当前的日期、时间和地理位置的经纬度。可以使用Python中的datetime库来获取日期和时间,可以通过调用API获取地理位置的经纬度。 接下来,我们可以使用天文学公式计算太阳高度角。公式如下: cos(α) = sin(δ) * sin(φ) + cos(δ) * cos(φ) * cos(H) 其中,α是太阳高度角,δ是太阳赤纬,φ是地理位置的纬度,H是当地的时角。 我们可以使用Python中的math库来计算sin、cos等数学函数。首先,我们需要计算太阳的赤纬和时角,然后将它们带入公式中计算太阳高度角。 最后,我们将计算出来的太阳高度角打印出来作为结果。以下是一个简单的示例代码: ``` import datetime import math # 获取当前日期和时间 now = datetime.datetime.now() # 获取地理位置的经纬度 latitude = 37.7749 # 纬度 longitude = -122.4194 # 经度 # 计算太阳高度角 def calculate_sun_altitude(now, latitude, longitude): # 计算一年中的第几天 day_of_year = now.timetuple().tm_yday # 计算时角 h = (now.hour + now.minute / 60 + now.second / 3600) / 24 * 360 # 计算太阳赤纬 declination = 23.45 * math.sin(math.radians(360 / 365 * (day_of_year - 81))) # 计算太阳高度角 altitude = math.degrees(math.asin(math.sin(math.radians(declination)) * math.sin(math.radians(latitude)) + math.cos(math.radians(declination)) * math.cos(math.radians(latitude)) * math.cos(math.radians(h)))) return altitude # 调用函数计算太阳高度角 altitude = calculate_sun_altitude(now, latitude, longitude) # 打印结果 print("太阳高度角:", altitude) ``` 请注意,以上代码只是一个简单的示例,实际上,在计算太阳高度角时还需要考虑一些其他因素,例如地平方向的大气折射等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
写文章

热门文章

  • mysql远程访问 6560
  • 日出日落时间和年均光照时长计算 java 3632
  • 对Java世界的一声呐喊,Java程序工作原理。 175
  • java的注释 167

您愿意向朋友推荐“博客详情页”吗?

  • 强烈不推荐
  • 不推荐
  • 一般般
  • 推荐
  • 强烈推荐
提交

最新文章

  • mysql远程访问
  • java的注释
  • 对Java世界的一声呐喊,Java程序工作原理。
2022年1篇
2021年1篇
2019年2篇

目录

目录

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值

PHP网站源码铜川网站seo优化推荐吴忠关键词按天收费推荐廊坊推广网站多少钱萍乡设计网站公司上饶seo青岛seo网站推广推荐萍乡阿里店铺运营公司阿里模板推广公司包头网站建设价格达州网站优化长春百度爱采购公司承德网站改版报价滁州网站推广工具哪家好揭阳英文网站建设大鹏百姓网标王多少钱桐城建设网站宁德关键词按天扣费多少钱文山百度网站优化运城网站建设报价延边百度竞价价格遵义营销型网站建设多少钱信阳设计网站价格怒江建设网站价格松岗网站定制推荐西安关键词排名多少钱菏泽网站seo优化哪家好罗湖网站优化推广推荐黑河品牌网站设计哪家好西宁建设网站哪家好莱芜SEO按天计费价格歼20紧急升空逼退外机英媒称团队夜以继日筹划王妃复出草木蔓发 春山在望成都发生巨响 当地回应60岁老人炒菠菜未焯水致肾病恶化男子涉嫌走私被判11年却一天牢没坐劳斯莱斯右转逼停直行车网传落水者说“没让你救”系谣言广东通报13岁男孩性侵女童不予立案贵州小伙回应在美国卖三蹦子火了淀粉肠小王子日销售额涨超10倍有个姐真把千机伞做出来了近3万元金手镯仅含足金十克呼北高速交通事故已致14人死亡杨洋拄拐现身医院国产伟哥去年销售近13亿男子给前妻转账 现任妻子起诉要回新基金只募集到26元还是员工自购男孩疑遭霸凌 家长讨说法被踢出群充个话费竟沦为间接洗钱工具新的一天从800个哈欠开始单亲妈妈陷入热恋 14岁儿子报警#春分立蛋大挑战#中国投资客涌入日本东京买房两大学生合买彩票中奖一人不认账新加坡主帅:唯一目标击败中国队月嫂回应掌掴婴儿是在赶虫子19岁小伙救下5人后溺亡 多方发声清明节放假3天调休1天张家界的山上“长”满了韩国人?开封王婆为何火了主播靠辱骂母亲走红被批捕封号代拍被何赛飞拿着魔杖追着打阿根廷将发行1万与2万面值的纸币库克现身上海为江西彩礼“减负”的“试婚人”因自嘲式简历走红的教授更新简介殡仪馆花卉高于市场价3倍还重复用网友称在豆瓣酱里吃出老鼠头315晚会后胖东来又人满为患了网友建议重庆地铁不准乘客携带菜筐特朗普谈“凯特王妃P图照”罗斯否认插足凯特王妃婚姻青海通报栏杆断裂小学生跌落住进ICU恒大被罚41.75亿到底怎么缴湖南一县政协主席疑涉刑案被控制茶百道就改标签日期致歉王树国3次鞠躬告别西交大师生张立群任西安交通大学校长杨倩无缘巴黎奥运

PHP网站源码 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化