libcarte2d.c
Go to the documentation of this file.
00001 // Copyright (c) 2010-2016 The YP-Spur Authors, except where otherwise indicated.
00002 //
00003 // Permission is hereby granted, free of charge, to any person obtaining a copy
00004 // of this software and associated documentation files (the "Software"), to
00005 // deal in the Software without restriction, including without limitation the
00006 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
00007 // sell copies of the Software, and to permit persons to whom the Software is
00008 // furnished to do so, subject to the following conditions:
00009 //
00010 // The above copyright notice and this permission notice shall be included in
00011 // all copies or substantial portions of the Software.
00012 //
00013 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00014 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00015 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
00016 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00017 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00018 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
00019 // SOFTWARE.
00020 
00021 #include <math.h>
00022 #include <stdio.h>
00023 #include <stdlib.h>
00024 #include <unistd.h>
00025 
00026 #include <cartesian2d.h>
00027 
00028 CSptr CSroot_ptr;
00029 
00030 /* 座標系の生成 */
00031 CSptr CS_add(CSptr parent_cs, double x, double y, double theta)
00032 {
00033   CSptr a_cs, p_cs;
00034 
00035   /* 新しい座標系を作成 */
00036   a_cs = (CSptr)malloc(sizeof(CoordinateSystem));
00037   if (!a_cs)
00038     return (CSptr)0; /* 作成失敗 */
00039 
00040   if (parent_cs == 0)
00041   { /* 座標系の神 */
00042     CSroot_ptr = a_cs;
00043     a_cs->parent = 0;
00044     a_cs->brother = 0;
00045     a_cs->child = 0;
00046     a_cs->x = 0;
00047     a_cs->y = 0;
00048     a_cs->theta = 0;
00049     a_cs->level = 0;
00050   }
00051   else
00052   { /* 誰かの子 */
00053     p_cs = parent_cs;
00054 
00055     if (!p_cs->child)
00056     { /* 長男 */
00057       p_cs->child = a_cs;
00058     }
00059     else
00060     { /* 既に兄がいる */
00061       p_cs = p_cs->child;
00062       while (p_cs->brother)
00063         p_cs = p_cs->brother;
00064       p_cs->brother = a_cs;
00065     }
00066     a_cs->parent = parent_cs;
00067     a_cs->brother = 0;
00068     a_cs->child = 0;
00069     a_cs->x = x;
00070     a_cs->y = y;
00071     a_cs->theta = theta;
00072     a_cs->level = parent_cs->level + 1;
00073   }
00074 
00075   return a_cs;
00076 }
00077 
00078 /* 座標系の削除(子・兄弟もろとも) */
00079 /* 実装中途半端 */
00080 int CS_delete(CSptr target_cs)
00081 {
00082   if (target_cs->child)
00083   {
00084     CS_delete(target_cs->child);
00085   }
00086 
00087   if (target_cs->brother)
00088   {
00089     CS_delete(target_cs->brother);
00090   }
00091 
00092   if (target_cs)
00093   {
00094     free((void *)target_cs);
00095   }
00096   return 1;
00097 }
00098 
00099 /* 座標系の設定 */
00100 int CS_set(CSptr target_cs, double x, double y, double theta)
00101 {
00102   if (!target_cs)
00103     return 0;
00104 
00105   target_cs->x = x;
00106   target_cs->y = y;
00107   target_cs->theta = theta;
00108 
00109   return 1;
00110 }
00111 
00112 /* ある座標系上の座標を入力 */
00113 int CS_set_on_CS(CSptr target_cs, CSptr on_cs, double x, double y, double theta)
00114 {
00115   if (!target_cs || !on_cs)
00116     return 0;
00117   if (target_cs->parent)
00118     CS_recursive_trans(target_cs->parent, on_cs, &x, &y, &theta);
00119   return 1;
00120 }
00121 
00122 /* 子から見た親の位置を、親から見た自分の位置に変換する */
00123 void CS_turn_base(double *x, double *y, double *theta)
00124 {
00125   double xx, yy;
00126 
00127   xx = -(*x) * cos(-(*theta)) + (*y) * sin(-(*theta));
00128   yy = -(*x) * sin(-(*theta)) - (*y) * cos(-(*theta));
00129   *theta = -(*theta);
00130   *x = xx;
00131   *y = yy;
00132 }
00133 
00134 /*-----------------座標変換まわり-----------------*/
00135 /* 目的の座標系へひとっとび? */
00136 /*               */
00137 void CS_recursive_trans(CSptr target_cs, CSptr now_cs, double *x, double *y, double *theta)
00138 {
00139   /* 座標系が有効か */
00140   if (!target_cs || !now_cs)
00141     return;
00142   // printf("now %d\n",now_cs->level);
00143   /* 同じ座標系か(case A) */
00144   if (target_cs == now_cs)
00145     return; /* 終了 */
00146 
00147   /* 下の座標系か */
00148   if (target_cs->level == now_cs->level)
00149   { /* 同じレベルにいるけど違う座標系 */
00150     // printf(".down from %d\n",now_cs->level);
00151     inv_trans_cs(now_cs, x, y, theta); /* 座標系をひとつ下る */
00152     CS_recursive_trans(target_cs->parent, now_cs->parent, x, y, theta);
00153     // printf(".up to %d\n" ,target_cs->level);
00154     trans_cs(target_cs, x, y, theta); /* 座標系をひとつ登る */
00155   }
00156   else if (target_cs->level > now_cs->level)
00157   {                                                             /* 現在位置の方が下 case C */
00158     CS_recursive_trans(target_cs->parent, now_cs, x, y, theta); /* ひとつ下る */
00159     // printf("up to %d\n",target_cs->level);
00160     trans_cs(target_cs, x, y, theta); /* 座標系をひとつ登る */
00161   }
00162   else
00163   { /* 現在位置の方が上 case D */
00164     // printf("down from %d\n" ,now_cs->level);
00165     inv_trans_cs(now_cs, x, y, theta);                          /* 座標系をひとつ下る */
00166     CS_recursive_trans(target_cs, now_cs->parent, x, y, theta); /* ひとつ下る */
00167   }
00168 
00169   return;
00170 }
00171 
00172 /* 座標系を一段下る(1段前の座標系での座標に変換する) */
00173 void inv_trans_cs(CSptr target_cs, double *x, double *y, double *theta)
00174 {
00175   double xx, yy;
00176   if (target_cs)
00177   {
00178     xx = *x * cos(target_cs->theta) - *y * sin(target_cs->theta) + target_cs->x;
00179     yy = *x * sin(target_cs->theta) + *y * cos(target_cs->theta) + target_cs->y;
00180     *x = xx;
00181     *y = yy;
00182     *theta += target_cs->theta;
00183   }
00184 }
00185 
00186 /* 座標系を一段あがる(一段後での座標系での座標に変換する) */
00187 void trans_cs(CSptr target_cs, double *x, double *y, double *theta)
00188 {
00189   double xx, yy;
00190   if (target_cs)
00191   {
00192     xx = (*x - target_cs->x) * cos(-target_cs->theta) - (*y - target_cs->y) * sin(-target_cs->theta);
00193     yy = (*x - target_cs->x) * sin(-target_cs->theta) + (*y - target_cs->y) * cos(-target_cs->theta);
00194     *x = xx;
00195     *y = yy;
00196     *theta -= target_cs->theta;
00197   }
00198 }
00199 
00200 /* 上にあがるだけ */
00201 void trace_trans_cs(CSptr target_cs, double *x, double *y, double *theta)
00202 {
00203   if (target_cs == CSroot_ptr)
00204     return;
00205   trace_trans_cs(target_cs->parent, x, y, theta);
00206   trans_cs(target_cs, x, y, theta);
00207 
00208   return;
00209 }


yp-spur
Author(s):
autogenerated on Fri May 10 2019 02:52:19