DA14695---multi-link简单解析

2024-08-22 00:52
文章标签 简单 解析 link multi da14695

本文主要是介绍DA14695---multi-link简单解析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、system_init

        在system_init中创建ble_multi_link_task任务,先是开启了BLE管理器,再注册ble_multi_link_task任务

 /* Initialize BLE Manager */ble_mgr_init();/* Start the Multi-Link application task. */OS_TASK_CREATE("Multi-Link",                    /* The text name assigned to the task, fordebug only; not used by the kernel. */ble_multi_link_task,             /* The function that implements the task. */NULL,                            /* The parameter passed to the task. */200 * OS_STACK_WORD_SIZE,        /* The number of bytes to allocate to thestack of the task. */mainBLE_MULTI_LINK_TASK_PRIORITY,/* The priority assigned to the task. */handle);                         /* The task handle. */OS_ASSERT(handle);
二、ble_multi_link_task

        从上到下依次做了

注册一个看门狗

        wdog_id = sys_watchdog_register(false);

 使能BLE

         status = ble_enable();

设置设备角色为外围设备和中心设备

         ble_gap_role_set(GAP_PERIPHERAL_ROLE | GAP_CENTRAL_ROLE);

注册本任务到BLE框架中,用于后面接收BLE栈的事件通知

        ble_register_app();

设置设备名称,设备名是存储在GATT服务中的一般在设备连接后来读取,与广播数据中的设备名是未连接状态下就可以被扫描看见的也就是手机上扫描BLE时显示的,他们两个可以一样但性质不一样。

         ble_gap_device_name_set("Dialog Multi-link", ATT_PERM_READ);

添加注册一个服务,bd_addr_write_cb后续在讲

         dlg_mls_init(bd_addr_write_cb);

设置广播数据和开始广播

        ble_gap_adv_data_set(sizeof(adv_data), adv_data, 0, NULL);
        ble_gap_adv_start(GAP_CONN_MODE_UNDIRECTED);

主循环,定时通知看门狗,等待BLE发送通知 ,再根据不同的BLE事件进行不同的回调处理

        if (notif & BLE_APP_NOTIFY_MASK)这里是在判断接收到的通知是不是属于BLE发来的,如果是就进行BLE事件的处理。

 完整代码

/******************************************************************************************** @file ble_multi_link_task.c** @brief Multi-Link Demo task** Copyright (C) 2015-2019 Dialog Semiconductor.* This computer program includes Confidential, Proprietary Information* of Dialog Semiconductor. All Rights Reserved.******************************************************************************************/#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <stdio.h>
#include "sdk_queue.h"
#include "osal.h"
#include "timers.h"
#include "osal.h"
#include "sys_watchdog.h"
#include "ble_att.h"
#include "ble_common.h"
#include "ble_gap.h"
#include "ble_gatts.h"
#include "ble_service.h"
#include "dlg_mls.h"/** Multi-link demo advertising data*/
static const uint8_t adv_data[] = {0x12, GAP_DATA_TYPE_LOCAL_NAME,'D', 'i', 'a', 'l', 'o', 'g', ' ', 'M', 'u', 'l', 't', 'i', '-', 'l', 'i', 'n', 'l'
};static const gap_conn_params_t cp = {.interval_min  = BLE_CONN_INTERVAL_FROM_MS(50),     // 50.00 ms.interval_max  = BLE_CONN_INTERVAL_FROM_MS(70),     // 70.00 ms.slave_latency = 0,.sup_timeout   = BLE_SUPERVISION_TMO_FROM_MS(420),  // 420.00 ms
};typedef struct {void            *next;bd_address_t    addr;uint16_t        conn_idx;
} conn_dev_t;__RETAINED static enum conn_cancel_reason {CONN_CANCEL_REASON_ADV_ERR,CONN_CANCEL_REASON_DEV_NOT_RESPONDING,
} conn_canceled_reason;__RETAINED static queue_t connections;__RETAINED_RW static uint16_t master_dev_conn_idx = BLE_CONN_IDX_INVALID;__RETAINED static bool connecting;__RETAINED static bd_address_t new_dev_addr;/** Debug functions*/static const char *format_bd_address(const bd_address_t *addr)
{static char buf[19];int i;for (i = 0; i < sizeof(addr->addr); i++) {int idx;// for printout, address should be reversedidx = sizeof(addr->addr) - i - 1;sprintf(&buf[i * 3], "%02X:", addr->addr[idx]);}buf[sizeof(buf) - 2] = '\0';return buf;
}static void print_connection_func(void *data, void *user_data)
{const conn_dev_t *conn_dev = data;int *num = user_data;(*num)++;printf("%2d | %5d | %s\r\n", *num, conn_dev->conn_idx,format_bd_address(&conn_dev->addr));
}static void print_connections(void)
{int num = 0;printf("\r\n");printf("Nr | Index | Address\r\n");queue_foreach(&connections, print_connection_func, &num);if (!num) {printf("(no active connections)\r\n");}printf("\r\n");
}bool list_elem_match(const void *elem, const void *ud)
{conn_dev_t *conn_dev = (conn_dev_t *) elem;uint16_t *conn_idx = (uint16_t *) ud;return conn_dev->conn_idx == *conn_idx;
}static void bd_addr_write_cb(ble_service_t *svc, uint16_t conn_idx, const bd_address_t *addr)
{
//    printf("bd_addr_write_cb,addr_type_t:%d",addr->addr_type);
//    // 以十六进制格式打印地址
//       printf("Address (Hex): ");
//       for(int i = 0; i < 6; i++) {
//           printf("%02X", addr->addr[i]);
//           if (i < 5) {
//               printf(":");
//           }
//       }ble_error_t status;status = ble_gap_connect(addr, &cp);if (status != BLE_STATUS_OK && status != BLE_ERROR_BUSY) {printf("%s: failed. Status=%d\r\n", __func__, status);}if (status == BLE_ERROR_BUSY) {new_dev_addr = *addr;conn_canceled_reason = CONN_CANCEL_REASON_DEV_NOT_RESPONDING;/** ble_gap_connect() will return a BLE_ERROR_BUSY status when another connection* procedure is already ongoing. To be able to connect to another device, cancel* the last connection request to retry connecting with the new device.*/ble_gap_connect_cancel();}connecting = (status == BLE_STATUS_OK);
}static void handle_evt_gap_connected(ble_evt_gap_connected_t *evt)
{conn_dev_t *conn_dev;printf("Device connected\r\n");printf("\tConnection index: %u\r\n", evt->conn_idx);printf("\tAddress: %s %s\r\n",evt->peer_address.addr_type == PUBLIC_ADDRESS ? "public" : "private",ble_address_to_string(&evt->peer_address));conn_dev = OS_MALLOC(sizeof(conn_dev_t));conn_dev->addr.addr_type = evt->peer_address.addr_type;memcpy(conn_dev->addr.addr, evt->peer_address.addr, sizeof(conn_dev->addr.addr));conn_dev->conn_idx = evt->conn_idx;queue_push_front(&connections, (void *)conn_dev);if (master_dev_conn_idx == BLE_CONN_IDX_INVALID) {master_dev_conn_idx = evt->conn_idx;}connecting = false;print_connections();
}static void handle_evt_gap_conn_completed(ble_evt_gap_connection_completed_t *evt)
{if (master_dev_conn_idx != BLE_CONN_IDX_INVALID &&conn_canceled_reason != CONN_CANCEL_REASON_DEV_NOT_RESPONDING) {return;}/* Process only then if the connection was completed not by intended cancellation then  */if (evt->status != BLE_ERROR_CANCELED) {return;}if (conn_canceled_reason == CONN_CANCEL_REASON_DEV_NOT_RESPONDING) {ble_error_t status;printf("%s: Last connection request was canceled. Connecting to new device...\r\n",__func__);status = ble_gap_connect(&new_dev_addr, &cp);printf("%s: Status=%d\r\n", __func__, status);} else if (conn_canceled_reason == CONN_CANCEL_REASON_ADV_ERR) {printf("%s: cancel the connect\r\n", __func__);ble_gap_adv_start(GAP_CONN_MODE_UNDIRECTED);printf("Advertising is on again after error\r\n");} else {printf("Undefined cancellation reason\r\n");}
}static void handle_evt_gap_disconnected(ble_evt_gap_disconnected_t *evt)
{printf("Device disconnected\r\n");printf("\tConnection index: %u\r\n", evt->conn_idx);printf("\tBD address of disconnected device: %s, %s\r\n",evt->address.addr_type == PUBLIC_ADDRESS ? "public" : "private",ble_address_to_string(&evt->address));printf("\tReason of disconnection: 0x%02x\r\n", evt->reason);conn_dev_t *conn_dev = queue_remove(&connections, list_elem_match, &evt->conn_idx);if (conn_dev) {OS_FREE(conn_dev);}print_connections();if (master_dev_conn_idx == evt->conn_idx) {master_dev_conn_idx = BLE_CONN_IDX_INVALID;ble_gap_adv_start(GAP_CONN_MODE_UNDIRECTED);printf("Advertising is on again\r\n");}
}static void handle_evt_gap_adv_completed(ble_evt_gap_adv_completed_t *evt)
{printf("Advertising completed\r\n");printf("\tAdvertising type: %d\r\n", evt->adv_type);printf("\tCompletion status: 0x%02x\r\n", evt->status);if (connecting && (evt->status == BLE_ERROR_NOT_ALLOWED)) {connecting = false;conn_canceled_reason = CONN_CANCEL_REASON_ADV_ERR;ble_gap_connect_cancel();}
}static void handle_evt_gap_pair_req(ble_evt_gap_pair_req_t *evt)
{printf("Pair request\r\n");printf("\tConnection index: %d\r\n", evt->conn_idx);printf("\tBond: %s\r\n", evt->bond ? "true" : "false");ble_gap_pair_reply(evt->conn_idx, true, evt->bond);
}static void handle_evt_gap_security_request(ble_evt_gap_security_request_t *evt)
{ble_error_t status;status = ble_gap_pair(evt->conn_idx, evt->bond);if (status != BLE_STATUS_OK) {printf("%s: failed. Status=%d\r\n", __func__, status);}
}void ble_multi_link_task(void *params)
{ble_error_t status;int8_t wdog_id;/* Register ble_multi_link task to be monitored by watchdog */wdog_id = sys_watchdog_register(false);/* Enable BLE */status = ble_enable();if (status == BLE_STATUS_OK) {/* Set all roles */ble_gap_role_set(GAP_PERIPHERAL_ROLE | GAP_CENTRAL_ROLE);} else {printf("%s: failed. Status=%d\r\n", __func__, status);}/* Register task to BLE framework to receive BLE event notifications */ble_register_app();/* Set device name */ble_gap_device_name_set("Dialog Multi-link", ATT_PERM_READ);/* Add Multi-Link Service */dlg_mls_init(bd_addr_write_cb);/* Set advertising data and start advertising */ble_gap_adv_data_set(sizeof(adv_data), adv_data, 0, NULL);ble_gap_adv_start(GAP_CONN_MODE_UNDIRECTED);printf("Advertising is on\r\n");for (;;) {OS_BASE_TYPE ret;uint32_t notif;/* Notify watchdog on each loop */sys_watchdog_notify(wdog_id);/* Suspend watchdog while blocking on OS_TASK_NOTIFY_WAIT() */sys_watchdog_suspend(wdog_id);/** Wait on any of the notification bits, then clear them all*/ret = OS_TASK_NOTIFY_WAIT(0, OS_TASK_NOTIFY_ALL_BITS, &notif, OS_TASK_NOTIFY_FOREVER);/* This must block forever, until a task notification is received. So, thereturn value must be OS_TASK_NOTIFY_SUCCESS */OS_ASSERT(ret == OS_TASK_NOTIFY_SUCCESS);/* Resume watchdog */sys_watchdog_notify_and_resume(wdog_id);/* Notified from BLE Manager? */if (notif & BLE_APP_NOTIFY_MASK) {ble_evt_hdr_t *hdr;hdr = ble_get_event(false);     //有没有事件if (!hdr) {goto no_event;          //没有事件}if (!ble_service_handle_event(hdr)) {       //有事件但没有被处理switch (hdr->evt_code) {case BLE_EVT_GAP_CONNECTED:handle_evt_gap_connected((ble_evt_gap_connected_t *) hdr);break;case BLE_EVT_GAP_CONNECTION_COMPLETED:handle_evt_gap_conn_completed((ble_evt_gap_connection_completed_t *) hdr);break;case BLE_EVT_GAP_DISCONNECTED:handle_evt_gap_disconnected((ble_evt_gap_disconnected_t *) hdr);break;case BLE_EVT_GAP_ADV_COMPLETED:handle_evt_gap_adv_completed((ble_evt_gap_adv_completed_t *) hdr);break;case BLE_EVT_GAP_PAIR_REQ:handle_evt_gap_pair_req((ble_evt_gap_pair_req_t *) hdr);break;case BLE_EVT_GAP_SECURITY_REQUEST:handle_evt_gap_security_request((ble_evt_gap_security_request_t *) hdr);break;default:ble_handle_event_default(hdr);break;}}OS_FREE(hdr);no_event:               //处理没有事件的情况/* Notify again if there are more events to process in queue */if (ble_has_event()) {  //检查是否还有其他事件待处理//如果还有事件,重新通知当前任务,确保任务会再次被唤醒来处理这些事件OS_TASK_NOTIFY(OS_GET_CURRENT_TASK(), BLE_APP_NOTIFY_MASK,OS_NOTIFY_SET_BITS);}}}
}
三、dlg_mls_init

        从上到下依次做了 

申请并清空了一个自定义的服务结构体

        ml_service_t *dlg_mls;

        dlg_mls = OS_MALLOC(sizeof(ml_service_t));
        memset(dlg_mls, 0, sizeof(ml_service_t));

ml_service_t 结构体如下

typedef struct {

ble_service_t svc;                                      //BLE 服务的基本结构体

bd_addr_write_cb_t addr_write_cb;          //指向外设地址写回调函数的指针

uint16_t periph_addr_val_h;                      //服务的特征句柄,用于后面处理写请求

} ml_service_t;

 计算获得服务的属性数量

        num_attr = ble_gatts_get_num_attr(0, 1, 0);

3个参数分别为

  • 0: 服务中的包含数。
  • 1: 特征数。
  • 0: 特征描述符的数量。

将服务的 UUID 字符串(UUID_DLG_MLS)转换为 att_uuid_t 类型的 UUID,并存储在 uuid 变量中。 

        ble_uuid_from_string(UUID_DLG_MLS, &uuid);

添加一个新的 BLE 服务:

        ble_gatts_add_service(&uuid, GATT_SERVICE_PRIMARY, num_attr);

  • &uuid: 指向服务的 UUID。
  • GATT_SERVICE_PRIMARY: 表示这是一个主服务。
  • num_attr: 服务的属性数量(包括特征、描述符等)。

将特征的 UUID 字符串(UUID_DLG_MLS_PERIPHERAL_ADDR)转换为 att_uuid_t 类型的 UUID,并存储在 uuid 变量中。

        ble_uuid_from_string(UUID_DLG_MLS_PERIPHERAL_ADDR, &uuid);

添加一个新的特征到刚刚创建的服务中:

        ble_gatts_add_characteristic(&uuid, GATT_PROP_WRITE_NO_RESP, ATT_PERM_WRITE, 7, 0, NULL, &dlg_mls->periph_addr_val_h);

  • &uuid: 指向特征的 UUID。
  • GATT_PROP_WRITE_NO_RESP: 特征属性,表示特征支持无应答的写操作。
  • ATT_PERM_WRITE: 特征的权限,表示该特征可以被写入。
  • 7: 特征值的最大长度(字节数)。
  • 0: 不使用额外的安全权限。
  • NULL: 初始值为空。
  • &dlg_mls->periph_addr_val_h: 存储特征的句柄,稍后会用于标识这个特征。

注册服务及其所有特征:

        ble_gatts_register_service(&dlg_mls->svc.start_h, &dlg_mls->periph_addr_val_h, 0);

  • &dlg_mls->svc.start_h: 存储服务的起始句柄。
  • &dlg_mls->periph_addr_val_h: 存储特征的句柄(已在上一步中设置)。
  • 0: 表示无更多的特征需要注册。

计算并设置服务的结束句柄。服务的结束句柄等于起始句柄加上属性数量。

        dlg_mls->svc.end_h = dlg_mls->svc.start_h + num_attr;

设置服务的写请求处理函数,将 handle_write_req 函数指针赋值给服务的 write_req 字段,以处理特征的写请求。

        dlg_mls->svc.write_req = handle_write_req;

将传入的回调函数 addr_write_cb 赋值给 dlg_mls 结构体的 addr_write_cb 字段。这个回调将在写请求处理过程中被调用。这里就是前面的dlg_mls_init(bd_addr_write_cb);参数

        dlg_mls->addr_write_cb = addr_write_cb;

将刚刚创建并初始化好的服务添加到 BLE 框架中,使其可以被外部设备访问。

        ble_service_add(&dlg_mls->svc);

完整代码

/******************************************************************************************** @file dlg_mls.c** @brief Dialog Multi-Link Service sample implementation** Copyright (C) 2015-2017 Dialog Semiconductor.* This computer program includes Confidential, Proprietary Information* of Dialog Semiconductor. All Rights Reserved.******************************************************************************************/#include <stdbool.h>
#include <stddef.h>
#include <string.h>
#include "osal.h"
#include "ble_gatts.h"
#include "ble_uuid.h"
#include "svc_defines.h"
#include "dlg_mls.h"#define UUID_DLG_MLS                        "3292546e-0a42-4348-aa38-33aab6f9af93"
#define UUID_DLG_MLS_PERIPHERAL_ADDR        "3292546e-0a42-4348-aa38-33aab6f9af94"typedef struct {ble_service_t svc;bd_addr_write_cb_t addr_write_cb;uint16_t periph_addr_val_h;
} ml_service_t;static att_error_t handle_peripheral_address_write(ml_service_t *dlg_mls, uint16_t conn_idx,uint16_t offset, uint16_t length, const uint8_t *value)
{
//        printf("handle_peripheral_address_write\r\n");if (!dlg_mls->addr_write_cb) {return ATT_ERROR_WRITE_NOT_PERMITTED;}if (length != sizeof(bd_address_t) || !value) {return ATT_ERROR_INVALID_VALUE_LENGTH;}if (value[0] != PUBLIC_ADDRESS && value[0] != PRIVATE_ADDRESS) {return ATT_ERROR_APPLICATION_ERROR;}dlg_mls->addr_write_cb(&dlg_mls->svc, conn_idx, (bd_address_t *) value);return ATT_ERROR_OK;
}static void handle_write_req(ble_service_t *svc, const ble_evt_gatts_write_req_t *evt)
{
//    printf("handle_write_req\r\n");ml_service_t *dlg_mls = (ml_service_t *) svc;att_error_t status = ATT_ERROR_ATTRIBUTE_NOT_FOUND;if (evt->handle == dlg_mls->periph_addr_val_h) {status = handle_peripheral_address_write(dlg_mls, evt->conn_idx, evt->offset,evt->length, evt->value);}ble_gatts_write_cfm(evt->conn_idx, evt->handle, status);
}ble_service_t *dlg_mls_init(bd_addr_write_cb_t addr_write_cb)
{uint16_t num_attr;ml_service_t *dlg_mls;att_uuid_t uuid;dlg_mls = OS_MALLOC(sizeof(ml_service_t));memset(dlg_mls, 0, sizeof(ml_service_t));num_attr = ble_gatts_get_num_attr(0, 1, 0);ble_uuid_from_string(UUID_DLG_MLS, &uuid);ble_gatts_add_service(&uuid, GATT_SERVICE_PRIMARY, num_attr);ble_uuid_from_string(UUID_DLG_MLS_PERIPHERAL_ADDR, &uuid);ble_gatts_add_characteristic(&uuid, GATT_PROP_WRITE_NO_RESP, ATT_PERM_WRITE,7, 0, NULL, &dlg_mls->periph_addr_val_h);ble_gatts_register_service(&dlg_mls->svc.start_h, &dlg_mls->periph_addr_val_h, 0);dlg_mls->svc.end_h = dlg_mls->svc.start_h + num_attr;dlg_mls->svc.write_req = handle_write_req;dlg_mls->addr_write_cb = addr_write_cb;ble_service_add(&dlg_mls->svc);return &dlg_mls->svc;
}

创建完后生成的服务,其服务的UUID与一个特征值的UUID一一对应

四、向上写数据的流程
  • 当手机端向 BLE 设备写入数据时,设备会触发 handle_write_req 函数,该函数负责处理所有写入请求。
  • handle_write_req 检查写请求的 handle 是否与 dlg_mls->periph_addr_val_h 匹配,这意味着客户端请求写入的是设备的外设地址特性。如果匹配,则调用 handle_peripheral_address_write 函数来处理写入操作,并将结果返回到 status
  • 在handle_peripheral_address_write做数据检查,检查都通过了,调用 addr_write_cb 回调函数,将写入的地址数据传递给回调函数进行进一步处理。
  • addr_write_cb(&dlg_mls->svc, conn_idx, (bd_address_t *) value);回调函数
    • &dlg_mls->svc:

      • 这是一个指向 BLE 服务 (ble_service_t) 的指针,表示当前正在处理的 BLE 服务实例。在回调函数中,这个指针可以用于获取或操作服务的相关信息。
    • conn_idx:

      • 这是一个 uint16_t 类型的值,表示当前连接的索引。它唯一标识了设备与客户端之间的连接。在回调函数中,可以用它来区分来自不同连接的请求。
    • (bd_address_t *) value:

      • 这是一个指向 bd_address_t 类型的指针,bd_address_t 结构体表示一个蓝牙设备的地址(包含地址类型和实际地址)。
      • value 是一个指向原始数据的 uint8_t 指针,在这里被强制转换为 bd_address_t 类型。在回调函数中,可以通过这个指针来访问写入的设备地址。
  • 写入操作完成后,设备将结果通过 ble_gatts_write_cfm 函数反馈给手机端,告知操作是否成功。

 

 

 

这篇关于DA14695---multi-link简单解析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1094770

相关文章

网页解析 lxml 库--实战

lxml库使用流程 lxml 是 Python 的第三方解析库,完全使用 Python 语言编写,它对 XPath表达式提供了良好的支 持,因此能够了高效地解析 HTML/XML 文档。本节讲解如何通过 lxml 库解析 HTML 文档。 pip install lxml lxm| 库提供了一个 etree 模块,该模块专门用来解析 HTML/XML 文档,下面来介绍一下 lxml 库

csu 1446 Problem J Modified LCS (扩展欧几里得算法的简单应用)

这是一道扩展欧几里得算法的简单应用题,这题是在湖南多校训练赛中队友ac的一道题,在比赛之后请教了队友,然后自己把它a掉 这也是自己独自做扩展欧几里得算法的题目 题意:把题意转变下就变成了:求d1*x - d2*y = f2 - f1的解,很明显用exgcd来解 下面介绍一下exgcd的一些知识点:求ax + by = c的解 一、首先求ax + by = gcd(a,b)的解 这个

hdu2289(简单二分)

虽说是简单二分,但是我还是wa死了  题意:已知圆台的体积,求高度 首先要知道圆台体积怎么求:设上下底的半径分别为r1,r2,高为h,V = PI*(r1*r1+r1*r2+r2*r2)*h/3 然后以h进行二分 代码如下: #include<iostream>#include<algorithm>#include<cstring>#include<stack>#includ

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

usaco 1.3 Prime Cryptarithm(简单哈希表暴搜剪枝)

思路: 1. 用一个 hash[ ] 数组存放输入的数字,令 hash[ tmp ]=1 。 2. 一个自定义函数 check( ) ,检查各位是否为输入的数字。 3. 暴搜。第一行数从 100到999,第二行数从 10到99。 4. 剪枝。 代码: /*ID: who jayLANG: C++TASK: crypt1*/#include<stdio.h>bool h

uva 10387 Billiard(简单几何)

题意是一个球从矩形的中点出发,告诉你小球与矩形两条边的碰撞次数与小球回到原点的时间,求小球出发时的角度和小球的速度。 简单的几何问题,小球每与竖边碰撞一次,向右扩展一个相同的矩形;每与横边碰撞一次,向上扩展一个相同的矩形。 可以发现,扩展矩形的路径和在当前矩形中的每一段路径相同,当小球回到出发点时,一条直线的路径刚好经过最后一个扩展矩形的中心点。 最后扩展的路径和横边竖边恰好组成一个直

poj 1113 凸包+简单几何计算

题意: 给N个平面上的点,现在要在离点外L米处建城墙,使得城墙把所有点都包含进去且城墙的长度最短。 解析: 韬哥出的某次训练赛上A出的第一道计算几何,算是大水题吧。 用convexhull算法把凸包求出来,然后加加减减就A了。 计算见下图: 好久没玩画图了啊好开心。 代码: #include <iostream>#include <cstdio>#inclu

uva 10130 简单背包

题意: 背包和 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#include <stack>#include <vector>#include <queue>#include <map>

2014 Multi-University Training Contest 8小记

1002 计算几何 最大的速度才可能拥有无限的面积。 最大的速度的点 求凸包, 凸包上的点( 注意不是端点 ) 才拥有无限的面积 注意 :  凸包上如果有重点则不满足。 另外最大的速度为0也不行的。 int cmp(double x){if(fabs(x) < 1e-8) return 0 ;if(x > 0) return 1 ;return -1 ;}struct poin

2014 Multi-University Training Contest 7小记

1003   数学 , 先暴力再解方程。 在b进制下是个2 , 3 位数的 大概是10000进制以上 。这部分解方程 2-10000 直接暴力 typedef long long LL ;LL n ;int ok(int b){LL m = n ;int c ;while(m){c = m % b ;if(c == 3 || c == 4 || c == 5 ||